Commit 29e85c0b authored by Alexandru Băluț's avatar Alexandru Băluț Committed by Jean-François Fortin Tam

Simplified the RippleUpdateGroup constructor and cleaned the class a bit.

parent 5a3a6ace
......@@ -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()
......
# 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))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment