[pitivi: 46/65] Simplified the RippleUpdateGroup constructor and cleaned the class a bit.



commit 29e85c0b1897ae93d6de830be7587f5b5bd09654
Author: Alex BÄluÈ <alexandru balut gmail com>
Date:   Mon Jun 13 11:51:49 2011 +0200

    Simplified the RippleUpdateGroup constructor and cleaned the class a bit.

 pitivi/ui/projectsettings.py     |   83 +++++++++++++++++---------------
 pitivi/ui/ripple_update_group.py |   96 +++++++++++++++++++++++++------------
 2 files changed, 109 insertions(+), 70 deletions(-)
---
diff --git a/pitivi/ui/projectsettings.py b/pitivi/ui/projectsettings.py
index 567aa90..fc4400d 100644
--- a/pitivi/ui/projectsettings.py
+++ b/pitivi/ui/projectsettings.py
@@ -120,65 +120,70 @@ class ProjectSettingsDialog():
 
         # behavior
 
-        self.wg = RippleUpdateGroup(
-            (self.frame_rate_combo, self._updateCombo, "changed",
-                self.frame_rate_fraction_widget),
-            (self.frame_rate_fraction_widget, self._updateFraction,
-                "value-changed", self.frame_rate_combo),
-            (self.dar_combo, None, "changed"),
-            (self.dar_fraction_widget, None, "value-changed"),
-            (self.par_combo, None, "changed"),
-            (self.par_fraction_widget, None, "value-changed"),
-            (self.width_spinbutton, None, "value-changed"),
-            (self.height_spinbutton, None, "value-changed"),
-            (self.save_audio_preset_button, self._updateAudioSaveButton),
-            (self.save_video_preset_button, self._updateVideoSaveButton),
-            (self.channels_combo,),
-            (self.sample_rate_combo,),
-            (self.sample_depth_combo,),
-        )
+        self.wg = RippleUpdateGroup()
+        self.wg.addVertex(self.frame_rate_combo,
+                signal="changed",
+                update_func=self._updateCombo,
+                update_func_args=(self.frame_rate_fraction_widget,))
+        self.wg.addVertex(self.frame_rate_fraction_widget,
+                signal="value-changed",
+                update_func=self._updateFraction,
+                update_func_args=(self.frame_rate_combo,))
+        self.wg.addVertex(self.dar_combo, signal="changed")
+        self.wg.addVertex(self.dar_fraction_widget, signal="value-changed")
+        self.wg.addVertex(self.par_combo, signal="changed")
+        self.wg.addVertex(self.par_fraction_widget, signal="value-changed")
+        self.wg.addVertex(self.width_spinbutton, signal="value-changed")
+        self.wg.addVertex(self.height_spinbutton, signal="value-changed")
+        self.wg.addVertex(self.save_audio_preset_button,
+                 update_func=self._updateAudioSaveButton)
+        self.wg.addVertex(self.save_video_preset_button,
+                 update_func=self._updateVideoSaveButton)
+        self.wg.addVertex(self.channels_combo)
+        self.wg.addVertex(self.sample_rate_combo)
+        self.wg.addVertex(self.sample_depth_combo)
 
         # constrain width and height IFF constrain_sar_button is active
-        self.wg.add_edge(self.width_spinbutton, self.height_spinbutton,
-            self.constrained, self.updateHeight)
-        self.wg.add_edge(self.height_spinbutton, self.width_spinbutton,
-            self.constrained, self.updateWidth)
+        self.wg.addEdge(self.width_spinbutton, self.height_spinbutton,
+            predicate=self.constrained, edge_func=self.updateHeight)
+        self.wg.addEdge(self.height_spinbutton, self.width_spinbutton,
+            predicate=self.constrained, edge_func=self.updateWidth)
 
         # keep framereate text field and combo in sync
-        self.wg.add_bi_edge(self.frame_rate_combo,
+        self.wg.addBiEdge(self.frame_rate_combo,
            self.frame_rate_fraction_widget)
 
         # keep dar text field and combo in sync
-        self.wg.add_edge(self.dar_combo, self.dar_fraction_widget,
+        self.wg.addEdge(self.dar_combo, self.dar_fraction_widget,
             edge_func=self.updateDarFromCombo)
-        self.wg.add_edge(self.dar_fraction_widget, self.dar_combo,
+        self.wg.addEdge(self.dar_fraction_widget, self.dar_combo,
             edge_func=self.updateDarFromFractionWidget)
 
         # keep par text field and combo in sync
-        self.wg.add_edge(self.par_combo, self.par_fraction_widget,
+        self.wg.addEdge(self.par_combo, self.par_fraction_widget,
             edge_func=self.updateParFromCombo)
-        self.wg.add_edge(self.par_fraction_widget, self.par_combo,
+        self.wg.addEdge(self.par_fraction_widget, self.par_combo,
             edge_func=self.updateParFromFractionWidget)
 
         # constrain DAR and PAR values. because the combo boxes are already
         # linked, we only have to link the fraction widgets together.
-        self.wg.add_edge(self.par_fraction_widget, self.dar_fraction_widget,
+        self.wg.addEdge(self.par_fraction_widget, self.dar_fraction_widget,
             edge_func=self.updateDarFromPar)
-        self.wg.add_edge(self.dar_fraction_widget, self.par_fraction_widget,
+        self.wg.addEdge(self.dar_fraction_widget, self.par_fraction_widget,
             edge_func=self.updateParFromDar)
 
         # update PAR when width/height change and the DAR checkbutton is
         # selected
-        self.wg.add_edge(self.width_spinbutton, self.par_fraction_widget,
+        self.wg.addEdge(self.width_spinbutton, self.par_fraction_widget,
             predicate=self.darSelected, edge_func=self.updateParFromDar)
-        self.wg.add_edge(self.height_spinbutton, self.par_fraction_widget,
+        self.wg.addEdge(self.height_spinbutton, self.par_fraction_widget,
             predicate=self.darSelected, edge_func=self.updateParFromDar)
 
         # update DAR when width/height change and the PAR checkbutton is
         # selected
-        self.wg.add_edge(self.width_spinbutton, self.dar_fraction_widget,
+        self.wg.addEdge(self.width_spinbutton, self.dar_fraction_widget,
             predicate=self.parSelected, edge_func=self.updateDarFromPar)
-        self.wg.add_edge(self.height_spinbutton, self.dar_fraction_widget,
+        self.wg.addEdge(self.height_spinbutton, self.dar_fraction_widget,
             predicate=self.parSelected, edge_func=self.updateDarFromPar)
 
         # presets
@@ -207,20 +212,20 @@ class ProjectSettingsDialog():
         self.bindCombo(self.audio_presets, "depth",
             self.sample_depth_combo)
 
-        self.wg.add_edge(self.par_fraction_widget,
+        self.wg.addEdge(self.par_fraction_widget,
             self.save_video_preset_button)
-        self.wg.add_edge(self.frame_rate_fraction_widget,
+        self.wg.addEdge(self.frame_rate_fraction_widget,
             self.save_video_preset_button)
-        self.wg.add_edge(self.width_spinbutton,
+        self.wg.addEdge(self.width_spinbutton,
             self.save_video_preset_button)
-        self.wg.add_edge(self.height_spinbutton,
+        self.wg.addEdge(self.height_spinbutton,
             self.save_video_preset_button)
 
-        self.wg.add_edge(self.channels_combo,
+        self.wg.addEdge(self.channels_combo,
             self.save_audio_preset_button)
-        self.wg.add_edge(self.sample_rate_combo,
+        self.wg.addEdge(self.sample_rate_combo,
             self.save_audio_preset_button)
-        self.wg.add_edge(self.sample_depth_combo,
+        self.wg.addEdge(self.sample_depth_combo,
             self.save_audio_preset_button)
 
         self.updateUI()
diff --git a/pitivi/ui/ripple_update_group.py b/pitivi/ui/ripple_update_group.py
index e11e1f7..0f16539 100644
--- a/pitivi/ui/ripple_update_group.py
+++ b/pitivi/ui/ripple_update_group.py
@@ -1,6 +1,6 @@
 # PiTiVi , Non-linear video editor
 #
-#       ui/projectsettings.py
+#       ui/ripple_update_group.py
 #
 # Copyright (c) 2010, Brandon Lewis <brandon lewis collabora co uk>
 #
@@ -21,7 +21,6 @@
 
 
 class RippleUpdateGroup(object):
-
     """Allows for event-driven spreadsheet-like ripple updates without
     infinite loops.
 
@@ -64,61 +63,96 @@ class RippleUpdateGroup(object):
 
         - a function to be called whenver the edge is visited during an update
           cycle. this function will not be called if the condition function
-          returns False."""
+          returns False.
+
+    @ivar arcs: A map from widget to a list of edges originating in the widget.
+    @ivar update_funcs: A map from widget to a (callable, args) tuple.
+    """
 
-    def __init__(self, *widgets):
+    def __init__(self):
         self.arcs = {}
         self.update_funcs = {}
         self.ignore_new_signals = False
-        for widget in widgets:
-            self.add_vertex(*widget)
 
-    def add_vertex(self, widget, update_func=None, signal=None, *args):
+    def addVertex(self, widget, signal=None, update_func=None,
+            update_func_args=()):
+        """Add a widget to the list of vertexes.
+
+        @param widget: The vertex to be added.
+        @type widget: gtk.Widget
+        @param signal: A signal of the widget to be monitored.
+        @type signal: str
+        @param update_func: A callable object called when the vertex is visited.
+        @type update_func: function
+        @param update_func_args: The arguments for calling update_func.
+        @type update_func_args: tuple
+        """
         if signal:
-            widget.connect(signal, self._widget_value_changed)
-        self.update_funcs[widget] = (update_func, args)
+            widget.connect(signal, self._widgetValueChanged)
+        self.update_funcs[widget] = (update_func, update_func_args)
         self.arcs[widget] = []
 
-    def add_edge(self, a, b, predicate=None,
-        edge_func=None):
-        self.arcs[a].append((b, predicate, edge_func))
-
-    def add_bi_edge(self, a, b, predicate=None,
-        edge_func=None):
-        self.add_edge(a, b, predicate, edge_func)
-        self.add_edge(b, a, predicate, edge_func)
-
-    def _widget_value_changed(self, widget, *unused):
+    def addEdge(self, widget_a, widget_b, predicate=None, edge_func=None):
+        """Add a directional edge from widget_a to widget_b.
+
+        @param widget_a: The source vertex.
+        @type widget_a: gtk.Widget
+        @param widget_b: The target vertex.
+        @type widget_b: gtk.Widget
+        @param predicate: A callable object returning whether the edge may be
+            traversed.
+        @type predicate: function
+        @param edge_func: A callable object called when the edge is traversed.
+        @type edge_func: function
+        """
+        self.arcs[widget_a].append((widget_b, predicate, edge_func))
+
+    def addBiEdge(self, widget_a, widget_b, predicate=None, edge_func=None):
+        """Add a bidirectional edge between the specified vertexes.
+
+        @see: addEdge
+        """
+        self.addEdge(widget_a, widget_b, predicate, edge_func)
+        self.addEdge(widget_b, widget_a, predicate, edge_func)
+
+    def _widgetValueChanged(self, widget, *unused):
+        """Handle an event generated by the specified widget."""
         if self.ignore_new_signals:
             return
 
         self.ignore_new_signals = True
-        self._updateValues(widget)
-        self.ignore_new_signals = False
+        try:
+            self._updateValues(widget)
+        finally:
+            self.ignore_new_signals = False
 
     def _updateValues(self, widget):
-        queue = [(widget, v) for v in self.arcs[widget]]
+        """Traverse the graph starting from the specified widget."""
+        # Initialize the list of (source_widget, arc) to be traversed.
+        queue = [(widget, arc) for arc in self.arcs[widget]]
         visited = set([widget])
         while queue:
-            parent, (cur, predicate, edge_func) = queue.pop(0)
+            source_widget, arc = queue.pop(0)
+            target_widget, predicate, edge_func = arc
 
             # ignore nodes we've seen
-            if cur in visited:
+            if target_widget in visited:
                 continue
 
             # check whether conditions permit this edge to be followed
-            if predicate and (not predicate()):
+            if predicate and not predicate():
                 continue
 
-            # if so call the edge function
+            # traverse the edge
             if edge_func:
                 edge_func()
 
-            # visit node
-            update_func, args = self.update_funcs[cur]
+            # visit the target node
+            update_func, update_func_args = self.update_funcs[target_widget]
             if update_func:
-                update_func(parent, cur, *args)
-            visited.add(cur)
+                update_func(source_widget, target_widget, *update_func_args)
+            visited.add(target_widget)
 
             # enqueue children
-            queue.extend(((cur, v) for v in self.arcs[cur]))
+            for arc in self.arcs[target_widget]:
+                queue.append((target_widget, arc))



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