[pitivi/ges: 1/287] Implement import and playback of 1 clip or project using GES
- From: Jean-FranÃois Fortin Tam <jfft src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi/ges: 1/287] Implement import and playback of 1 clip or project using GES
- Date: Thu, 15 Mar 2012 16:25:55 +0000 (UTC)
commit 1dbb504a9d9ebba54a48a0e30afd087c692fd591
Author: Mathieu Duponchelle <seeed laposte net>
Date: Sun Aug 28 23:21:22 2011 +0200
Implement import and playback of 1 clip or project using GES
* Disconnect observer, need to be reconnect. Start making changes to get it ready for GES
* Disconnect selection changed, needs to be handled with/by GES
* Unconnect the track names recenter when adding track
* Effects are not handled anymore
Almost everything is broken now!
pitivi/application.py | 9 ++-
pitivi/project.py | 21 +++----
pitivi/projectmanager.py | 8 ---
pitivi/timeline/timeline_undo.py | 14 +++--
pitivi/ui/clipproperties.py | 13 +++--
pitivi/ui/mainwindow.py | 45 ++++-----------
pitivi/ui/startupwizard.py | 5 +-
pitivi/ui/timeline.py | 98 +++++--------------------------
pitivi/ui/timelinecanvas.py | 10 +--
pitivi/ui/timelinecontrols.py | 23 ++++---
pitivi/ui/track.py | 79 ++++++++++++++++---------
pitivi/ui/trackobject.py | 76 +++++++++++++++---------
pitivi/ui/viewer.py | 118 +++++++++++++++++++++-----------------
pitivi/utils.py | 4 +-
14 files changed, 245 insertions(+), 278 deletions(-)
---
diff --git a/pitivi/application.py b/pitivi/application.py
index 094e51c..f28315c 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -133,7 +133,8 @@ class Pitivi(Loggable, Signallable):
self.action_log = UndoableActionLog()
self.debug_action_log_observer = DebugActionLogObserver()
self.debug_action_log_observer.startObserving(self.action_log)
- self.timelineLogObserver = TimelineLogObserver(self.action_log)
+ # TODO reimplement the observing after GES port
+ #self.timelineLogObserver = TimelineLogObserver(self.action_log)
self.projectLogObserver = ProjectLogObserver(self.action_log)
self.sourcelist_log_observer = SourceListLogObserver(self.action_log)
@@ -184,7 +185,7 @@ class Pitivi(Loggable, Signallable):
def _projectManagerNewProjectLoaded(self, projectManager, project):
self.current = project
self.action_log.clean()
- self.timelineLogObserver.startObserving(project.timeline)
+ #self.timelineLogObserver.startObserving(project.timeline)
self.projectLogObserver.startObserving(project)
self.sourcelist_log_observer.startObserving(project.sources)
self._newProjectLoaded(project)
@@ -197,7 +198,7 @@ class Pitivi(Loggable, Signallable):
return self.emit("closing-project", project)
def _projectManagerProjectClosed(self, projectManager, project):
- self.timelineLogObserver.stopObserving(project.timeline)
+ #self.timelineLogObserver.stopObserving(project.timeline)
self.projectLogObserver.stopObserving(project)
self.current = None
self.emit("project-closed", project)
@@ -369,6 +370,8 @@ class StartupWizardGuiPitivi(FullGuiPitivi):
def __init__(self, debug=False):
FullGuiPitivi.__init__(self, debug)
+ self.projectManager.newBlankProject()
+ self.gui.viewer.setPipeline()
def _createGui(self):
self.wizard = StartUpWizard(self)
diff --git a/pitivi/project.py b/pitivi/project.py
index 298dc71..7dec97f 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -24,7 +24,6 @@ Project class
"""
from pitivi.log.loggable import Loggable
-from pitivi.timeline.timeline import Timeline
from pitivi.pipeline import Pipeline
from pitivi.factories.timeline import TimelineSourceFactory
from pitivi.sourcelist import SourceList
@@ -33,6 +32,7 @@ from pitivi.signalinterface import Signallable
from pitivi.action import ViewAction
from pitivi.utils import Seeker
import gst
+import ges
class ProjectError(Exception):
@@ -90,19 +90,20 @@ class Project(Signallable, Loggable):
self._dirty = False
- self.timeline = Timeline()
+ self.timeline = ges.timeline_new_audio_video()
+ self.layer = ges.TimelineLayer()
+ self.timeline.add_layer(self.layer)
- self.factory = TimelineSourceFactory(self.timeline)
- self.pipeline = Pipeline()
+ self.pipeline = ges.TimelinePipeline()
+ self.pipeline._setUp = False
+ self.pipeline.add_timeline(self.timeline)
self.view_action = ViewAction()
- self.view_action.addProducers(self.factory)
self.seeker = Seeker(80)
self.settings = ExportSettings()
self._videocaps = self.settings.getVideoCaps()
def release(self):
- self.pipeline.release()
self.pipeline = None
#{ Settings methods
@@ -142,14 +143,12 @@ class Project(Signallable, Loggable):
def _projectSettingsChanged(self):
settings = self.getSettings()
self._videocaps = settings.getVideoCaps()
- if self.timeline:
- self.timeline.updateVideoCaps(self._videocaps)
for fact in self.sources.getSources():
fact.setFilterCaps(self._videocaps)
- if self.pipeline.getState() != gst.STATE_NULL:
- self.pipeline.stop()
- self.pipeline.pause()
+ if self.pipeline.get_state() != gst.STATE_NULL:
+ self.pipeline.set_state(gst.STATE_READY)
+ self.pipeline.set_state(gst.STATE_PAUSED)
def _sourceAddedCb(self, sourcelist, factory):
factory.setFilterCaps(self._videocaps)
diff --git a/pitivi/projectmanager.py b/pitivi/projectmanager.py
index 0497295..5f25a66 100644
--- a/pitivi/projectmanager.py
+++ b/pitivi/projectmanager.py
@@ -21,7 +21,6 @@
from gettext import gettext as _
import gobject
-import gst
import os
from urlparse import urlparse
@@ -37,7 +36,6 @@ from pitivi.stream import AudioStream, VideoStream
from pitivi.timeline.track import Track
from pitivi.undo import UndoableAction
-
class ProjectSettingsChanged(UndoableAction):
def __init__(self, project, old, new):
@@ -191,12 +189,6 @@ class ProjectManager(Signallable, Loggable):
# the rendered content will have. Pitivi currently supports
# projects with exactly one video track and one audio track.
settings = project.getSettings()
- video = VideoStream(gst.Caps(settings.getVideoCaps()))
- track = Track(video)
- project.timeline.addTrack(track)
- audio = AudioStream(gst.Caps(settings.getAudioCaps()))
- track = Track(audio)
- project.timeline.addTrack(track)
project.connect("project-changed", self._projectChangedCb)
self.emit("new-project-loaded", self.current)
diff --git a/pitivi/timeline/timeline_undo.py b/pitivi/timeline/timeline_undo.py
index d9a5ede..33b5cb2 100644
--- a/pitivi/timeline/timeline_undo.py
+++ b/pitivi/timeline/timeline_undo.py
@@ -369,10 +369,11 @@ class TimelineLogObserver(object):
def startObserving(self, timeline):
self._connectToTimeline(timeline)
- for timeline_object in timeline.timeline_objects:
- self._connectToTimelineObject(timeline_object)
- for track_object in timeline_object.track_objects:
- self._connectToTrackObject(track_object)
+ for layer in timeline.get_layers():
+ for timeline_object in layer.get_objects():
+ self._connectToTimelineObject(timeline_object)
+ for track_object in timeline_object.track_objects:
+ self._connectToTrackObject(track_object)
def stopObserving(self, timeline):
self._disconnectFromTimeline(timeline)
@@ -382,8 +383,9 @@ class TimelineLogObserver(object):
self._disconnectFromTrackObject(track_object)
def _connectToTimeline(self, timeline):
- timeline.connect("timeline-object-added", self._timelineObjectAddedCb)
- timeline.connect("timeline-object-removed", self._timelineObjectRemovedCb)
+ for layer in timeline.get_layers():
+ layer.connect("object-added", self._timelineObjectAddedCb)
+ layer.connect("object-removed", self._timelineObjectRemovedCb)
def _disconnectFromTimeline(self, timeline):
timeline.disconnect_by_func(self._timelineObjectAddedCb)
diff --git a/pitivi/ui/clipproperties.py b/pitivi/ui/clipproperties.py
index 5bc8f85..5eb3a68 100644
--- a/pitivi/ui/clipproperties.py
+++ b/pitivi/ui/clipproperties.py
@@ -245,7 +245,8 @@ class EffectProperties(gtk.Expander, gtk.HBox):
def _newProjectLoadedCb(self, app, project):
self.clip_properties.project = project
- self.selected_effects = self.timeline.selection.getSelectedTrackEffects()
+ #GES break, reimplement me
+ #self.selected_effects = self.timeline.selection.getSelectedTrackEffects()
self._updateAll()
def _vcontentNotifyCb(self, paned, gparamspec):
@@ -258,8 +259,9 @@ class EffectProperties(gtk.Expander, gtk.HBox):
def _setTimeline(self, timeline):
self._timeline = timeline
- if timeline:
- self.timeline.connect('selection-changed', self._selectionChangedCb)
+ #GES break, reimplement me
+ #if timeline:
+ # self.timeline.connect('selection-changed', self._selectionChangedCb)
timeline = property(_getTimeline, _setTimeline)
@@ -626,7 +628,8 @@ class TransformationProperties(gtk.Expander):
def _setTimeline(self, timeline):
self._timeline = timeline
- if timeline:
- self.timeline.connect('selection-changed', self._selectionChangedCb)
+ #TODO reimplement it in GES
+ #if timeline:
+ # self.timeline.connect('selection-changed', self._selectionChangedCb)
timeline = property(_getTimeline, _setTimeline)
diff --git a/pitivi/ui/mainwindow.py b/pitivi/ui/mainwindow.py
index 0b21e3b..5c8d092 100644
--- a/pitivi/ui/mainwindow.py
+++ b/pitivi/ui/mainwindow.py
@@ -364,7 +364,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
vpaned.show()
self.timeline = Timeline(instance, self.uimanager)
- self.timeline.project = self.project
+ self.project = None
vpaned.pack2(self.timeline, resize=True, shrink=False)
self.timeline.show()
@@ -401,7 +401,6 @@ class PitiviMainWindow(gtk.Window, Loggable):
#Clips properties
self.propertiestabs = BaseTabs(instance, True)
self.clipconfig = ClipProperties(instance, self.uimanager)
- self.clipconfig.project = self.project
self.propertiestabs.append_page(self.clipconfig,
gtk.Label(_("Clip configuration")))
self.clipconfig.show()
@@ -689,8 +688,11 @@ class PitiviMainWindow(gtk.Window, Loggable):
def _projectManagerNewProjectLoadedCb(self, projectManager, project):
self.log("A NEW project is loaded, update the UI!")
self.project = project
+ self.timeline.project = self.project
+ self.clipconfig.project = self.project
self._connectToProjectSources(project.sources)
- can_render = project.timeline.duration > 0
+ duration = 0
+ can_render = duration > 0
self.render_button.set_sensitive(can_render)
self._syncDoUndo(self.app.action_log)
@@ -699,7 +701,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.actiongroup.get_action("SaveProject").set_sensitive(True)
self._missingUriOnLoading = False
- if project.timeline.duration != 0:
+ if duration != 0:
self.setBestZoomRatio()
else:
self._zoom_duration_changed = True
@@ -714,7 +716,10 @@ class PitiviMainWindow(gtk.Window, Loggable):
ruler_width = self.timeline.ruler.get_allocation()[2]
# Add gst.SECOND - 1 to the timeline duration to make sure the
# last second of the timeline will be in view.
- timeline_duration = self.project.timeline.duration + gst.SECOND - 1
+ tracks = self.project.timeline.get_tracks()
+ duration = max (tracks[0].props.duration, tracks[1].props.duration)
+ self.project.timeline.duration = duration
+ timeline_duration = duration + gst.SECOND - 1
timeline_duration_s = int(timeline_duration / gst.SECOND)
ideal_zoom_ratio = float(ruler_width) / timeline_duration_s
@@ -807,10 +812,6 @@ class PitiviMainWindow(gtk.Window, Loggable):
def _projectManagerProjectClosedCb(self, projectManager, project):
# we must disconnect from the project pipeline before it is released
- self._disconnectFromProjectSources(project.sources)
- self.viewer.setAction(None)
- self.viewer.setPipeline(None)
- project.seeker.disconnect_by_func(self._timelineSeekCb)
return False
def _projectManagerRevertingToSavedCb(self, projectManager, project):
@@ -958,14 +959,6 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.clipconfig.project = self.project
self.app.timelineLogObserver.pipeline = self.project.pipeline
- project = receiver(_setProject)
-
- @handler(project, "settings-changed")
- def _settingsChangedCb(self, project, old, new):
- if self.viewer.action == self.project.view_action:
- self.viewer.setDisplayAspectRatio(float(new.videopar *
- new.videowidth) / float(new.videoheight))
-
def _sourceListMissingPluginsCb(self, project, uri, factory,
details, descriptions, missingPluginsCallback):
res = self._installPlugins(details, missingPluginsCallback)
@@ -1081,26 +1074,12 @@ class PitiviMainWindow(gtk.Window, Loggable):
context.finish(True, False, ctime)
def _viewFactory(self, factory):
- # FIXME: we change the viewer pipeline unconditionally for now
- # we need a pipeline for playback
- pipeline = Pipeline()
- action = ViewAction()
- action.addProducers(factory)
- self.viewer.setPipeline(None)
- self.viewer.showSlider()
- # FIXME: why do I have to call viewer.setAction ?
- self.viewer.setAction(action)
- self.viewer.setPipeline(pipeline)
- self.viewer.play()
+ #GES crazyness... remove it or implement something?
+ pass
def _timelineSeekCb(self, ruler, position, format):
self.debug("position:%s", gst.TIME_ARGS(position))
if self.viewer.action != self.project.view_action:
- self.viewer.setPipeline(None)
- self.viewer.hideSlider()
- self.viewer.setAction(self.project.view_action)
- self.viewer.setPipeline(self.project.pipeline)
- # get the pipeline settings and set the DAR of the viewer
sett = self.project.getSettings()
self.viewer.setDisplayAspectRatio(float(sett.videopar * sett.videowidth) / float(sett.videoheight))
# everything above only needs to be done if the viewer isn't already
diff --git a/pitivi/ui/startupwizard.py b/pitivi/ui/startupwizard.py
index 6cf9e9d..96ef954 100644
--- a/pitivi/ui/startupwizard.py
+++ b/pitivi/ui/startupwizard.py
@@ -21,7 +21,6 @@
import os
import gtk
-import webbrowser
from gettext import gettext as _
@@ -77,11 +76,11 @@ class StartUpWizard(object):
def _loadCb(self, unused_recent_chooser):
"""Handle a double-click on the recent chooser."""
- self.app.projectManager.loadProject(self._getFileName())
+ self.app.gui.viewer.loadProject(self._getFileName())
def _getFileName(self):
"""Get the URI of the project selected in the recent chooser."""
- uri = self.recent_chooser.get_current_uri()
+ uri = self.recent_chooser.get_current_uri()[7:]
return unquote(uri)
def _keyPressCb(self, widget, event):
diff --git a/pitivi/ui/timeline.py b/pitivi/ui/timeline.py
index 27c4b74..39c3dfc 100644
--- a/pitivi/ui/timeline.py
+++ b/pitivi/ui/timeline.py
@@ -30,6 +30,7 @@ import ruler
import dnd
import gst
import gobject
+import ges
from gettext import gettext as _
from timelinecanvas import TimelineCanvas
@@ -390,9 +391,6 @@ class Timeline(gtk.Table, Loggable, Zoomable):
## Drag and Drop callbacks
def _dragMotionCb(self, unused, context, x, y, timestamp):
- self.warning("self._factories:%r, self._temp_objects:%r",
- not not self._factories,
- not not self._temp_objects)
if self._factories is None:
if context.targets in DND_EFFECT_LIST:
@@ -405,12 +403,8 @@ class Timeline(gtk.Table, Loggable, Zoomable):
else:
if context.targets not in DND_EFFECT_LIST:
if not self._temp_objects:
- self.timeline.disableUpdates()
- self._add_temp_source()
- 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)
+ #GES break,FIXME
+ pass
return True
def _dragLeaveCb(self, unused_layout, context, unused_tstamp):
@@ -422,25 +416,18 @@ class Timeline(gtk.Table, Loggable, Zoomable):
self._temp_objects = None
self.drag_unhighlight()
- self.timeline.enableUpdates()
+ #FIXME, GES break, temporary hack
+ uris = self.selection_data.split("\n")
+ layer = self.app.projectManager.current.timeline.get_layers()[0]
+ for uri in uris :
+ src = ges.TimelineFileSource(uri)
+ layer.add_object(src)
def _dragDropCb(self, widget, context, x, y, timestamp):
+ #FIXME GES break, reimplement me
if context.targets not in DND_EFFECT_LIST:
self.app.action_log.begin("add clip")
- self.timeline.disableUpdates()
-
- self._add_temp_source()
- self.timeline.selection.setSelection(self._temp_objects, SELECT)
- 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)
- self._move_context.finish()
self.app.action_log.commit()
- context.drop_finish(True, timestamp)
- self._factories = None
- self._temp_objects = None
- self.app.current.seeker.seek(self._position)
return True
elif context.targets in DND_EFFECT_LIST:
@@ -474,6 +461,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.
+ self.selection_data = selection.data
if targetType not in [dnd.TYPE_PITIVI_FILESOURCE, dnd.TYPE_PITIVI_EFFECT]:
context.finish(False, False, timestamp)
@@ -555,11 +543,14 @@ class Timeline(gtk.Table, Loggable, Zoomable):
self._vscrollbar.set_value(self._vscrollbar.get_value() +
self.vadj.props.page_size ** (2.0 / 3.0))
- def _updateScrollPosition(self, adjustment):
+ def unsureVadjHeight (self):
self._scroll_pos_ns = Zoomable.pixelToNs(self.hadj.get_value())
self._root_item.set_simple_transform(-self.hadj.get_value(),
-self.vadj.get_value(), 1.0, 0)
+ def _updateScrollPosition(self, adjustment):
+ self.unsureVadjHeight()
+
def _zoomAdjustmentChangedCb(self, adjustment):
# GTK crack
self._updateZoom = False
@@ -643,6 +634,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
self.timeline = self.project.timeline
self._controls.timeline = self.timeline
self._canvas.timeline = self.timeline
+ self._canvas.set_timeline()
self._canvas.zoomChanged()
self.ruler.setProjectFrameRate(self.project.getSettings().videorate)
self.ruler.zoomChanged()
@@ -667,16 +659,6 @@ class Timeline(gtk.Table, Loggable, Zoomable):
self._controls.timeline = self.timeline
- timeline = receiver(_setTimeline)
-
- @handler(timeline, "duration-changed")
- def _timelineStartDurationChanged(self, unused_timeline, duration):
- self._prev_duration = duration
- self.ruler.setMaxDuration(duration + 60 * gst.SECOND)
- self._canvas.setMaxDuration(duration + 60 * gst.SECOND)
- self.ruler.setShadedDuration(duration)
- self._updateScrollAdjustments()
-
def _updateScrollAdjustments(self):
a = self.get_allocation()
size = Zoomable.nsToPixel(self.timeline.duration)
@@ -686,54 +668,6 @@ class Timeline(gtk.Table, Loggable, Zoomable):
self.hadj.props.page_increment = size * 0.9
self.hadj.props.step_increment = size * 0.1
- @handler(timeline, "selection-changed")
- def _timelineSelectionChanged(self, timeline):
- delete = False
- link = False
- unlink = False
- group = False
- ungroup = False
- align = False
- split = False
- keyframe = False
- if timeline.selection:
- delete = True
- if len(timeline.selection) > 1:
- link = True
- group = True
- align = AutoAligner.canAlign(timeline.selection)
-
- start = None
- duration = None
- for obj in self.timeline.selection:
- if obj.link:
- link = False
- unlink = True
-
- if len(obj.track_objects) > 1:
- ungroup = True
-
- if start is not None and duration is not None:
- if obj.start != start or obj.duration != duration:
- group = False
- else:
- start = obj.start
- duration = obj.duration
-
- keyframe = True
-
- if (len(timeline.timeline_objects) > 0):
- split = True
-
- self.delete_action.set_sensitive(delete)
- self.link_action.set_sensitive(link)
- self.unlink_action.set_sensitive(unlink)
- self.group_action.set_sensitive(group)
- self.ungroup_action.set_sensitive(ungroup)
- self.align_action.set_sensitive(align)
- self.split_action.set_sensitive(split)
- self.keyframe_action.set_sensitive(keyframe)
-
## ToolBar callbacks
def _zoomFitCb(self, unused_action):
self.app.gui.setBestZoomRatio()
diff --git a/pitivi/ui/timelinecanvas.py b/pitivi/ui/timelinecanvas.py
index 6941e96..e2b22b6 100644
--- a/pitivi/ui/timelinecanvas.py
+++ b/pitivi/ui/timelinecanvas.py
@@ -305,17 +305,16 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
## Timeline callbacks
- def _set_timeline(self):
+ def set_timeline(self):
while self._tracks:
self._trackRemoved(None, 0)
if self.timeline:
- for track in self.timeline.tracks:
+ for track in self.timeline.get_tracks():
self._trackAdded(None, track)
+ self.timeline.connect ("track-added", self._trackAdded)
+ self.timeline.connect ("track-removed", self._trackRemoved)
self.zoomChanged()
- timeline = receiver(_set_timeline)
-
- @handler(timeline, "track-added")
def _trackAdded(self, timeline, track):
track = Track(self.app, track, self.timeline)
self._tracks.append(track)
@@ -323,7 +322,6 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
self.tracks.add_child(track)
self.regroupTracks()
- @handler(timeline, "track-removed")
def _trackRemoved(self, unused_timeline, position):
track = self._tracks[position]
del self._tracks[position]
diff --git a/pitivi/ui/timelinecontrols.py b/pitivi/ui/timelinecontrols.py
index 312f3b3..e83d545 100644
--- a/pitivi/ui/timelinecontrols.py
+++ b/pitivi/ui/timelinecontrols.py
@@ -31,11 +31,13 @@ class TrackControls(gtk.Label):
if self.track:
self._maxPriorityChanged(None, self.track.max_priority)
- track = receiver(_setTrack)
-
- @handler(track, "max-priority-changed")
- def _maxPriorityChanged(self, track, max_priority):
- self._setSize(max_priority + 1)
+ # FIXME Stop using the receiver
+ #
+ # TODO implement in GES
+ #track = receiver(_setTrack)
+ # handler(track, "max-priority-changed")
+ #def _maxPriorityChanged(self, track, max_priority):
+ # self._setSize(max_priority + 1)
def _setSize(self, layers_count):
assert layers_count >= 1
@@ -44,12 +46,13 @@ class TrackControls(gtk.Label):
@staticmethod
def _getTrackName(track):
- stream_type = type(track.stream)
- if stream_type == stream.AudioStream:
+ track_name = ""
+ #FIXME check that it is the best way to check the type
+ if track.props.track_type.first_value_name == 'GES_TRACK_TYPE_AUDIO':
track_name = _("Audio:")
- elif stream_type == stream.VideoStream:
+ elif track.props.track_type.first_value_name == 'GES_TRACK_TYPE_VIDEO':
track_name = _("Video:")
- elif stream_type == stream.TextStream:
+ elif track.props.track_type.first_value_name == 'GES_TRACK_TYPE_TEXT':
track_name = _("Text:")
return "<b>%s</b>" % track_name
@@ -69,7 +72,7 @@ class TimelineControls(gtk.VBox):
while self._tracks:
self._trackRemoved(None, 0)
if self.timeline:
- for track in self.timeline.tracks:
+ for track in self.timeline.get_tracks():
self._trackAdded(None, track)
timeline = receiver(_set_timeline)
diff --git a/pitivi/ui/track.py b/pitivi/ui/track.py
index caf21e8..272f337 100644
--- a/pitivi/ui/track.py
+++ b/pitivi/ui/track.py
@@ -4,7 +4,8 @@ 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
-
+import ges
+import gobject
class Transition(goocanvas.Rect, Zoomable):
@@ -26,20 +27,20 @@ class Transition(goocanvas.Rect, Zoomable):
def _updateAll(self):
transition = self.transition
- start = transition.start
- duration = transition.duration
- priority = transition.priority
+ start = transition.get_start()
+ duration = transition.get_duration()
+ priority = transition.get_priority()
self._updateStart(transition, start)
self._updateDuration(transition, duration)
self._updatePriority(transition, priority)
transition = receiver(_setTransition)
- @handler(transition, "start-changed")
+ @handler(transition, "notify::start")
def _updateStart(self, transition, start):
self.props.x = self.nsToPixel(start)
- @handler(transition, "duration-changed")
+ @handler(transition, "notify::duration")
def _updateDuration(self, transition, duration):
width = max(0, self.nsToPixel(duration))
if width == 0:
@@ -48,9 +49,9 @@ class Transition(goocanvas.Rect, Zoomable):
self.props.visibility = goocanvas.ITEM_VISIBLE
self.props.width = width
- @handler(transition, "priority-changed")
+ @handler(transition, "notify::priority")
def _updatePriority(self, transition, priority):
- self.props.y = (LAYER_HEIGHT_EXPANDED + LAYER_SPACING) * priority
+ self.props.y = (LAYER_HEIGHT_EXPANDED + LAYER_SPACING) * transition.get_priority()
def zoomChanged(self):
self._updateAll()
@@ -80,8 +81,22 @@ class Track(goocanvas.Group, Zoomable):
self.get_canvas().regroupTracks()
def getHeight(self):
+ track_objects = self.track.get_objects()
+ max_priority = 0
+ for track_object in track_objects :
+ if isinstance (track_object, ges.TrackAudioTestSource):
+ break
+ if isinstance (track_object, ges.TrackVideoTestSource):
+ break
+ priority = track_object.get_priority()
+ if priority > max_priority:
+ max_priority = priority
+ self.track.max_priority = (max_priority) / 10
+ if self.track.max_priority < 0:
+ self.track.max_priority = 0
if self._expanded:
return (1 + self.track.max_priority) * (LAYER_HEIGHT_EXPANDED + LAYER_SPACING)
+ #return LAYER_HEIGHT_EXPANDED + LAYER_SPACING
else:
return LAYER_HEIGHT_COLLAPSED + LAYER_SPACING
@@ -93,41 +108,47 @@ class Track(goocanvas.Group, Zoomable):
def _setTrack(self):
if self.track:
- for trackobj in self.track.track_objects:
+ for trackobj in self.track.get_objects():
self._objectAdded(None, trackobj)
- for transition in self.track.transitions.itervalues():
- self._transitionAdded(None, transition)
track = receiver(_setTrack)
@handler(track, "track-object-added")
def _objectAdded(self, unused_timeline, track_object):
- if not isinstance(track_object, TrackEffect):
- w = TrackObject(self.app, track_object, self.track, self.timeline)
- self.widgets[track_object] = w
+ if isinstance (track_object, ges.TrackParseLaunchEffect):
+ return
+ if isinstance (track_object, ges.TrackAudioTestSource):
+ return
+ if isinstance (track_object, ges.TrackVideoTestSource):
+ return
+ if isinstance (track_object, ges.TrackVideoTestSource):
+ return
+ if isinstance (track_object, ges.TrackAudioTransition):
+ self._transitionAdded (track_object)
+ return
+ if isinstance (track_object, ges.TrackVideoTransition):
+ self._transitionAdded (track_object)
+ return
+ gobject.timeout_add(1, self.check, track_object)
+
+ def check(self, tr_obj):
+ if tr_obj.get_timeline_object():
+ w = TrackObject(self.app, tr_obj, self.track, self.timeline)
+ self.widgets[tr_obj] = w
self.add_child(w)
+ self.app.gui.setBestZoomRatio()
@handler(track, "track-object-removed")
def _objectRemoved(self, unused_timeline, track_object):
- if not isinstance(track_object, TrackEffect):
+ if not isinstance(track_object, ges.TrackParseLaunchEffect):
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):
- w = Transition(transition)
+ def _transitionAdded(self, transition):
+ w = TrackObject(self.app, transition, self.track, self.timeline, self, True)
self.widgets[transition] = w
self.add_child(w)
-
- @handler(track, "transition-removed")
- def _transitionRemoved(self, unused_timeline, transition):
- w = self.widgets[transition]
- self.remove_child(w)
- del self.widgets[transition]
- Zoomable.removeInstance(w)
-
- @handler(track, "max-priority-changed")
- def _maxPriorityChanged(self, track, max_priority):
- self.get_canvas().regroupTracks()
+ self.transitions.append(w)
+ w.raise_(None)
diff --git a/pitivi/ui/trackobject.py b/pitivi/ui/trackobject.py
index b67e70b..9e5e0cd 100644
--- a/pitivi/ui/trackobject.py
+++ b/pitivi/ui/trackobject.py
@@ -240,7 +240,7 @@ class TrackObject(View, goocanvas.Group, Zoomable):
self._view.app.current.seeker.seek(Zoomable.pixelToNs(x))
timeline.setSelectionToObj(element, SELECT)
- def __init__(self, instance, element, track, timeline):
+ def __init__(self, instance, element, track, timeline, is_transition = False):
goocanvas.Group.__init__(self)
View.__init__(self)
Zoomable.__init__(self)
@@ -249,13 +249,12 @@ class TrackObject(View, goocanvas.Group, Zoomable):
self.timeline = timeline
self.namewidth = 0
self.nameheight = 0
+ self.is_transition = is_transition
self.bg = goocanvas.Rect(
height=self.height,
line_width=1)
- self.content = Preview(self.app, element)
-
self.name = goocanvas.Text(
x=NAME_HOFFSET + NAME_PADDING,
y=NAME_VOFFSET + NAME_PADDING,
@@ -278,12 +277,14 @@ class TrackObject(View, goocanvas.Group, Zoomable):
line_width=0.0,
height=self.height)
- 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))
+ if not self.is_transition:
+ for thing in (self.bg, self.selection_indicator,
+ self.start_handle, self.end_handle, self.namebg, self.name):
+ self.add_child(thing)
+ else :
+ for thing in (self.bg, self.selection_indicator,
+ self.namebg, self.name):
+ self.add_child(thing)
self.element = element
self.settings = instance.settings
@@ -354,10 +355,10 @@ class TrackObject(View, goocanvas.Group, Zoomable):
@handler(settings, "selectedColorChanged")
@handler(settings, "clipFontDescChanged")
def clipAppearanceSettingsChanged(self, *args):
- if isinstance(self.element.stream, VideoStream):
- color = self.settings.videoClipBg
- elif isinstance(self.element.stream, AudioStream):
+ if self.element.get_track().props.track_type.first_value_name == 'GES_TRACK_TYPE_AUDIO':
color = self.settings.audioClipBg
+ else:
+ color = self.settings.videoClipBg
pattern = unpack_cairo_gradient(color)
self.bg.props.fill_pattern = pattern
@@ -377,9 +378,8 @@ class TrackObject(View, goocanvas.Group, Zoomable):
## element signals
def _setElement(self):
- if self.element:
- self.name.props.text = os.path.basename(unquote(
- self.element.factory.name))
+ if self.element and not self.is_transition:
+ self.name.props.text = self.element.get_property ("uri")
twidth, theight = text_size(self.name)
self.namewidth = twidth
self.nameheight = theight
@@ -387,32 +387,50 @@ class TrackObject(View, goocanvas.Group, Zoomable):
element = receiver(_setElement)
- @handler(element, "start-changed")
- @handler(element, "duration-changed")
+ @handler(element, "notify::start")
+ @handler(element, "notify::duration")
def startChangedCb(self, track_object, start):
self._update()
- @handler(element, "selected-changed")
- def selected_changed(self, element, state):
- if element.selected:
+ def selected_changed(self, unused_project, element):
+ self.timeline.selected = []
+ if isinstance(element, set):
+ for elem in element:
+ elem.selected = True
+ self.timeline.selected.append(elem)
+ for elem in element:
+ if elem == self.element:
+ print elem.get_timeline_object().get_property("priority"), "la pute !!"
+ self.selection_indicator.props.visibility = goocanvas.ITEM_VISIBLE
+ elem.selected = True
+ elif self.element.selected == False:
+ self.selection_indicator.props.visibility = \
+ goocanvas.ITEM_INVISIBLE
+ for elem in element:
+ elem.selected = False
+ return
+
+ else:
+ self.timeline.selected.append(element)
+
+ if element == self.element:
self.selection_indicator.props.visibility = goocanvas.ITEM_VISIBLE
else:
self.selection_indicator.props.visibility = \
goocanvas.ITEM_INVISIBLE
- @handler(element, "priority-changed")
- def priority_changed(self, element, priority):
- self._update()
-
def _update(self):
try:
- x = self.nsToPixel(self.element.start)
+ x = self.nsToPixel(self.element.get_start())
except Exception, e:
- print self.element.start
+ print self.element.get_start()
raise Exception(e)
- y = (self.height + LAYER_SPACING) * self.element.priority
+ priority = (self.element.get_priority()) / 10
+ if priority < 0 :
+ priority = 0
+ y = (self.height + LAYER_SPACING) * priority
self.set_simple_transform(x, y, 1, 0)
- width = self.nsToPixel(self.element.duration)
+ width = self.nsToPixel(self.element.get_duration())
min_width = self.start_handle.props.width * 2
if width < min_width:
width = min_width
@@ -430,3 +448,5 @@ class TrackObject(View, goocanvas.Group, Zoomable):
self.namebg.props.visibility = goocanvas.ITEM_VISIBLE
else:
self.namebg.props.visibility = goocanvas.ITEM_INVISIBLE
+ self.app.gui.timeline._canvas.regroupTracks()
+ self.app.gui.timeline.unsureVadjHeight()
diff --git a/pitivi/ui/viewer.py b/pitivi/ui/viewer.py
index c912695..3085445 100644
--- a/pitivi/ui/viewer.py
+++ b/pitivi/ui/viewer.py
@@ -26,6 +26,7 @@ from gtk import gdk
import gst
from math import pi
import cairo
+import ges
from gettext import gettext as _
@@ -108,7 +109,10 @@ class PitiviViewer(gtk.VBox, Loggable):
self.seeker = Seeker(80)
self.seeker.connect('seek', self._seekerSeekCb)
self.action = action
- self.pipeline = pipeline
+ self.pipeline = None
+
+ self.formatter = ges.PitiviFormatter()
+
self.sink = None
self.docked = True
@@ -122,7 +126,6 @@ class PitiviViewer(gtk.VBox, Loggable):
self._createUi()
self.target = self.internal
self.setAction(action)
- self.setPipeline(pipeline)
self.undock_action = undock_action
if undock_action:
self.undock_action.connect("activate", self._toggleDocked)
@@ -130,7 +133,16 @@ class PitiviViewer(gtk.VBox, Loggable):
if not self.settings.viewerDocked:
self.undock()
- def setPipeline(self, pipeline):
+ def loadProject(self, uri):
+ self.app.projectManager.current.pipeline.set_state(gst.STATE_NULL)
+ self.timeline = self.app.projectManager.current.timeline
+ for layer in self.timeline.get_layers():
+ self.timeline.remove_layer(layer)
+ self.formatter.load_from_uri(self.timeline, uri)
+ self.app.projectManager.emit("new-project-loading", uri)
+ self.app.projectManager.current.pipeline.set_state(gst.STATE_PAUSED)
+
+ def setPipeline(self):
"""
Set the Viewer to the given Pipeline.
@@ -139,24 +151,17 @@ class PitiviViewer(gtk.VBox, Loggable):
@param pipeline: The Pipeline to switch to.
@type pipeline: L{Pipeline}.
"""
- self.debug("self.pipeline:%r, pipeline:%r", self.pipeline, pipeline)
-
- if pipeline is not None and pipeline == self.pipeline:
- return
+ self.debug("self.pipeline:%r", self.pipeline)
+ self.pipeline = self.app.projectManager.current.pipeline
if self.pipeline != None:
- # remove previously set Pipeline
- self._disconnectFromPipeline()
- # make ui inactive
- self._setUiActive(False)
- # finally remove previous pipeline
- self.pipeline = None
+ bus = self.pipeline.get_bus()
+ bus.add_signal_watch()
+ bus.connect('message', self._busMessageCb)
+ bus.set_sync_handler(self._elementMessageCb)
+ self.pipeline.set_state(gst.STATE_PAUSED)
self.currentState = gst.STATE_PAUSED
- self.playpause_button.setPause()
- self._connectToPipeline(pipeline)
- self.pipeline = pipeline
- if self.pipeline is not None:
- self._setUiActive()
+ self._setUiActive()
def setAction(self, action):
"""
@@ -179,24 +184,19 @@ class PitiviViewer(gtk.VBox, Loggable):
self._connectToAction(action)
self.showControls()
- def _connectToPipeline(self, pipeline):
- self.debug("pipeline:%r", pipeline)
- if self.pipeline != None:
- raise ViewerError("previous pipeline wasn't disconnected")
- self.pipeline = pipeline
- if self.pipeline == None:
- return
- self.pipeline.connect('position', self._posCb)
- self.pipeline.activatePositionListener()
- self.pipeline.connect('state-changed', self._currentStateCb)
- self.pipeline.connect('element-message', self._elementMessageCb)
- self.pipeline.connect('duration-changed', self._durationChangedCb)
- self.pipeline.connect('eos', self._eosCb)
- self.pipeline.connect("state-changed", self.internal.currentStateCb)
- # if we have an action set it to that new pipeline
- if self.action:
- self.pipeline.setAction(self.action)
- self.action.activate()
+ def _busMessageCb(self, unused_bus, message):
+ if message.type == gst.MESSAGE_EOS:
+ print "eos"
+ elif message.type == gst.MESSAGE_STATE_CHANGED:
+ prev, new, pending = message.parse_state_changed()
+
+ if message.src == self.pipeline:
+ self.debug("Pipeline change state prev:%r, new:%r, pending:%r", prev, new, pending)
+
+ state_change = pending == gst.STATE_VOID_PENDING
+
+ if state_change:
+ self._currentStateCb(new)
def _disconnectFromPipeline(self):
self.debug("pipeline:%r", self.pipeline)
@@ -418,7 +418,7 @@ class PitiviViewer(gtk.VBox, Loggable):
self.info("button pressed")
self.moving_slider = True
self.valuechangedid = slider.connect("value-changed", self._sliderValueChangedCb)
- self.pipeline.pause()
+ self.pipeline.set_state(gst.STATE_PAUSED)
return False
def _sliderButtonReleaseCb(self, slider, event):
@@ -431,9 +431,9 @@ class PitiviViewer(gtk.VBox, Loggable):
self.valuechangedid = 0
# revert to previous state
if self.currentState == gst.STATE_PAUSED:
- self.pipeline.pause()
+ self.pipeline.set_state(gst.STATE_PAUSED)
else:
- self.pipeline.play()
+ self.pipeline.set_state(gst.STATE_PLAYING)
return False
def _sliderValueChangedCb(self, slider):
@@ -510,8 +510,11 @@ class PitiviViewer(gtk.VBox, Loggable):
def _backCb(self, unused_button):
self.seekRelative(-gst.SECOND)
- def _playButtonCb(self, unused_button, isplaying):
- self.togglePlayback()
+ def _playButtonCb(self, unused_button, playing):
+ if playing:
+ self.pipeline.set_state(gst.STATE_PLAYING)
+ else:
+ self.pipeline.set_state(gst.STATE_PAUSED)
def _forwardCb(self, unused_button):
self.seekRelative(gst.SECOND)
@@ -605,11 +608,11 @@ class PitiviViewer(gtk.VBox, Loggable):
def _posCb(self, unused_pipeline, pos):
self._newTime(pos)
- def _currentStateCb(self, unused_pipeline, state):
+ def _currentStateCb(self, state):
self.info("current state changed : %s", state)
- if state == int(gst.STATE_PLAYING):
+ if int(state) == int(gst.STATE_PLAYING):
self.playpause_button.setPause()
- elif state == int(gst.STATE_PAUSED):
+ elif int(state) == int(gst.STATE_PAUSED):
self.playpause_button.setPlay()
else:
self.sink = None
@@ -618,18 +621,21 @@ class PitiviViewer(gtk.VBox, Loggable):
def _eosCb(self, unused_pipeline):
self.playpause_button.setPlay()
- def _elementMessageCb(self, unused_pipeline, message):
- name = message.structure.get_name()
- self.log('message:%s / %s', message, name)
- if name == 'prepare-xwindow-id':
- sink = message.src
- self.sink = sink
- self._switch_output_window()
+ def _elementMessageCb(self, unused_bus, message):
+ if message.type == gst.MESSAGE_ELEMENT:
+ name = message.structure.get_name()
+ self.log('message:%s / %s', message, name)
+ if name == 'prepare-xwindow-id':
+ sink = message.src
+ self.sink = sink
+ self._switch_output_window()
+ return gst.BUS_PASS
def _switch_output_window(self):
gtk.gdk.threads_enter()
self.sink.set_xwindow_id(self.target.window_xid)
- self.sink.expose()
+ #FIXME GES break
+ #self.sink.expose()
gtk.gdk.threads_leave()
@@ -1115,6 +1121,9 @@ class PlayPauseButton(gtk.Button, Loggable):
self.image = gtk.Image()
self.add(self.image)
self.playing = True
+
+ self.get_settings().props.gtk_button_images = True
+ self.playing = False
self.setPlay()
self.connect('clicked', self._clickedCb)
@@ -1122,6 +1131,7 @@ class PlayPauseButton(gtk.Button, Loggable):
gtk.Button.set_sensitive(self, value)
def _clickedCb(self, unused):
+ self.playing = not self.playing
self.emit("play", self.playing)
def setPlay(self):
@@ -1129,6 +1139,8 @@ class PlayPauseButton(gtk.Button, Loggable):
self.log("setPlay")
if self.playing:
self.image.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
+ if not self.playing:
+ self.set_image(gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON))
self.set_tooltip_text(_("Play"))
self.playing = False
@@ -1137,5 +1149,7 @@ class PlayPauseButton(gtk.Button, Loggable):
""" display the pause image """
if not self.playing:
self.image.set_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_BUTTON)
+ if self.playing:
+ self.set_image(gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_BUTTON))
self.set_tooltip_text(_("Pause"))
self.playing = True
diff --git a/pitivi/utils.py b/pitivi/utils.py
index 7767404..95df0f9 100644
--- a/pitivi/utils.py
+++ b/pitivi/utils.py
@@ -332,7 +332,7 @@ class PropertyChangeTracker(Signallable):
self.obj = obj
self.properties = self._takeCurrentSnapshot(obj)
for property_name in self.property_names:
- signal_name = property_name + '-changed'
+ signal_name = "notify::" + property_name
self.__signals__[signal_name] = []
obj.connect(signal_name,
self._propertyChangedCb, property_name)
@@ -341,7 +341,7 @@ class PropertyChangeTracker(Signallable):
properties = {}
for property_name in self.property_names:
properties[property_name] = \
- getattr(obj, property_name.replace("-", "_"))
+ obj.get_property (property_name.replace("-", "_"))
return properties
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]