[gcompris] electricity activity: fixed the implementation of the z order management.



commit 750eba33def7c4ab2d907d42820b87b0b2e5b551
Author: Bruno Coudoin <bruno coudoin free fr>
Date:   Fri May 18 16:13:28 2012 +0200

    electricity activity: fixed the implementation of the z order management.
    
    This was completely broken. It was not behaving correctly and in some
    cases it could even crash GCompris.

 src/anim-activity/AnimItem.py |    8 ++++--
 src/anim-activity/Timeline.py |    2 +
 src/anim-activity/anim.py     |   48 ++++++++++++++++++++++++++++------------
 3 files changed, 40 insertions(+), 18 deletions(-)
---
diff --git a/src/anim-activity/AnimItem.py b/src/anim-activity/AnimItem.py
index 6e48ec0..5290f6d 100644
--- a/src/anim-activity/AnimItem.py
+++ b/src/anim-activity/AnimItem.py
@@ -67,6 +67,8 @@ class AnimItem:
 
         self.rootitem.set_data("id", self.id)
 
+        AnimItem.anim.doc.zorder_dirty()
+
     # Return the type name of the managed object
     def type_name(self):
         return (gobject.type_name(self.item))
@@ -297,7 +299,7 @@ class AnimItem:
         if not self.visible:
             AnimItem.anim.deleteItem(self)
         self.show(False)
-        AnimItem.anim.doc.delete_from_zorder(self.id)
+        AnimItem.anim.doc.zorder_dirty()
 
     def raise_(self):
         parent = self.item.get_parent()
@@ -305,7 +307,7 @@ class AnimItem:
         child_num = rootparent.find_child (parent);
         if child_num < rootparent.get_n_children() - 1:
             rootparent.move_child (child_num, child_num + 1);
-            AnimItem.anim.doc.save_zorder()
+            AnimItem.anim.doc.zorder_dirty()
 
     def lower(self):
         parent = self.item.get_parent()
@@ -313,7 +315,7 @@ class AnimItem:
         child_num = rootparent.find_child (parent);
         if child_num > 0:
             rootparent.move_child (child_num, child_num - 1);
-            AnimItem.anim.doc.save_zorder()
+            AnimItem.anim.doc.zorder_dirty()
 
 
     def rotate(self, angle):
diff --git a/src/anim-activity/Timeline.py b/src/anim-activity/Timeline.py
index 3ee8aee..61f42ec 100644
--- a/src/anim-activity/Timeline.py
+++ b/src/anim-activity/Timeline.py
@@ -122,6 +122,7 @@ class Timeline:
         self.select_it(self.timelinelist[time])
 
     def next(self):
+        self.anim.doc.save_zorder()
         self.current_time += 1
         if self.current_time >= min(len(self.timelinelist),
                                     self.lastmark + 1):
@@ -130,6 +131,7 @@ class Timeline:
 
 
     def previous(self):
+        self.anim.doc.save_zorder()
         self.current_time -= 1
         if self.current_time < 0:
             self.current_time = min(len(self.timelinelist) - 1,
diff --git a/src/anim-activity/anim.py b/src/anim-activity/anim.py
index 773edf8..7c9f5bc 100644
--- a/src/anim-activity/anim.py
+++ b/src/anim-activity/anim.py
@@ -770,6 +770,9 @@ class Document:
     # a list of items id in the order they appear on screen.
     self.zorder = {}
 
+    # Set to true when the order or the list of object has changed
+    self.zorderDirty = False
+
     # Create our rootitem. We put each canvas item in it so at the end we
     # only have to kill it. The canvas deletes all the items it contains
     # automaticaly.
@@ -790,16 +793,14 @@ class Document:
       item.display_at_time(time)
     self.restore_zorder()
 
-  # If an item is removed, we must remove it from all
-  # the timelines in which we saved a z_order
-  def delete_from_zorder(self, item_id):
-    for z_order in self.zorder.values():
-      try:
-        z_order.remove(item_id)
-      except ValueError:
-        pass
+
+  def zorder_dirty(self):
+    self.zorderDirty = True
 
   def save_zorder(self):
+    if not self.zorderDirty:
+      return
+
     z_order = []
     for i in range(self.rootitem.get_n_children()):
       item = self.rootitem.get_child(i)
@@ -807,21 +808,38 @@ class Document:
         z_order.append(item.get_data("id"))
 
     self.zorder[self.timeline.get_time()] = z_order
+    self.zorderDirty = False
 
   def restore_zorder(self):
     z_order = []
     if self.timeline.get_time() in self.zorder:
       z_order = self.zorder[self.timeline.get_time()]
+    else:
+      return
+
+    # Build the list of items_is present in the image
+    present_items = []
     for i in range(self.rootitem.get_n_children()):
       item = self.rootitem.get_child(i)
       if item:
-        item_id = item.get_data("id")
-        try:
-          z_index = z_order.index(item_id)
-          self.rootitem.move_child(i, z_index);
-        except ValueError:
-          pass
-
+        present_items.append( item.get_data("id") )
+
+    # Remove items in z_order that are not in present_items
+    z_order = [item for item in z_order if item in present_items]
+
+    for z_item_id in z_order:
+      for i in range(self.rootitem.get_n_children()):
+        item = self.rootitem.get_child(i)
+        if item:
+          item_id = item.get_data("id")
+          if ( item_id == z_item_id ):
+            z_index = z_order.index(item_id)
+            if ( i != z_index ):
+              try:
+                self.rootitem.move_child(i, z_index);
+                break
+              except ValueError:
+                pass
 
   def anim_to_file(self, filename):
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]