Rozdział 18 · Historia i dokument
Cofnij działania (Undo)
Pojedynczy gest użytkownika może składać się z wielu elementów Canvas i musi być całkowicie anulowany.
Cofnij przez działanie, a nie przez Canvas przedmioty
Naiwną implementacją Undo jest po prostu usunięcie ostatniego elementu utworzonego Canvas. Problem: jeden kres ołówka składa się z WIELU pojedynczych segmentów (Rozdział 18.14) – „cofnij”
istoriya_deystviy.py
undo_stack = [
[item_id_1, item_id_2, item_id_3], # jeden pociągnięcie ołówka — trzy odcinki
[item_id_4], # jeden prostokąt – jeden element
]
Ostateczna aplikacja rozwiązuje to poprzez dokument (sekcja 18.13, 18.29): każdy użytkownik
Akcja — Jeden lub więcej obiektów Shape - W pełni dodane do
Dokument można anulować w całości:
undo.py
def _commit_action(self, shapes):
self.document.extend(shapes)
self.undo_stack.append(shapes) # JEDNA akcja — nawet jeśli shapes z wielu segmentów
self.redo_stack.clear()
self.render_document()
def undo(self):
if not self.undo_stack:
return
shapes = self.undo_stack.pop()
del self.document[len(self.document) - len(shapes):]
self.redo_stack.append(shapes)
self.render_document()
render_document() jest tym samym render() co w rozdziale 17
Po anulowaniu dokument zmienia się, a płótno po prostu PRZERYSOWUJE się z niego na nowo — nie jest to punktowe usuwanie konkretnych elementów Canvas. Ten sam zasad „model zmienia akcje, Canvas tylko wyświetla aktualny stan”
render() w grze „Kółko-krzyżyk”Praktyka: Cofnij stos według akcji
Automatyczne skanowanie – undo usuwa WSZYSTKIE przedmioty z jednej akcji, zamiast tylko jednej