pitivi r1370 - in trunk/pitivi: timeline ui



Author: edwardrv
Date: Fri Nov 28 17:03:52 2008
New Revision: 1370
URL: http://svn.gnome.org/viewvc/pitivi?rev=1370&view=rev

Log:
moved source trimming and edge-snapping into core, special cased for TimelineSources

Modified:
   trunk/pitivi/timeline/objects.py
   trunk/pitivi/timeline/source.py
   trunk/pitivi/ui/complextimeline.py

Modified: trunk/pitivi/timeline/objects.py
==============================================================================
--- trunk/pitivi/timeline/objects.py	(original)
+++ trunk/pitivi/timeline/objects.py	Fri Nov 28 17:03:52 2008
@@ -347,6 +347,7 @@
     __edges = []
     __deadband = 0
     __do_updates = True
+    __instances = []
 
     def __init__(self, factory=None, start=gst.CLOCK_TIME_NONE,
                  duration=0, media_type=MEDIA_TYPE_NONE, name="", **kwargs):
@@ -362,6 +363,10 @@
         self.media_type = media_type
         self.gnlobject = None
         self.factory = factory
+        TimelineObject.registerInstance(self)
+
+    def __del__(self):
+        TimelineObject.unregisterInstance(self)
 
     ## properties
 
@@ -450,10 +455,14 @@
         # really modify the start/duration time
         self.gnlobject.info("start:%s , duration:%s" %( gst.TIME_ARGS(start),
                                                         gst.TIME_ARGS(duration)))
-        if duration > 0 and (not self._duration == duration or force):
+        if duration > 0 and (not self.duration == duration or force):
+            duration = max(duration, 0)
+            if self.factory:
+                duration = min(duration, self.factory.getDuration())
             self._duration = duration
             self.gnlobject.set_property("duration", long(duration))
-        if not start == gst.CLOCK_TIME_NONE and (not self._start == start or force):
+        if not start == gst.CLOCK_TIME_NONE and (not self.start == start or force):
+            start = max(0, start)
             self._start = start
             self.gnlobject.set_property("start", long(start))
 
@@ -468,6 +477,23 @@
         self.setStartDurationTime(TimelineObject.snapObjToEdge(self, start),
             duration)
 
+    def setInTime(self, time):
+        """Sets the timeline object's in point in the timeline, keeping its
+        out-point constant."""
+        delta = self.start - time 
+        self.setStartDurationTime(time, self.duration + delta)
+
+    def setOutTime(self, time):
+        """Set's the timeline object's out point in the timeline, keeping its
+        in-point constant."""
+        self.setStartDurationTime(self.start, time - self.start)
+
+    def snapInTime(self, time):
+        self.setInTime(TimelineObject.snapTimeToEdge(time))
+
+    def snapOutTime(self, time):
+        self.setOutTime(TimelineObject.snapTimeToEdge(time))
+
     def _startDurationChangedCb(self, gnlobject, property):
         """ start/duration time has changed """
         gst.log("self:%r , gnlobject:%r %r" % (self, gnlobject, self.gnlobject))
@@ -545,6 +571,16 @@
     ## for all layers/tracks.
 
     @classmethod
+    def registerInstance(cls, instance):
+        cls.__instances.append(weakref.ref(instance))
+
+    @classmethod
+    def unregisterInstance(cls, instance):
+        ref = weakref.ref(instance)
+        assert ref in self.__instances
+        self.__instances.remove(ref)
+
+    @classmethod
     def setDeadband(cls, db):
         cls.__deadband = db
 
@@ -564,13 +600,15 @@
         #FIXME: this might be more efficient if we used a binary sort tree,
         # filter out duplicate edges in linear time
         edges = {}
-        for obj in cls.__instances__.itervalues():
-                # start/end of object both considered "edit points"
-                edges[obj.start] = None
-                edges[obj.start + obj.duration] = None
-                # TODO: add other critical object points when these are
-                # implemented
-                # TODO: filtering mechanism
+        for obj in cls.__instances:
+            assert obj()
+            obj = obj()
+            # start/end of object both considered "edit points"
+            edges[obj.start] = None
+            edges[obj.start + obj.duration] = None
+            # TODO: add other critical object points when these are
+            # implemented
+            # TODO: filtering mechanism
         cls.__edges = edges.keys()
         cls.__edges.sort()
 

Modified: trunk/pitivi/timeline/source.py
==============================================================================
--- trunk/pitivi/timeline/source.py	(original)
+++ trunk/pitivi/timeline/source.py	Fri Nov 28 17:03:52 2008
@@ -38,7 +38,6 @@
         "media-start-duration-changed" : ["media-start", "media-duration"]
         }
 
-
     __data_type__ = "timeline-source"
 
 
@@ -108,19 +107,52 @@
             gst.TIME_ARGS(self.media_start),
             gst.TIME_ARGS(self.media_duration)))
         if duration > 0 and not self.media_duration == duration:
+            duration = max(0, min(duration, self.factory.getDuration()))
             self.gnlobject.set_property("media-duration", long(duration))
         if not start == gst.CLOCK_TIME_NONE and not self.media_start == start:
+            start = max(0, start)
             self.gnlobject.set_property("media-start", long(start))
 
+    # override setInTime and setOutTime methods to handle media-start/duration
+
+    def setInTime(self, time):
+        """Sets [media]{start,duration} properties such that the hypothetical
+        start of the source, and the out-point of the source are constant"""
+        delta = self.start - time
+        duration = self.duration + delta
+        self.setStartDurationTime(time, duration)
+        self.setMediaStartDurationTime(self.media_start - delta,
+            duration)
+
+    def setInTime(self, time):
+        """Sets the [media-]{start,duration} properties such that the
+        out-point and hypothetical beginning of the media remain constant."""
+        # { .... [ ==|=======] .... }
+        # A      B   t       C      D
+        # or
+        # { ..|. [ ==========] .... }
+        # A   t  B           C      D
+        # 
+        # A = hypothetical start of media file
+        # B = in-point in timeline
+        # C = out-point in timeline
+        # D = hypothetical end of media file
+        # t = input time, where we want point B
+        delta = time - self.start
+        duration = self.duration - delta
+        media_start = self.media_start + delta
+        self.setStartDurationTime(time, duration)
+        self.setMediaStartDurationTime(media_start, duration)
+
+    def setOutTime(self, time):
+        """Sets the [media-]{start,duration} properties such that the in-point
+        of the source remain constant."""
+        self.setStartDurationTime(gst.CLOCK_TIME_NONE, time - self.start)
+        self.setMediaStartDurationTime(gst.CLOCK_TIME_NONE, time - self.start)
+
     def setMediaStartDurationTime(self, start=gst.CLOCK_TIME_NONE,
                                   duration=0):
         """ sets the media start/duration time """
-        if not start == gst.CLOCK_TIME_NONE and start < 0:
-            gst.warning("Can't set start values < 0 !")
-            return
-        if duration < 0:
-            gst.warning("Can't set durations < 0 !")
-            return
         self._setMediaStartDurationTime(start, duration)
         if self.linked and isinstance(self.linked, TimelineFileSource):
             self.linked._setMediaStartDurationTime(start, duration)

Modified: trunk/pitivi/ui/complextimeline.py
==============================================================================
--- trunk/pitivi/ui/complextimeline.py	(original)
+++ trunk/pitivi/ui/complextimeline.py	Fri Nov 28 17:03:52 2008
@@ -271,34 +271,11 @@
     # problem.
 
     def _trim_source_start_cb(self, item, pos):
-        element = item.element
-        cur_end = element.start + element.duration
-        # Invariant:
-        #  max(duration) = element.factory.duration
-        #  start = end - duration
-        # Therefore
-        #  min(start) = end - element.factory.duration
-        new_start =  max(0,
-            cur_end - element.factory.duration,
-            self.pixelToNs(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)
-        #FIXME: only for sources
-        element.setMediaStartDurationTime(new_media_start, new_duration)
+        item.element.snapInTime(self.pixelToNs(pos[0]))
 
     def _trim_source_end_cb(self, item, pos):
-        element = item.element
-        cur_start = element.start
-        new_end = min(cur_start + element.factory.duration,
-            max(cur_start, self.pixelToNs(pos[0] + width(item))))
-        new_duration = new_end - element.start
-
-        element.setStartDurationTime(gst.CLOCK_TIME_NONE, new_duration)
-        #FIXME: only for sources
-        element.setMediaStartDurationTime(gst.CLOCK_TIME_NONE, new_duration)
+        item.element.snapOutTime(self.pixelToNs(pos[0]))
 
-    # FIXME: this is part of the zoomable interface I want to get rid of
     def zoomChanged(self):
         """Force resize if zoom ratio changes"""
         for child in self.elements:



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