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

@ -22,12 +22,26 @@ const commands = makeReadOnly(
/** The types of commands we can run (private) */ /** The types of commands we can run (private) */
_types: {}, _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 * Undoes the last commands in the history
* *
* @param {number} [n] Number of actions to undo * @param {number} [n] Number of actions to undo
*/ */
async undo(n = 1) { 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++) { for (var i = 0; i < n && this.current > -1; i++) {
try { try {
await this._history[this._current--].undo(); await this._history[this._current--].undo();
@ -45,6 +59,12 @@ const commands = makeReadOnly(
* @param {number} [n] Number of actions to redo * @param {number} [n] Number of actions to redo
*/ */
async redo(n = 1) { 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++) { for (var i = 0; i < n && this.current + 1 < this._history.length; i++) {
try { try {
await this._history[++this._current].redo(); await this._history[++this._current].redo();

View file

@ -24,6 +24,9 @@ const selectTransformTool = () =>
// Layer system handlers // Layer system handlers
uil.onactive.on(state.uilayeractivecb); uil.onactive.on(state.uilayeractivecb);
commands.onundo.on(state.undocb);
commands.onredo.on(state.redocb);
// Registers keyboard shortcuts // Registers keyboard shortcuts
keyboard.onShortcut({ctrl: true, key: "KeyA"}, state.ctrlacb); keyboard.onShortcut({ctrl: true, key: "KeyA"}, state.ctrlacb);
keyboard.onShortcut( keyboard.onShortcut(
@ -65,6 +68,9 @@ const selectTransformTool = () =>
uil.onactive.clear(state.uilayeractivecb); uil.onactive.clear(state.uilayeractivecb);
commands.onundo.clear(state.undocb);
commands.onredo.clear(state.redocb);
// Clear any selections // Clear any selections
state.reset(); state.reset();
@ -180,6 +186,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 // Mirroring
state.togglemirror = () => { state.togglemirror = () => {
state.mirrorSetValue(!state.mirrorSelection); state.mirrorSetValue(!state.mirrorSelection);