summaryrefslogtreecommitdiff
path: root/tools/editor
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-01-28 11:53:26 +0100
committerskal <pascal.massimino@gmail.com>2026-01-28 11:53:26 +0100
commit38a35612ab6cc90279cc89577310791a811df0b2 (patch)
tree7afba4d57eb9e8ef5b67568dd378b9a0762d0e1a /tools/editor
parent9b003f762f7fea313ecb3b2b17ef9446881d7a8c (diff)
feat(editor): Implement basic undo/redo functionality
Adds the core logic for managing an action history stack and an undo button. - Initializes undoStack, redoStack, and MAX_HISTORY_SIZE. - Implements addAction to record operations and clear redoStack. - Implements handleUndo to revert actions and manage stacks. - Adds placeholder for redrawCanvas and updateUndoRedoButtons.
Diffstat (limited to 'tools/editor')
-rw-r--r--tools/editor/script.js75
1 files changed, 68 insertions, 7 deletions
diff --git a/tools/editor/script.js b/tools/editor/script.js
index 45af325..737a9e6 100644
--- a/tools/editor/script.js
+++ b/tools/editor/script.js
@@ -5,6 +5,10 @@
let currentSpecData = null; // Stores the parsed spectrogram data
let dctSize = 512; // Default DCT size, read from header
+let undoStack = [];
+let redoStack = [];
+const MAX_HISTORY_SIZE = 50;
+
// --- File Handling ---
const specFileInput = document.getElementById('specFileInput');
specFileInput.addEventListener('change', handleFileSelect);
@@ -35,7 +39,7 @@ async function handleFileSelect(event) {
dctSize = header.dct_size;
const dataStart = 16;
- const numBytes = header.num_frames * header.dct_size * sizeof(float);
+ const numBytes = header.num_frames * header.dct_size * Float32Array.BYTES_PER_ELEMENT;
const spectralDataFloat = new Float32Array(buffer, dataStart, header.num_frames * header.dct_size);
currentSpecData = {
@@ -106,20 +110,77 @@ function drawSpectrogram(specData) {
const lineToolButton = document.getElementById('lineTool');
const ellipseToolButton = document.getElementById('ellipseTool');
const noiseToolButton = document.getElementById('noiseTool');
+const undoButton = document.getElementById('undoButton');
lineToolButton.addEventListener('click', () => console.log('Line tool selected'));
ellipseToolButton.addEventListener('click', () => console.log('Ellipse tool selected'));
noiseToolButton.addEventListener('click', () => console.log('Noise tool selected'));
-// TODO: Implement canvas event listeners for drawing shapes
-// TODO: Implement shape parameter controls
-// TODO: Implement save/load JSON
-// TODO: Implement .spec export
+undoButton.addEventListener('click', handleUndo);
+
+// --- Undo/Redo Logic ---
+function addAction(action) {
+ undoStack.push(action);
+ // Limit history size
+ if (undoStack.length > MAX_HISTORY_SIZE) {
+ undoStack.shift(); // Remove oldest action
+ }
+ redoStack = []; // Clear redo stack on new action
+ updateUndoRedoButtons();
+}
+
+function handleUndo() {
+ if (undoStack.length === 0) {
+ console.log('Undo stack is empty.');
+ return;
+ }
+
+ const actionToUndo = undoStack.pop();
+ actionToUndo.undo(); // Execute the inverse operation
+ redoStack.push(actionToUndo);
+ redrawCanvas(); // Redraw canvas to reflect the undo operation
+ updateUndoRedoButtons();
+}
+
+function handleRedo() {
+ if (redoStack.length === 0) {
+ console.log('Redo stack is empty.');
+ return;
+ }
+
+ const actionToRedo = redoStack.pop();
+ actionToRedo.redo(); // Re-apply the action
+ undoStack.push(actionToRedo);
+ redrawCanvas(); // Redraw canvas to reflect the redo operation
+ updateUndoRedoButtons();
+}
+
+function redrawCanvas() {
+ // This function needs to be implemented to redraw the entire canvas state
+ // based on the current undoStack. For now, it's a placeholder.
+ console.log('Redrawing canvas...');
+ if (currentSpecData) {
+ drawSpectrogram(currentSpecData);
+ } else {
+ // Clear canvas if no data is loaded
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.fillStyle = '#ffffff';
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ }
+}
+
+function updateUndoRedoButtons() {
+ // Enable/disable buttons based on stack emptiness
+ undoButton.disabled = undoStack.length === 0;
+ // redoButton.disabled = redoStack.length === 0; // If redo button exists
+}
// Initial setup for canvas size (can be updated on window resize)
window.addEventListener('resize', () => {
- // Re-draw or re-initialize canvas size if needed
if (currentSpecData) {
drawSpectrogram(currentSpecData);
}
-}); \ No newline at end of file
+});
+
+// Initial call to set button states and potentially draw initial state if any is loaded
+updateUndoRedoButtons(); \ No newline at end of file