diff --git a/js/lib/commands.js b/js/lib/commands.js index 0dc492f..3b9a3ca 100644 --- a/js/lib/commands.js +++ b/js/lib/commands.js @@ -21,6 +21,14 @@ const commands = makeReadOnly( _history: [], /** The types of commands we can run (private) */ _types: {}, + + /** @type {Observer<{n: int, cancel: function}>} */ + get onundo() { return this._onundo; }, + _onundo: new Observer(), + + /** @type {Observer<{n: int, cancel: function}>} */ + get onredo() { return this._onredo; }, + _onredo: new Observer(), /** * Undoes the last commands in the history @@ -28,6 +36,12 @@ const commands = makeReadOnly( * @param {number} [n] Number of actions to undo */ async undo(n = 1) { + var cancelled = false; + await this._onundo.emit({ + n:n, + cancel: ()=>{cancelled=true;}, + }); + if (cancelled) return; for (var i = 0; i < n && this.current > -1; i++) { try { await this._history[this._current--].undo(); @@ -45,6 +59,12 @@ const commands = makeReadOnly( * @param {number} [n] Number of actions to redo */ async redo(n = 1) { + let cancelled = false; + await this._onredo.emit({ + n:n, + cancel: ()=>{cancelled=true;}, + }); + if (cancelled) return; for (var i = 0; i < n && this.current + 1 < this._history.length; i++) { try { await this._history[++this._current].redo(); diff --git a/js/ui/tool/select.js b/js/ui/tool/select.js index f89da91..855c2e1 100644 --- a/js/ui/tool/select.js +++ b/js/ui/tool/select.js @@ -23,6 +23,9 @@ const selectTransformTool = () => // Layer system handlers uil.onactive.on(state.uilayeractivecb); + + commands.onundo.on(state.undocb); + commands.onredo.on(state.redocb); // Registers keyboard shortcuts keyboard.onShortcut({ctrl: true, key: "KeyA"}, state.ctrlacb); @@ -65,6 +68,9 @@ const selectTransformTool = () => uil.onactive.clear(state.uilayeractivecb); + commands.onundo.clear(state.undocb); + commands.onredo.clear(state.redocb); + // Clear any selections state.reset(); @@ -179,6 +185,17 @@ const selectTransformTool = () => ); } }; + + // Undo/Redo Handling, reset state before Undo/Redo + state.undocb= (undo)=>{ + if (state.selected){ + if (undo.n<=1) undo.cancel(); + state.reset(false); + } + } + state.redocb= (redo)=>{ + if (state.selected){ state.reset(false); } + } // Mirroring state.togglemirror = () => {