[Sugar-devel] [PATCH] Fix for first undo, undo/redo mechanism refactored

Manuel Quiñones manuq at laptop.org
Thu Jun 16 08:03:27 EDT 2011


---
 Area.py |  114 ++++++++++++++++++++++----------------------------------------
 1 files changed, 41 insertions(+), 73 deletions(-)

diff --git a/Area.py b/Area.py
index 5011fd3..71ef6aa 100644
--- a/Area.py
+++ b/Area.py
@@ -177,16 +177,9 @@ class Area(gtk.DrawingArea):
 
         self._set_selection_bounds(0, 0, 0, 0)
 
-        #start of UNDO and REDO
-        ## This flag is used when is the first time you click on Undo
-        self.first_undo = True
-        ## When you are just clicking on undo or redo and not
-        # drawing undo_surf is True
-        self.undo_surf = False
-        self.undo_times = 0
-        self.redo_times = 0
-        ##pixmaps list to Undo func
+        # List of pixmaps for the Undo function:
         self.undo_list = []
+        self.undo_index = None
 
         # variables to show the tool shape
         self.drawing = False
@@ -197,6 +190,7 @@ class Area(gtk.DrawingArea):
         """Configure the Area object."""
 
         if self.pixmap:
+            # Already set up
             return
 
         logging.debug('Area.setup: w=%s h=%s' % (width, height))
@@ -244,7 +238,7 @@ class Area(gtk.DrawingArea):
             gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
         self.gc_selection1.set_foreground(self.white)
 
-        self.enableUndo(self)
+        self.enableUndo(self, size=(width, height))
 
         # Setting a initial tool
         self.set_tool(self.tool)
@@ -711,27 +705,15 @@ class Area(gtk.DrawingArea):
         logging.debug('Area.undo(self)')
         width, height = self.window.get_size()
 
-        # if is the first time you click on UNDO
-        # (because undo_list always wait for the NEXT image)
-        if self.first_undo:
-            self.undo_times -= 1
-
-        #print "Undo no.%d" %(self.undo_times)
-        if self.undo_times > 0:
-            self.undo_times -= 1
-            self.redo_times += 1
-            try:  # to not try paint someting wrong
-                self.pixmap.draw_drawable(self.gc,
-                    self.undo_list[self.undo_times], 0, 0, 0, 0, width, height)
-            except:
-                logging.debug('Cant draw')
-                pass
-            self.queue_draw()
-        else:
-            self.undo_times = 0
+        if self.undo_index == 0:
+            # first undo:
+            pass
+        elif self.undo_index > 0:
+            self.undo_index -= 1
 
-        self.first_undo = False
-        self.undo_surf = True
+        undo_pix = self.undo_list[self.undo_index]
+        self.pixmap.draw_drawable(self.gc, undo_pix, 0, 0, 0, 0, width, height)
+        self.queue_draw()
 
         #special case for func polygon
         if self.tool['name'] == 'freeform':
@@ -747,50 +729,47 @@ class Area(gtk.DrawingArea):
         logging.debug('Area.redo(self)')
         width, height = self.window.get_size()
 
-        #print "REDO no.%d" %(self.redo_times)
-        if self.redo_times > 0:
-            self.redo_times -= 1
-            self.undo_times += 1
+        if self.undo_index < len(self.undo_list)-1:
+            self.undo_index += 1
 
-            try:  # to not try paint someting wrong
-                self.pixmap.draw_drawable(self.gc,
-                    self.undo_list[self.undo_times], 0, 0, 0, 0,
-                    width, height)
-            except:
-                logging.debug('Cant draw')
-                self.undo_times -= 1
+        undo_pix = self.undo_list[self.undo_index]
+        self.pixmap.draw_drawable(self.gc, undo_pix, 0, 0, 0, 0, width, height)
         self.queue_draw()
 
         self.emit('redo')
 
-    def enableUndo(self, widget):
+    def enableUndo(self, widget, size=None):
         """Keep the last change in a list for Undo/Redo commands.
 
             @param  self -- the Area object (GtkDrawingArea)
             @param  widget -- the Area object (GtkDrawingArea)
 
         """
-        #logging.debug('Area.enableUndo(self,widget)')
+        logging.debug('Area.enableUndo(self,widget)')
 
         width, height = self.window.get_size()
-
-        if self.undo_surf:
-            self.undo_times += 1
-
-        self.undo_list.append(None)  # alloc memory
-        self.undo_list[self.undo_times] = gtk.gdk.Pixmap(widget.window,
-            width, height, -1)  # define type
-        self.undo_list[self.undo_times].draw_drawable(self.gc, self.pixmap,
-            0, 0, 0, 0, width, height)  # copy workarea
-        self.undo_times += 1
-        self.redo_times = 0
-        self.first_undo = True
-        self.undo_surf = False
-
-        #This is the part where we can limit the steps of undo/redo
-        if self.undo_times == 12:
+        # We need to pass explicitly the size on set up, because the
+        # window size is not allocated yet.
+        if size is not None:
+            width, height = size
+
+        if len(self.undo_list) == 0:
+            # first_undo:
+            self.undo_index = 0
+        elif len(self.undo_list) == 12:
+            #This is the part where we can limit the steps of
+            #undo/redo:
             self.undo_list.pop(0)
-            self.undo_times -= 1
+        else:
+            self.undo_index += 1
+            # Forget the redos after this one:
+            self.undo_list = self.undo_list[:self.undo_index]
+
+        undo_pix = gtk.gdk.Pixmap(widget.window, width, height, -1)
+        undo_pix.draw_drawable(self.gc, self.pixmap,
+            0, 0, 0, 0, width, height)
+
+        self.undo_list.append(undo_pix)
 
         self.emit('action-saved')
 
@@ -1168,25 +1147,14 @@ class Area(gtk.DrawingArea):
         Indicate if is there some action to undo
             @param  self -- the Area object (GtkDrawingArea)
         """
-        undo_times = self.undo_times
-
-        if self.first_undo:
-            undo_times -= 1
-
-        if undo_times < 1:
-            return False
-        else:
-            return True
+        return self.undo_index > 0
 
     def can_redo(self):
         """
         Indicate if is there some action to redo
             @param  self -- the Area object (GtkDrawingArea)
         """
-        if self.redo_times < 1:
-            return False
-        else:
-            return True
+        return self.undo_index < len(self.undo_list) - 1
 
     def is_selected(self):
         """
-- 
1.7.4.4



More information about the Sugar-devel mailing list