adding redo functionality
This commit is contained in:
@@ -91,6 +91,7 @@ class GUI:
|
|||||||
edit_menu = tk.Menu(menu, tearoff=0)
|
edit_menu = tk.Menu(menu, tearoff=0)
|
||||||
menu.add_cascade(label="Edit", menu=edit_menu)
|
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="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_separator()
|
||||||
edit_menu.add_command(label="Toggle Selection Mode", accelerator="Ctrl+S", command=lambda: self._toggleSelectionMode())
|
edit_menu.add_command(label="Toggle Selection Mode", accelerator="Ctrl+S", command=lambda: self._toggleSelectionMode())
|
||||||
|
|
||||||
@@ -118,6 +119,7 @@ class GUI:
|
|||||||
|
|
||||||
# Key bindings
|
# Key bindings
|
||||||
root.bind_all('<Control-z>', lambda event: self._undo())
|
root.bind_all('<Control-z>', lambda event: self._undo())
|
||||||
|
root.bind_all('<Control-y>', lambda event: self._redo())
|
||||||
root.bind_all('<Control-s>', lambda event: self._toggleSelectionMode())
|
root.bind_all('<Control-s>', lambda event: self._toggleSelectionMode())
|
||||||
|
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
@@ -184,6 +186,12 @@ class GUI:
|
|||||||
self._currentImage.undo()
|
self._currentImage.undo()
|
||||||
self._renderCurrentImage()
|
self._renderCurrentImage()
|
||||||
|
|
||||||
|
def _redo(self) -> None:
|
||||||
|
if self._currentImage is None:
|
||||||
|
return
|
||||||
|
self._currentImage.redo()
|
||||||
|
self._renderCurrentImage()
|
||||||
|
|
||||||
def _toggleSelectionMode(self) -> None:
|
def _toggleSelectionMode(self) -> None:
|
||||||
"""Toggle interactive selection mode on/off."""
|
"""Toggle interactive selection mode on/off."""
|
||||||
self._selectionMode = not self._selectionMode
|
self._selectionMode = not self._selectionMode
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class ImageContainer:
|
|||||||
_imageData = None
|
_imageData = None
|
||||||
_path = None
|
_path = None
|
||||||
_history = None
|
_history = None
|
||||||
|
_redo_history = None
|
||||||
|
|
||||||
def loadImage(self, path: str) -> None:
|
def loadImage(self, path: str) -> None:
|
||||||
""" Load image file from the path.
|
""" Load image file from the path.
|
||||||
@@ -21,6 +22,7 @@ class ImageContainer:
|
|||||||
|
|
||||||
self._path = path
|
self._path = path
|
||||||
self._history = []
|
self._history = []
|
||||||
|
self._redo_history = []
|
||||||
|
|
||||||
print("Opened image:", path)
|
print("Opened image:", path)
|
||||||
|
|
||||||
@@ -41,6 +43,9 @@ class ImageContainer:
|
|||||||
return
|
return
|
||||||
# Ensure a deep copy (but PIL copy should be sufficient)
|
# Ensure a deep copy (but PIL copy should be sufficient)
|
||||||
self._history.append(self._imageData.copy())
|
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
|
# Cap history size to avoid memory blow up
|
||||||
if len(self._history) > 20:
|
if len(self._history) > 20:
|
||||||
self._history.pop(0)
|
self._history.pop(0)
|
||||||
@@ -48,4 +53,19 @@ class ImageContainer:
|
|||||||
def undo(self) -> None:
|
def undo(self) -> None:
|
||||||
if not self._history:
|
if not self._history:
|
||||||
return
|
return
|
||||||
self._imageData = self._history.pop()
|
# 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()
|
||||||
Reference in New Issue
Block a user