diff --git a/activities/Gears.activity/css/activity.css b/activities/Gears.activity/css/activity.css index e717cabc0..f50c29da7 100644 --- a/activities/Gears.activity/css/activity.css +++ b/activities/Gears.activity/css/activity.css @@ -35,6 +35,14 @@ body { background-image: url(../icons/edit-clear.svg); } +#main-toolbar #undo-button { + background-image: url(../icons/edit-undo.svg); +} + +#main-toolbar #redo-button { + background-image: url(../icons/edit-redo.svg); +} + #main-toolbar #help-button { background-image: url(../icons/help.svg); } diff --git a/activities/Gears.activity/icons/edit-redo.svg b/activities/Gears.activity/icons/edit-redo.svg new file mode 100644 index 000000000..c6af89278 --- /dev/null +++ b/activities/Gears.activity/icons/edit-redo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/activities/Gears.activity/icons/edit-undo.svg b/activities/Gears.activity/icons/edit-undo.svg new file mode 100644 index 000000000..2a7c03c5c --- /dev/null +++ b/activities/Gears.activity/icons/edit-undo.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/activities/Gears.activity/index.html b/activities/Gears.activity/index.html index 7b6bae786..c0b2fbfe3 100644 --- a/activities/Gears.activity/index.html +++ b/activities/Gears.activity/index.html @@ -25,6 +25,8 @@ + +
diff --git a/activities/Gears.activity/js/activity.js b/activities/Gears.activity/js/activity.js index 2b1d8e693..55bc5e301 100644 --- a/activities/Gears.activity/js/activity.js +++ b/activities/Gears.activity/js/activity.js @@ -7,7 +7,7 @@ define(["sugar-web/activity/activity","sugar-web/graphics/radiobuttonsgroup","ge // Initialize the activity. activity.setup(); - + var stopButton = document.getElementById("stop-button"); stopButton.addEventListener('click', function (event) { console.log("writing..."); @@ -39,6 +39,97 @@ define(["sugar-web/activity/activity","sugar-web/graphics/radiobuttonsgroup","ge } datastoreObject.loadAsText(onLoaded); + // Create a redo array associated with history object of global scope + window.history = {}; + window.$h = window.history; + history.undo = []; + history.redo = []; + + document.getElementById('undo-button').addEventListener('click', function(){ + if ($h.undo.length > 0 && gearSketch.selectedButton !== "playButton") { + var obj = $h.undo.pop(); + if(obj.method === "delete" || obj.method === "add"){ + $h.redo.push(obj); + gearSketch.board.clear(); + // console.log($h.undo); + $h.undo.map((value, ind) => { + if(value.method === "add"){ + gearSketch.board[value.type][value.item.id] = value.item; + } else if( value.method === "delete"){ + // Search for the item with the id and delete it + for (var type in gearSketch.board) { + if (gearSketch.board.hasOwnProperty(type)) { + var items = gearSketch.board[type]; + for (var itemId in items) { + if (items.hasOwnProperty(itemId) && itemId === value.item.id) { + delete gearSketch.board[type][itemId]; + } + } + } + } + } + }) + } else if(obj.method === "locationchange") { + for (var type in gearSketch.board) { + if (gearSketch.board.hasOwnProperty(type)) { + var items = gearSketch.board[type]; + for (var itemId in items) { + if (items.hasOwnProperty(itemId) && itemId === obj.item) { + var earlierLocation = gearSketch.board[type][itemId].location; + gearSketch.board[type][itemId].location = obj.location; + obj.location = earlierLocation; + $h.redo.push(obj); + } + } + } + } + } + document.getElementById("redo-button").style.opacity = 1; + } + if($h.undo.length === 0) document.getElementById("undo-button").style.opacity = 0.4; + else document.getElementById("undo-button").style.opacity = 1; + }) + + document.getElementById('redo-button').addEventListener('click', function(){ + if ($h.redo.length > 0 && gearSketch.selectedButton !== "playButton") { + var obj = $h.redo.pop(); + if(obj.method === "delete"){ + $h.undo.push(obj); + // Search for the item with the id and delete it + for (var type in gearSketch.board) { + if (gearSketch.board.hasOwnProperty(type)) { + var items = gearSketch.board[type]; + for (var itemId in items) { + if (items.hasOwnProperty(itemId) && itemId === obj.item.id) { + delete gearSketch.board[type][itemId]; + } + } + } + } + } else if(obj.method === "add"){ + $h.undo.push(obj); + gearSketch.board[obj.type][obj.item.id] = obj.item; + } else if(obj.method === "locationchange") { + for (var type in gearSketch.board) { + if (gearSketch.board.hasOwnProperty(type)) { + var items = gearSketch.board[type]; + for (var itemId in items) { + if (items.hasOwnProperty(itemId) && itemId === obj.item) { + var earlierLocation = gearSketch.board[type][itemId].location; + gearSketch.board[type][itemId].location = obj.location; + obj.location = earlierLocation; + $h.undo.push(obj); + } + } + } + } + } + document.getElementById("undo-button").style.opacity = 1; + } + if($h.redo.length === 0) document.getElementById("redo-button").style.opacity = 0.4; + else document.getElementById("redo-button").style.opacity = 1; + }) + var radioButtons; var gearButton = document.getElementById("gear-button"); var chainButton = document.getElementById("chain-button"); @@ -125,7 +216,7 @@ define(["sugar-web/activity/activity","sugar-web/graphics/radiobuttonsgroup","ge } gearSketch.playDemo(); }); - + // Full screen. document.getElementById("fullscreen-button").addEventListener('click', function() { document.getElementById("main-toolbar").style.opacity = 0; diff --git a/activities/Gears.activity/lib/gearsketch/gearsketch_main.js b/activities/Gears.activity/lib/gearsketch/gearsketch_main.js index d81ffca17..bb376472a 100644 --- a/activities/Gears.activity/lib/gearsketch/gearsketch_main.js +++ b/activities/Gears.activity/lib/gearsketch/gearsketch_main.js @@ -247,6 +247,11 @@ } else if (this.selectedButton === "gearButton") { this.selectedGear = this.board.getTopLevelGearAt(point); if (this.selectedGear != null) { + $h.undo.push({type:"gears", method: "locationchange", item: this.selectedGear.id, location: this.selectedGear.location}); + $h.redo = []; + document.getElementById("redo-button").style.opacity = 0.4; + document.getElementById("undo-button").style.opacity = 1; + this.offset = point.minus(this.selectedGear.location); } else if (this.board.getGearAt(point) == null) { this.stroke.push(point); @@ -265,9 +270,9 @@ } } }; - + var goalLocation; GearSketch.prototype.handlePenMove = function (x, y) { - var canPlaceGear, goalLocation, point; + var canPlaceGear, point; point = new Point(x, y); if (this.isPenDown) { if (this.selectedButton === "gearButton") { @@ -402,6 +407,10 @@ if (!__hasProp.call(_ref, id)) continue; gear = _ref[id]; if (Util.pointPathDistance(gear.location, stroke, false) < gear.innerRadius) { + $h.undo.push({type: "gears", item: gear, method: "delete"}); + $h.redo = []; + document.getElementById("redo-button").style.opacity = 0.4; + document.getElementById("undo-button").style.opacity = 1; _results.push(this.board.removeGear(gear)); } else { _results.push(void 0); @@ -417,6 +426,10 @@ if (gear != null) { isGearAdded = this.board.addGear(gear); if (isGearAdded && !(gear.numberOfTeeth in this.gearImages)) { + $h.undo.push({type: "gears", item: gear, method: "add"}); + $h.redo = []; + document.getElementById("redo-button").style.opacity = 0.4; + document.getElementById("undo-button").style.opacity = 1; this.addGearImage(gear); } } else { @@ -454,7 +467,20 @@ if (!__hasProp.call(_ref, id)) continue; chain = _ref[id]; if (chain.intersectsPath(stroke)) { - _results.push(this.board.removeChain(chain)); + $h.undo.push({type: "chains", item: chain, method: "delete"}); + $h.redo = []; + document.getElementById("redo-button").style.opacity = 0.4; + document.getElementById("undo-button").style.opacity = 1; + for (var type in this.board) { + if (this.board.hasOwnProperty(type)) { + var items = this.board[type]; + for (var itemId in items) { + if (items.hasOwnProperty(itemId) && itemId === chain.id) { + delete this.board[type][itemId]; + } + } + } + } } else { _results.push(void 0); } @@ -469,6 +495,10 @@ gearsInChain = Util.findGearsInsidePolygon(normalizedStroke, this.board.getGears()); if (normalizedStroke.length >= 3 && gearsInChain.length > 0) { chain = new Chain(normalizedStroke); + $h.undo.push({type: "chains", item: chain, method: "add"}); + $h.redo = []; + document.getElementById("redo-button").style.opacity = 0.4; + document.getElementById("undo-button").style.opacity = 1; return this.board.addChain(chain); } else if (normalizedStroke.length >= 2) { return this.removeStrokedChains(normalizedStroke);