[pitivi] Makes effects per clips



commit e9ef210754146b377e837e6b102af0fcfbb5fc3d
Author: Thibault Saunier <tsaunier gnome org>
Date:   Fri Jun 25 21:12:17 2010 -0400

    Makes effects per clips

 pitivi/effects.py           |    2 +-
 pitivi/timeline/timeline.py |   77 ++++++++++++++++++++++++++++++++++++++++---
 pitivi/timeline/track.py    |    2 +-
 pitivi/ui/timeline.py       |   16 +++++++--
 pitivi/ui/track.py          |   17 +++++----
 pitivi/ui/trackobject.py    |   76 ++++--------------------------------------
 6 files changed, 103 insertions(+), 87 deletions(-)
---
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 1ea1c3a..af03aaa 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -149,7 +149,7 @@ class Magician:
 
         for padTmp in pads:
             pad = gst.Pad (padTmp.get())
-            if pad.get_caps() == "ANY": #FIXME, I don't understand that!
+            if pad.get_caps() == "ANY": #FIXME
                 return False
 
             if padTmp.direction == gst.PAD_SRC:
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 7c152ef..4c80d23 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -77,6 +77,8 @@ class TimelineObject(Signallable, Loggable):
     @type selected: L{bool}
     @ivar track_objects: The Track objects controlled.
     @type track_objects: list of L{TrackObject}
+    @ivar effects: Effects that are applied
+    @type effect: list of L{TimelineObject}
     @ivar timeline: The L{Timeline} to which this object belongs
     @type timeline: L{Timeline}
     """
@@ -90,6 +92,8 @@ class TimelineObject(Signallable, Loggable):
         'selected-changed' : ['state'],
         'track-object-added': ["track_object"],
         'track-object-removed': ["track_object"],
+        'effect-added': ["effect_object"],
+        'effect-removed': ["effect_object"],
     }
 
     DEFAULT_START = 0
@@ -102,17 +106,22 @@ class TimelineObject(Signallable, Loggable):
         Loggable.__init__(self)
         self.factory = factory
         self.track_objects = []
+        self.effects = []
         self.timeline = None
         self.link = None
         self._selected = False
 
-    def copy(self, copy_track_objects=True):
+    def copy(self, copy_track_objects=True, copy_effects=True):
         cls = self.__class__
         other = cls(self.factory)
         other.track_objects = []
         if copy_track_objects:
             for track_object in self.track_objects:
                 other.addTrackObject(track_object.copy())
+        other.effect = []
+        if copy_effects:
+            for effect in self.effects:
+                other.addEffect(effect.copy())
 
         return other
 
@@ -155,6 +164,9 @@ class TimelineObject(Signallable, Loggable):
         for track_object in self.track_objects:
             track_object.setObjectStart(position)
 
+        for effect in self.effects:
+            effect.setStart(position)
+
         self.emit('start-changed', position)
 
     def _getDuration(self):
@@ -424,6 +436,39 @@ class TimelineObject(Signallable, Loggable):
 
         self.emit("track-object-added", obj)
 
+    def addEffect(self, obj):
+        """
+        Add the given C{TimelineObject} to the list of applied effects.
+
+        @param obj: The effect object to add
+        @type obj: C{TimelineObject}
+        @raises TimelineError: If the provided L{TimelineObject} is already applied to
+        this L{TimelineObject}
+        """
+        if obj in self.effects:
+            raise TimelineError()
+
+        self.effects.append(obj)
+
+        self.emit("effect-added", obj)
+
+    def removeEffect(self, obj):
+        """
+        Remove the given C{TimelineObject} to the list of applied effects.
+
+        @param obj: The effect object to add
+        @type obj: C{TimelineObject}
+        @raises TimelineError: If the provided L{TimelineObject} is not applied to
+        this L{TimelineObject}
+        """
+
+        if obj not in self.effects:
+            raise TimelineError()
+
+        self.effects.remove(obj)
+
+        self.emit("effect-removed", obj)
+
     def removeTrackObject(self, obj):
         """
         Remove the given object from the list of controlled C{TrackObject}.
@@ -1493,6 +1538,7 @@ class Timeline(Signallable, Loggable):
         self.dead_band = 10
         self.edges = TimelineEdges()
         self.property_trackers = {}
+        self.source_to_add_effect = None
 
     def addTrack(self, track):
         """
@@ -1676,15 +1722,13 @@ class Timeline(Signallable, Loggable):
         self.addTimelineObject(timeline_object)
         return timeline_object
 
-    def addEffectFactory(self, factory, start=0):
+    def addEffectFactory(self, factory, time, priority):
         """
         Creates a TimelineObject for the given EffectFactory and adds it to the timeline.
 
         @param factory: The EffectFactory to add.
         @type factory: L{EffectFactory}
         @param factory: The EffectFactory to add.
-        @ivar start: The position of the effect on a timeline (nanoseconds)
-        @type start: L{long}
         @raises TimelineError: if the factory doesn't have input or output streams
         """
         self.debug("factory:%r", factory)
@@ -1700,6 +1744,9 @@ class Timeline(Signallable, Loggable):
         input_stream = input_stream[0]
 
         track = self.getEffectTrack(factory)
+
+        timeline_objects = self.getSourceToAddEffectTo(time, priority)
+
         if track is None:
           raise TimelineError()
 
@@ -1710,8 +1757,14 @@ class Timeline(Signallable, Loggable):
 
         self.addTimelineObject(timeline_object)
 
+        start = min([obj.start for obj in timeline_objects])
+        end = max([obj.duration + obj.start for obj in timeline_objects])
+
         timeline_object.start = start
-        timeline_object.setDuration(track.duration - start)
+        timeline_object.setDuration(end-start)
+
+        for obj in timeline_objects:
+            obj.addEffect(timeline_object)
 
         return timeline_object
 
@@ -2054,3 +2107,17 @@ class Timeline(Signallable, Loggable):
         keyframe_positions = list(keyframe_positions)
         keyframe_positions.sort()
         return keyframe_positions
+
+    def getSourceToAddEffectTo(self, point, priority):
+        timeline_objects = []
+        if point == -1:
+            #We should return all objects from the layer
+            pass
+
+        for obj in self.timeline_objects:
+            if (obj.start <= point and
+                    point <= (obj.start + obj.duration) and\
+                    obj.priority == priority):
+                timeline_objects.append(obj)
+        print "Timeline objects: %s, priority: %s" %(timeline_objects, priority)
+        return timeline_objects
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index b214844..d2f711f 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -708,7 +708,7 @@ class SourceTrackObject(TrackObject):
     numobjs = 0
 
     def _makeGnlObject(self):
-        source = gst.element_factory_make('gnlsource', 
+        source = gst.element_factory_make('gnlsource',
             "gnlsource: " + self.factory.__class__.__name__ +
             str(SourceTrackObject.numobjs))
         SourceTrackObject.numobjs += 1
diff --git a/pitivi/ui/timeline.py b/pitivi/ui/timeline.py
index 632a4f1..ade2efd 100644
--- a/pitivi/ui/timeline.py
+++ b/pitivi/ui/timeline.py
@@ -37,7 +37,7 @@ from timelinecanvas import TimelineCanvas
 from timelinecontrols import TimelineControls
 from pitivi.receiver import receiver, handler
 from zoominterface import Zoomable
-from pitivi.ui.common import LAYER_HEIGHT_EXPANDED, LAYER_SPACING
+from pitivi.ui.common import LAYER_HEIGHT_EXPANDED, LAYER_SPACING, TRACK_SPACING
 from pitivi.timeline.timeline import MoveContext
 from pitivi.utils import Seeker
 from pitivi.ui.filelisterrordialog import FileListErrorDialog
@@ -426,7 +426,9 @@ class Timeline(gtk.Table, Loggable, Zoomable):
                 focus = self._temp_objects[0]
                 self._move_context = MoveContext(self.timeline,
                         focus, set(self._temp_objects[1:]))
-            self._move_temp_source(self.hadj.props.value + x, y)
+            if  context.targets not in [[dnd.VIDEO_EFFECT_TUPLE[0], dnd.EFFECT_TUPLE[0]],\
+                                    [dnd.AUDIO_EFFECT_TUPLE[0], dnd.EFFECT_TUPLE[0]]]:
+                self._move_temp_source(self.hadj.props.value + x, y)
         return True
 
     def _dragLeaveCb(self, unused_layout, unused_context, unused_tstamp):
@@ -446,7 +448,11 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         focus = self._temp_objects[0]
         self._move_context = MoveContext(self.timeline,
                 focus, set(self._temp_objects[1:]))
-        self._move_temp_source(self.hadj.props.value + x, y)
+
+        if  context.targets not in [[dnd.VIDEO_EFFECT_TUPLE[0], dnd.EFFECT_TUPLE[0]],\
+                                    [dnd.AUDIO_EFFECT_TUPLE[0], dnd.EFFECT_TUPLE[0]]]:
+            self._move_temp_source(self.hadj.props.value + x, y)
+
         self._move_context.finish()
         self.timeline.enableUpdates()
         self.app.action_log.commit()
@@ -467,6 +473,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         # tell current project to import the uri
         # wait for source-added signal, meanwhile ignore dragMotion signals
         # when ready, add factories to the timeline.
+
         if targetType not in [dnd.TYPE_PITIVI_FILESOURCE, dnd.TYPE_PITIVI_EFFECT]:
             context.finish(False, False, timestamp)
             return
@@ -482,7 +489,8 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
     def _add_temp_source(self, x, y):
         if isinstance (self._factories[0], EffectFactory):
-            self._temp_objects = [self.timeline.addEffectFactory(factory, Zoomable.pixelToNs(x))
+            priority = y / (LAYER_HEIGHT_EXPANDED + TRACK_SPACING + LAYER_SPACING)
+            self._temp_objects = [self.timeline.addEffectFactory(factory, self.pixelToNs(x), priority)
                 for factory in self._factories]
         else:
             self._temp_objects = [self.timeline.addSourceFactory(factory)
diff --git a/pitivi/ui/track.py b/pitivi/ui/track.py
index b64f396..833c5fc 100644
--- a/pitivi/ui/track.py
+++ b/pitivi/ui/track.py
@@ -1,5 +1,6 @@
 from pitivi.ui.zoominterface import Zoomable
 from pitivi.ui.trackobject import TrackObject
+from pitivi.timeline.track import TrackEffect
 from pitivi.receiver import receiver, handler
 from pitivi.ui.common import LAYER_HEIGHT_EXPANDED, LAYER_HEIGHT_COLLAPSED, LAYER_SPACING
 import goocanvas
@@ -100,16 +101,18 @@ class Track(goocanvas.Group, Zoomable):
 
     @handler(track, "track-object-added")
     def _objectAdded(self, unused_timeline, track_object):
-        w = TrackObject(self.app, track_object, self.track, self.timeline)
-        self.widgets[track_object] = w
-        self.add_child(w)
+        if not isinstance(track_object, TrackEffect):
+            w = TrackObject(self.app, track_object, self.track, self.timeline)
+            self.widgets[track_object] = w
+            self.add_child(w)
 
     @handler(track, "track-object-removed")
     def _objectRemoved(self, unused_timeline, track_object):
-        w = self.widgets[track_object]
-        self.remove_child(w)
-        del self.widgets[track_object]
-        Zoomable.removeInstance(w)
+        if not isinstance (track_object, TrackEffect):
+            w = self.widgets[track_object]
+            self.remove_child(w)
+            del self.widgets[track_object]
+            Zoomable.removeInstance(w)
 
     @handler(track, "transition-added")
     def _transitionAdded(self, unused_timeline, transition):
diff --git a/pitivi/ui/trackobject.py b/pitivi/ui/trackobject.py
index a099145..be4088e 100644
--- a/pitivi/ui/trackobject.py
+++ b/pitivi/ui/trackobject.py
@@ -23,7 +23,6 @@ from pitivi.ui.point import Point
 from pitivi.ui.prefs import PreferencesDialog
 from pitivi.settings import GlobalSettings
 from pitivi.stream import AudioStream, VideoStream
-from pitivi.timeline.track import TrackEffect
 
 LEFT_SIDE = gtk.gdk.Cursor(gtk.gdk.LEFT_SIDE)
 RIGHT_SIDE = gtk.gdk.Cursor(gtk.gdk.RIGHT_SIDE)
@@ -200,7 +199,6 @@ class EndHandle(TrimHandle):
 
 class TrackObject(View, goocanvas.Group, Zoomable):
 
-
     class Controller(TimelineController):
 
         _handle_enter_leave = True
@@ -248,13 +246,7 @@ class TrackObject(View, goocanvas.Group, Zoomable):
             height=self.height,
             line_width=1)
 
-        #FIXME I should find the way we want to effects in the time (It should
-        #be shown on existing track?)
-        if not isinstance(element, TrackEffect):
-            self.content = Preview(self.app, element)
-        else:
-            w = Effect(element)
-            self.add_child(w)
+        self.content = Preview(self.app, element)
 
         self.name = goocanvas.Text(
             x= NAME_HOFFSET + NAME_PADDING,
@@ -278,13 +270,12 @@ class TrackObject(View, goocanvas.Group, Zoomable):
             line_width = 0.0,
             height=self.height)
 
-        if not isinstance(element, TrackEffect): #FIXME
-            for thing in (self.bg, self.content, self.selection_indicator,
-                self.start_handle, self.end_handle, self.namebg, self.name):
-                self.add_child(thing)
+        for thing in (self.bg, self.content, self.selection_indicator,
+            self.start_handle, self.end_handle, self.namebg, self.name):
+            self.add_child(thing)
 
-            for prop, interpolator in element.getInterpolators().itervalues():
-                self.add_child(Curve(instance, element, interpolator))
+        for prop, interpolator in element.getInterpolators().itervalues():
+            self.add_child(Curve(instance, element, interpolator))
 
         self.element = element
         self.settings = instance.settings
@@ -426,61 +417,8 @@ class TrackObject(View, goocanvas.Group, Zoomable):
         if self.expanded:
             if w - NAME_HOFFSET > 0:
                 self.namebg.props.height = self.nameheight + NAME_PADDING2X
-                self.namebg.props.width = min(w - NAME_HOFFSET, 
+                self.namebg.props.width = min(w - NAME_HOFFSET,
                     self.namewidth + NAME_PADDING2X)
                 self.namebg.props.visibility = goocanvas.ITEM_VISIBLE
             else:
                 self.namebg.props.visibility = goocanvas.ITEM_INVISIBLE
-
-class Effect(goocanvas.Rect, Zoomable):
-
-    def __init__(self, element):
-        goocanvas.Rect.__init__(self)
-        Zoomable.__init__(self)
-        self.props.fill_color = "blue"
-        self.props.stroke_color = "black"
-        self.set_simple_transform(0, -LAYER_SPACING + 3, 1.0, 0)
-        self.props.height = LAYER_SPACING - 6
-        self.props.pointer_events = goocanvas.EVENTS_NONE
-        self.props.radius_x = 2
-        self.props.radius_y = 2
-        self.props.y = 0 #We keep the effect up
-        self.element = element
-
-    def _setEffect(self):
-        if self.element:
-            self._updateAll()
-
-    def _updateAll(self):
-        element = self.element
-        start = element.start
-        duration = element.factory.duration
-        self._updateStart(element, start)
-        self._updateDuration(element, duration)
-        self._updatePriority(element, duration)
-
-    element = receiver(_setEffect)
-
-    @handler(element, "start-changed")
-    def _updateStart(self, element, start):
-        if self.element.timeline_object is not None:
-            element.setStart(start, True)
-            track_duration = element.timeline_object.timeline.getEffectTrack(element.factory).duration
-            x = self.nsToPixel(start)
-            self.element.setDuration(track_duration - start, True)
-
-    @handler(element, "duration-changed")
-    def _updateDuration(self, element, duration):
-        width = max(0, self.nsToPixel(duration) - self.props.x)
-        if width == 0:
-            self.props.visibility = goocanvas.ITEM_INVISIBLE
-        else:
-            self.props.visibility = goocanvas.ITEM_VISIBLE
-        self.props.width = width
-
-    @handler(element, "priority-changed")
-    def _updatePriority(self, transition, priority):
-        self.props.y = 0
-
-    def zoomChanged(self):
-        self._updateAll()



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