Add onundo/redo events, add undo/redo handling to select tool to avoid history desync when undoing with an active selection.

This commit is contained in:
Metachs 2024-08-25 16:59:35 -04:00
parent 90758e3762
commit a8f208eda4
2 changed files with 37 additions and 0 deletions

View file

@ -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();

View file

@ -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 = () => {