Add undo/redo functionality to Canvas

Implemented undo and redo history stacks in Canvas.js, including keyboard shortcuts (Ctrl+Z, Ctrl+Y/Shift+Z), and state saving on relevant actions. Added Undo and Redo buttons to the UI in Canvas_view.js, with dynamic enable/disable based on history state.
This commit is contained in:
Dariusz L
2025-06-24 05:34:32 +02:00
parent 41bd1761c4
commit c8e7e2c561
2 changed files with 151 additions and 13 deletions

View File

@@ -519,6 +519,18 @@ async function createCanvasWidget(node, widget, app) {
}
}),
$el("button.painter-button", {
id: `undo-button-${node.id}`,
textContent: "Undo",
disabled: true,
onclick: () => canvas.undo()
}),
$el("button.painter-button", {
id: `redo-button-${node.id}`,
textContent: "Redo",
disabled: true,
onclick: () => canvas.redo()
}),
$el("button.painter-button.requires-selection.matting-button", {
textContent: "Matting",
onclick: async () => {
@@ -600,7 +612,18 @@ async function createCanvasWidget(node, widget, app) {
};
canvas.onSelectionChange = updateButtonStates;
const undoButton = controlPanel.querySelector(`#undo-button-${node.id}`);
const redoButton = controlPanel.querySelector(`#redo-button-${node.id}`);
canvas.onHistoryChange = ({ canUndo, canRedo }) => {
if(undoButton) undoButton.disabled = !canUndo;
if(redoButton) redoButton.disabled = !canRedo;
};
updateButtonStates();
canvas.updateHistoryButtons();
const resizeObserver = new ResizeObserver((entries) => {
const controlsHeight = entries[0].target.offsetHeight;
@@ -621,9 +644,14 @@ async function createCanvasWidget(node, widget, app) {
};
const addUpdateToButton = (button) => {
if (button.textContent === "Undo" || button.textContent === "Redo") {
return;
}
const origClick = button.onclick;
button.onclick = async (...args) => {
await origClick?.(...args);
if (origClick) {
await origClick(...args);
}
await updateOutput();
};
};