pitivi r1204 - in branches/SOC_2008_BLEWIS: . pitivi/ui



Author: blewis
Date: Sun Jul 20 21:45:58 2008
New Revision: 1204
URL: http://svn.gnome.org/viewvc/pitivi?rev=1204&view=rev

Log:
* pitivi/ui/complextimeline.py:
made edge-snapping work for clip resizing. also made edge snapping
take all edit points into consideration, rather than just the edit-
points within a given track. This required moving edit-point / edgei-
snapping code into ComplexLayers class.


Modified:
   branches/SOC_2008_BLEWIS/ChangeLog
   branches/SOC_2008_BLEWIS/pitivi/ui/complextimeline.py

Modified: branches/SOC_2008_BLEWIS/pitivi/ui/complextimeline.py
==============================================================================
--- branches/SOC_2008_BLEWIS/pitivi/ui/complextimeline.py	(original)
+++ branches/SOC_2008_BLEWIS/pitivi/ui/complextimeline.py	Sun Jul 20 21:45:58 2008
@@ -127,17 +127,14 @@
         SmartGroup.__init__(self, *args, **kwargs)
         self.widgets = {}
         self.elements = {}
-        self._edges = []
         self.sig_ids = None
         self.comp = None
-        # more of a factor, really
         self._zoom_adjustment = gtk.Adjustment()
         self._zoom_ratio = 0.0
         self._zoom_adjustment.lower = 0.1
         self._zoom_adjustment.upper = 1000
         self._zoom_adjustment.connect("value-changed", self._adjust_zoom)
         self.set_zoom_ratio(10.0)
-        self._deadband = self.pixel_to_ns(DEADBAND)
         self.object_style = None
 
     def get_zoom_adjustment(self):
@@ -145,7 +142,6 @@
 
     def _adjust_zoom(self, adjustment):
         self._zoom_ratio = adjustment.get_value()
-        self._deadband = self.pixel_to_ns(DEADBAND)
         self._zoom()
 
     def set_zoom_ratio(self, ratio):
@@ -171,7 +167,7 @@
     def _objectAdded(self, timeline, element):
         w = ComplexTimelineObject(element, self.object_style)
         make_dragable(self.canvas, w, start=self._start_drag,
-            moved=self._move_source_cb)
+            end=self._end_drag, moved=self._move_source_cb)
         element.connect("start-duration-changed", self.start_duration_cb, w)
         self.widgets[element] = w
         self.elements[w] = element
@@ -197,23 +193,6 @@
     def pixel_to_ns(self, pixel):
         return long(pixel * gst.SECOND / self._zoom_ratio)
 
-    def _edge_snap(self, element, coord):
-        # need to find the closest edge to both the left and right sides of
-        # the object we are draging.
-        duration = element.duration
-        left_res, left_diff = closest_item(self._edges, coord)
-        right_res, right_diff = closest_item(self._edges, coord + duration)
-
-        if left_diff <= right_diff:
-            res = left_res
-            diff = left_diff
-        else:
-            res = right_res - duration
-            diff = right_diff
-        if diff <= self._deadband:
-            return res
-        return coord
-
     def start_duration_cb(self, obj, start, duration, widget):
         widget.props.width =  self.ns_to_pixel(duration)
         self.set_child_pos(widget, (self.ns_to_pixel(start), 0))
@@ -221,29 +200,22 @@
     def _start_drag(self, item):
         item.raise_(None)
         self._draging = item.element
-        self._update_edges()
+        self.canvas.block_size_request(True)
+        self.canvas.update_editpoints()
 
-    def _update_edges(self):
-        #FIXME: this might be more efficient if we used a binary sort tree,
-        # updated only when the timeline actually changes instead of before
-        # every drag operation. possibly concerned this could lead to a
-        # noticible lag on large timelines
-        edges = {}
-        for element in self.widgets:
-            edges[element.start] = None
-            edges[element.start + element.duration] = None
-        self._edges = edges.keys()
-        self._edges.sort()
+    def _end_drag(self, item):
+        self.canvas.block_size_request(False)
 
     def _move_source_cb(self, item, pos):
         element = item.element
-        element.setStartDurationTime(max(self._edge_snap(element,
+        element.setStartDurationTime(max(self.canvas.snap_obj_to_edit(element,
             self.pixel_to_ns(pos[0])), 0))
 
     def _trim_source_start_cb(self, item, pos):
         element = item.element
         cur_end = element.start + element.duration
-        new_start = min(cur_end, max(0, self.pixel_to_ns(pos[0])))
+        new_start = min(cur_end, max(0,
+            self.canvas.snap_time_to_edit(self.pixel_to_ns(pos[0]))))
         new_duration = cur_end - new_start
         new_media_start = element.media_start + (new_start - element.media_start)
         element.setStartDurationTime(new_start, new_duration)
@@ -253,7 +225,8 @@
     def _trim_source_end_cb(self, item, pos):
         element = item.element
         cur_start = element.start
-        new_end = max(cur_start, self.pixel_to_ns(pos[0] + width(item)))
+        new_end = max(cur_start, self.canvas.snap_time_to_edit(
+            self.pixel_to_ns(pos[0] + width(item))))
         new_duration = new_end - element.start
         element.setStartDurationTime(gst.CLOCK_TIME_NONE, new_duration)
         #FIXME: only for sources
@@ -350,6 +323,9 @@
 
     def __init__(self, leftsizegroup, layerinfolist):
         goocanvas.Canvas.__init__(self)
+        self._editpoints = []
+        self._deadband = 0
+        self._block_size_request = False
         self.leftSizeGroup = leftsizegroup
         self.layerInfoList = layerinfolist
         self.layerInfoList.connect('layer-added', self._layerAddedCb)
@@ -358,7 +334,7 @@
         self.props.automatic_bounds = False
         self.props.integer_layout = True
         self.connect("size_allocate", self._size_allocate)
-
+       
     def _createUI(self):
         self.set_border_width(2)
         self.layers = VList(canvas=self)
@@ -369,10 +345,18 @@
         self._marquee = make_item(MARQUEE)
         manage_selection(self, self._marquee, True, self._selection_changed_cb)
 
+## methods for dealing with updating the canvas size
+
+    def block_size_request(self, status):
+        self._block_size_request = status
+
     def _size_allocate(self, unused_layout, allocation):
         width = max(allocation.width, self.layers.width)
 
     def _request_size(self, unused_item, prop):
+        #TODO: figure out why this doesn't work... (wtf?!?)
+        if self._block_size_request:
+            return True
         # we only update the bounds of the canvas by chunks of 100 pixels
         # in width, otherwise we would always be redrawing the whole canvas.
         # Make sure canvas is at least 800 pixels wide, and at least 100 pixels 
@@ -386,6 +370,50 @@
             self.set_bounds(0, 0, w, h)
         return True
 
+## code for keeping track of edit points, and snapping timestamps to the
+## nearest edit point. We do this here so we can keep track of edit points
+## for all layers/tracks.
+
+    def update_editpoints(self):
+        #FIXME: this might be more efficient if we used a binary sort tree,
+        # updated only when the timeline actually changes instead of before
+        # every drag operation. possibly concerned this could lead to a
+        # noticible lag on large timelines
+
+        # using a dictionary to silently filter out duplicate entries
+        # this list: it will screw up the edge-snaping algorithm
+        edges = {}
+        for layer in self.layerInfoList:
+            for obj in layer.composition.condensed:
+                # start/end of object both considered "edit points"
+                edges[obj.start] = None
+                edges[obj.start + obj.duration] = None
+        self._editpoints = edges.keys()
+        self._editpoints.sort()
+
+    def snap_time_to_edit(self, time):
+        res, diff = closest_item(self._editpoints, time)
+        if diff <= self._deadband:
+            return res
+        return time
+
+    def snap_obj_to_edit(self, obj, time):
+        # need to find the closest edge to both the left and right sides of
+        # the object we are draging.
+        duration = obj.duration
+        left_res, left_diff = closest_item(self._editpoints, time)
+        right_res, right_diff = closest_item(self._editpoints, time + duration)
+        if left_diff <= right_diff:
+
+            res = left_res
+            diff = left_diff
+        else:
+            res = right_res - duration
+            diff = right_diff
+        if diff <= self._deadband:
+            return res
+        return time
+
 ## ZoomableWidgetInterface overrides
 
     def _selection_changed_cb(self, selected, deselected):
@@ -404,6 +432,7 @@
 
     def zoomChanged(self):
         ratio = self.getZoomRatio()
+        self._deadband = self.pixelToNs(DEADBAND)
         for layer in self.layers:
             layer.set_zoom_ratio(ratio)
 
@@ -491,6 +520,8 @@
         self.scrolledWindow.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_AUTOMATIC)
         self.scrolledWindow.add(self.compositionLayers)
         self.pack_start(self.scrolledWindow, expand=True)
+        # force update of the zoom ratio, which hasn't been set yet.
+        self.compositionLayers.zoomChanged()
 
         #toolbar
         self.tb = TimelineToolBar()



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