diff --git a/src/GUI.py b/src/GUI.py index d52d55c..30aec02 100644 --- a/src/GUI.py +++ b/src/GUI.py @@ -91,6 +91,7 @@ class GUI: edit_menu = tk.Menu(menu, tearoff=0) menu.add_cascade(label="Edit", menu=edit_menu) edit_menu.add_command(label="Undo", accelerator="Ctrl+Z", command=lambda: self._undo()) + edit_menu.add_command(label="Redo", accelerator="Ctrl+Y", command=lambda: self._redo()) edit_menu.add_separator() edit_menu.add_command(label="Toggle Selection Mode", accelerator="Ctrl+S", command=lambda: self._toggleSelectionMode()) @@ -118,6 +119,7 @@ class GUI: # Key bindings root.bind_all('', lambda event: self._undo()) + root.bind_all('', lambda event: self._redo()) root.bind_all('', lambda event: self._toggleSelectionMode()) root.mainloop() @@ -184,6 +186,12 @@ class GUI: self._currentImage.undo() self._renderCurrentImage() + def _redo(self) -> None: + if self._currentImage is None: + return + self._currentImage.redo() + self._renderCurrentImage() + def _toggleSelectionMode(self) -> None: """Toggle interactive selection mode on/off.""" self._selectionMode = not self._selectionMode diff --git a/src/ImageContainer.py b/src/ImageContainer.py index 5622276..d1e85ba 100644 --- a/src/ImageContainer.py +++ b/src/ImageContainer.py @@ -5,6 +5,7 @@ class ImageContainer: _imageData = None _path = None _history = None + _redo_history = None def loadImage(self, path: str) -> None: """ Load image file from the path. @@ -21,6 +22,7 @@ class ImageContainer: self._path = path self._history = [] + self._redo_history = [] print("Opened image:", path) @@ -41,6 +43,9 @@ class ImageContainer: return # Ensure a deep copy (but PIL copy should be sufficient) self._history.append(self._imageData.copy()) + # New action invalidates redo history + if self._redo_history is not None: + self._redo_history.clear() # Cap history size to avoid memory blow up if len(self._history) > 20: self._history.pop(0) @@ -48,4 +53,19 @@ class ImageContainer: def undo(self) -> None: if not self._history: return - self._imageData = self._history.pop() \ No newline at end of file + # Move current state to redo stack + if self._redo_history is None: + self._redo_history = [] + if self._imageData is not None: + self._redo_history.append(self._imageData.copy()) + # Restore last snapshot + self._imageData = self._history.pop() + + def redo(self) -> None: + if not self._redo_history: + return + # Moving forward: save current to undo history + if self._imageData is not None: + self._history.append(self._imageData.copy()) + # Apply redo state + self._imageData = self._redo_history.pop() \ No newline at end of file