diff --git a/src/js/controller/PreviewFilmController.js b/src/js/controller/PreviewFilmController.js index d61a80c6..867c1859 100644 --- a/src/js/controller/PreviewFilmController.js +++ b/src/js/controller/PreviewFilmController.js @@ -80,7 +80,6 @@ if (action === ACTION.CLONE) { this.piskelController.duplicateFrameAt(index); - this.piskelController.setCurrentFrameIndex(index + 1); this.updateScrollerOverflows(); } else if (action === ACTION.DELETE) { this.piskelController.removeFrameAt(index); @@ -89,7 +88,6 @@ this.piskelController.setCurrentFrameIndex(index); } else if (action === ACTION.NEW_FRAME) { this.piskelController.addFrame(); - this.piskelController.setCurrentFrameIndex(this.piskelController.getFrameCount() - 1); this.updateScrollerOverflows(); } }; diff --git a/src/js/controller/piskel/PiskelController.js b/src/js/controller/piskel/PiskelController.js index b337866e..ed03a303 100644 --- a/src/js/controller/piskel/PiskelController.js +++ b/src/js/controller/piskel/PiskelController.js @@ -58,6 +58,21 @@ return this.piskel.getLayerAt(index); }; + ns.PiskelController.prototype.hasLayerAt = function (index) { + return !!this.getLayerAt(index); + }; + + // FIXME ?? No added value compared to getLayerAt ?? + // Except normalizing to null if undefined ?? ==> To merge + ns.PiskelController.prototype.getLayerByIndex = function (index) { + var layers = this.getLayers(); + if (layers[index]) { + return layers[index]; + } else { + return null; + } + }; + ns.PiskelController.prototype.getCurrentFrame = function () { var layer = this.getCurrentLayer(); return layer.getFrameAt(this.currentFrameIndex); @@ -105,6 +120,8 @@ this.getLayers().forEach(function (l) { l.addFrameAt(this.createEmptyFrame_(), index); }.bind(this)); + + this.setCurrentFrameIndex(index); }; ns.PiskelController.prototype.createEmptyFrame_ = function () { @@ -130,6 +147,7 @@ this.getLayers().forEach(function (l) { l.duplicateFrameAt(index); }); + this.setCurrentFrameIndex(index+1); }; ns.PiskelController.prototype.moveFrame = function (fromIndex, toIndex) { @@ -144,7 +162,11 @@ }; ns.PiskelController.prototype.setCurrentFrameIndex = function (index) { - this.currentFrameIndex = index; + if (this.hasFrameAt(index)) { + this.currentFrameIndex = index; + } else { + window.console.error('Could not set current frame index to ' + index); + } }; ns.PiskelController.prototype.selectNextFrame = function () { @@ -162,7 +184,11 @@ }; ns.PiskelController.prototype.setCurrentLayerIndex = function (index) { - this.currentLayerIndex = index; + if (this.hasLayerAt(index)) { + this.currentLayerIndex = index; + } else { + window.console.error('Could not set current layer index to ' + index); + } }; ns.PiskelController.prototype.selectLayer = function (layer) { @@ -179,15 +205,6 @@ } }; - ns.PiskelController.prototype.getLayerByIndex = function (index) { - var layers = this.getLayers(); - if (layers[index]) { - return layers[index]; - } else { - return null; - } - }; - ns.PiskelController.prototype.generateLayerName_ = function () { var name = "Layer " + this.layerIdCounter; while (this.hasLayerForName_(name)) { diff --git a/src/js/controller/piskel/PublicPiskelController.js b/src/js/controller/piskel/PublicPiskelController.js index 1db6af95..24ebb4e3 100644 --- a/src/js/controller/piskel/PublicPiskelController.js +++ b/src/js/controller/piskel/PublicPiskelController.js @@ -49,7 +49,7 @@ ns.PublicPiskelController.prototype.raiseSaveStateEvent_ = function (fn, args) { $.publish(Events.PISKEL_SAVE_STATE, { - type : pskl.service.HistoryService.REPLAY, + type : pskl.service.HistoryService.REPLAY_NO_SNAPSHOT, scope : this, replay : { fn : fn, diff --git a/src/js/drawingtools/Lighten.js b/src/js/drawingtools/Lighten.js index 425a3526..ff388c46 100644 --- a/src/js/drawingtools/Lighten.js +++ b/src/js/drawingtools/Lighten.js @@ -29,6 +29,7 @@ darken : {}, lighten : {} }; + this.superclass.resetUsedPixels_.call(this); }; /** * @override @@ -64,13 +65,12 @@ }; ns.Lighten.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) { - // apply on real frame this.setPixelsToFrame_(frame, this.pixels); - this.resetUsedPixels_(); - $.publish(Events.PISKEL_SAVE_STATE, { type : pskl.service.HistoryService.SNAPSHOT }); + + this.resetUsedPixels_(); }; })(); \ No newline at end of file diff --git a/src/js/drawingtools/SimplePen.js b/src/js/drawingtools/SimplePen.js index 3f8bab6b..993ca445 100644 --- a/src/js/drawingtools/SimplePen.js +++ b/src/js/drawingtools/SimplePen.js @@ -71,7 +71,7 @@ }); // reset - this.pixels = []; + this.resetUsedPixels_(); }; ns.SimplePen.prototype.replay = function (frame, replayData) { @@ -83,4 +83,8 @@ frame.setPixel(pixel.col, pixel.row, pixel.color); }); }; + + ns.SimplePen.prototype.resetUsedPixels_ = function() { + this.pixels = []; + }; })(); diff --git a/src/js/service/HistoryService.js b/src/js/service/HistoryService.js index 512f1c8b..25319aac 100644 --- a/src/js/service/HistoryService.js +++ b/src/js/service/HistoryService.js @@ -1,7 +1,7 @@ (function () { var ns = $.namespace('pskl.service'); - var SNAPSHOT_PERIOD = 50; + var SNAPSHOT_PERIOD = 5; var LOAD_STATE_INTERVAL = 50; ns.HistoryService = function (piskelController) { @@ -11,10 +11,17 @@ this.saveState__b = this.onSaveStateEvent.bind(this); this.lastLoadState = -1; + + this.saveNextAsSnapshot = false; }; ns.HistoryService.SNAPSHOT = 'SNAPSHOT'; ns.HistoryService.REPLAY = 'REPLAY'; + /** + * This event alters the state (frames, layers) of the piskel. The event is triggered before the execution of associated command. + * Don't store snapshots for such events. + */ + ns.HistoryService.REPLAY_NO_SNAPSHOT = 'REPLAY_NO_SNAPSHOT'; ns.HistoryService.prototype.init = function () { $.subscribe(Events.PISKEL_SAVE_STATE, this.saveState__b); @@ -41,8 +48,14 @@ layerIndex : this.piskelController.currentLayerIndex }; - if (stateInfo.type === ns.HistoryService.SNAPSHOT || this.currentIndex % SNAPSHOT_PERIOD === 0) { + var isSnapshot = stateInfo.type === ns.HistoryService.SNAPSHOT; + var isNoSnapshot = stateInfo.type === ns.HistoryService.REPLAY_NO_SNAPSHOT; + var isAtAutoSnapshotInterval = this.currentIndex % SNAPSHOT_PERIOD === 0; + if (isNoSnapshot && isAtAutoSnapshotInterval) { + this.saveNextAsSnapshot = true; + } else if (isSnapshot || isAtAutoSnapshotInterval) { state.piskel = this.piskelController.serialize(true); + this.saveNextAsSnapshot = false; } this.stateQueue.push(state); @@ -96,6 +109,8 @@ window.console.error(e.message); window.console.error(e.stack); } + this.stateQueue = []; + this.currentIndex = -1; } }; @@ -125,10 +140,11 @@ this.replayState(state); } - var lastState = this.stateQueue[index+1]; + var lastState = this.stateQueue[index]; if (lastState) { this.setupState(lastState); } + this.currentIndex = index; $.publish(Events.PISKEL_RESET); if (originalSize !== this.getPiskelSize_()) {