[pitivi] Makes effects per clips
- From: Edward Hervey <edwardrv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Makes effects per clips
- Date: Wed, 22 Sep 2010 13:37:03 +0000 (UTC)
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]