Fix undo handling of group and some other IO tools (#2931)

* Fix undo handling of group and some other IO tools

* Emit change signal inside onObjectModified

* Fix group lost after moving group then undoing

* Skip undo entry if canvas has not changed

The onObjectModified() call I added in a previous commit to deleteDuplicateTools results in a duplicate undo entry for the delete tool. Checking for duplicate entries seems simpler than having to think about where onObjectModified() should be called exactly

* Fix extra undo entry added after ungroup
This commit is contained in:
Abdo 2024-01-09 04:19:46 +03:00 committed by GitHub
parent 5d1fc9a591
commit cc81db0f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 4 deletions

View File

@ -301,6 +301,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip="{tool.tooltip()} ({getPlatformString(tool.shortcut)})"
on:click={() => {
tool.action(canvas);
undoStack.onObjectModified();
}}
>
{@html tool.icon}
@ -328,7 +329,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tooltip="{tool.tooltip()} ({getPlatformString(tool.shortcut)})"
on:click={() => {
tool.action(canvas);
emitChangeSignal();
undoStack.onObjectModified();
}}
>
{@html tool.icon}
@ -368,6 +369,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
)})"
on:click={() => {
alignTool.action(canvas);
undoStack.onObjectModified();
}}
>
{@html alignTool.icon}

View File

@ -81,6 +81,7 @@ export const unGroupShapes = (canvas: fabric.Canvas): void => {
const group = canvas.getActiveObject();
const items = group.getObjects();
group._restoreObjectsState();
group.destroyed = true;
canvas.remove(group);
items.forEach((item) => {

View File

@ -19,7 +19,7 @@ type UndoState = {
redoable: boolean;
};
const shapeType = ["rect", "ellipse", "i-text"];
const shapeType = ["rect", "ellipse", "i-text", "group"];
const validShape = (shape: fabric.Object): boolean => {
if (shape.width <= 5 || shape.height <= 5) {
@ -49,7 +49,12 @@ class UndoStack {
setCanvas(canvas: fabric.Canvas): void {
this.canvas = canvas;
this.canvas.on("object:modified", (opts) => this.maybePush(opts));
this.canvas.on("object:removed", (opts) => this.maybePush(opts));
this.canvas.on("object:removed", (opts) => {
// `destroyed` is a custom property set on groups in the ungrouping routine to avoid adding a spurious undo entry
if (!opts.target.group && !opts.target.destroyed) {
this.maybePush(opts);
}
});
}
reset(): void {
@ -94,6 +99,7 @@ class UndoStack {
onObjectModified(): void {
this.push();
emitChangeSignal();
}
private maybePush(opts): void {
@ -103,8 +109,12 @@ class UndoStack {
}
private push(): void {
const entry = JSON.stringify(this.canvas);
if (entry === this.stack[this.stack.length - 1]) {
return;
}
this.stack.length = this.index + 1;
this.stack.push(JSON.stringify(this.canvas));
this.stack.push(entry);
this.index++;
this.updateState();
}