Commit c7c7ee9e authored by Edward Hervey's avatar Edward Hervey

* pitivi/playground.py:

Added 'position' signal which is emitted to inform a change of position
with the current SmartBin.
* pitivi/ui/complextimeline.py:
* pitivi/ui/mainwindow.py:
* pitivi/ui/timeline.py:
* pitivi/ui/viewer.py:
Switch to use playground's 'position' signal in Viewer and
ComplexTimeline.
This should fix several issues:
_ Position checking not being in ui-independent part,
_ Position updating not starting,
_ Position checking done during critical parts (state change).


git-svn-id: svn+ssh://svn.gnome.org/svn/pitivi/trunk@777 d3729300-e425-0410-8a4c-d956edccc248
parent d7a3bb8d
2006-05-16 Edward Hervey <edward@fluendo.com>
* pitivi/playground.py:
Added 'position' signal which is emitted to inform a change of position
with the current SmartBin.
* pitivi/ui/complextimeline.py:
* pitivi/ui/mainwindow.py:
* pitivi/ui/timeline.py:
* pitivi/ui/viewer.py:
Switch to use playground's 'position' signal in Viewer and
ComplexTimeline.
This should fix several issues:
_ Position checking not being in ui-independent part,
_ Position updating not starting,
_ Position checking done during critical parts (state change).
2006-05-16 Edward Hervey <edward@fluendo.com>
* pitivi/configure.py.in:
......
......@@ -45,6 +45,7 @@ class PlayGround(gobject.GObject):
bin-added : The given bin was added to the playground
bin-removed : The given bin was removed from the playground
error : An error was seen (two strings : reason, details)
position : Updated position (SmartBin, position)
"""
__gsignals__ = {
......@@ -62,7 +63,10 @@ class PlayGround(gobject.GObject):
( gobject.TYPE_PYOBJECT, )),
"error" : ( gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
( gobject.TYPE_STRING, gobject.TYPE_STRING ))
( gobject.TYPE_STRING, gobject.TYPE_STRING )),
"position" : ( gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
( gobject.TYPE_PYOBJECT, gobject.TYPE_UINT64 ))
}
def __init__(self):
......@@ -91,6 +95,9 @@ class PlayGround(gobject.GObject):
self.state = gst.STATE_READY
# handle for the position g_timeout_add()
self._positiontimeoutid = 0
if self.switchToDefault():
if self.current.set_state(self.state) == gst.STATE_CHANGE_FAILURE:
gst.warning("Couldn't set default bin to READY")
......@@ -142,6 +149,9 @@ class PlayGround(gobject.GObject):
if not pipeline in self.pipelines and not pipeline == self.default:
return True
if self.current:
if self._positiontimeoutid:
gobject.source_remove(self._positiontimeoutid)
self._positiontimeoutid = 0
self.current.info("setting to READY")
self.current.set_state(gst.STATE_READY)
self.current.removeAudioSinkThread()
......@@ -238,6 +248,10 @@ class PlayGround(gobject.GObject):
return False
target = self.current
if self._positiontimeoutid:
gobject.source_remove(self._positiontimeoutid)
self._positiontimeoutid = 0
# actual seeking
res = target.seek(1.0, format, gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_SET, value,
......@@ -246,6 +260,9 @@ class PlayGround(gobject.GObject):
gst.warning ("Seeking in current failed !");
return False
gst.debug("Seeking to %s succeeded" % gst.TIME_ARGS (value))
self.emit('position', self.current, value)
return True
def shutdown(self):
......@@ -253,9 +270,28 @@ class PlayGround(gobject.GObject):
for pipeline in self.pipelines:
gst.debug("Setting pipeline to NULL : %r" % pipeline)
pipeline.set_state(gst.STATE_NULL)
if self._positiontimeoutid:
gobject.source_remove(self._positiontimeoutid)
self._positiontimeoutid = 0
gst.debug("Setting DefaultBin to NULL")
self.default.set_state(gst.STATE_NULL)
#
# Position callback
#
def _checkTimeCb(self):
gst.log("Checking time, current:%r" % self.current)
try:
cur, format = self.current.query_position(gst.FORMAT_TIME)
except:
self.current.warning("Couldn't get position in time")
cur = 0
self.emit('position', self.current, cur)
# hit me !
return True
#
# Bus handler
#
......@@ -266,8 +302,11 @@ class PlayGround(gobject.GObject):
oldstate, newstate, pending = message.parse_state_changed()
message.src.debug("old:%s, new:%s, pending:%s" %
(oldstate, newstate, pending))
if message.src == self.current:
if (not self.current == self.default) and message.src == self.current:
if pending == gst.STATE_VOID_PENDING:
if (not self._positiontimeoutid) and newstate in [gst.STATE_PLAYING]:
self._checkTimeCb()
self._positiontimeoutid = gobject.timeout_add(300, self._checkTimeCb)
self.emit("current-state", newstate)
elif message.type == gst.MESSAGE_ERROR:
error, detail = message.parse_error()
......@@ -344,7 +383,12 @@ class PlayGround(gobject.GObject):
if not self.current or self.current == self.default:
return gst.STATE_CHANGE_SUCCESS
self.state = gst.STATE_PAUSED
return self.current.set_state(self.state)
res = self.current.set_state(self.state)
if self._positiontimeoutid:
gobject.source_remove(self._positiontimeoutid)
self._positiontimeoutid = 0
return res
def fast_forward(self):
""" fast forward the current pipeline """
......
......@@ -28,6 +28,7 @@ import gst
import pitivi.instance as instance
from pitivi.bin import SmartTimelineBin
from complexlayer import LayerInfoList
from layerwidgets import TopLayer, CompositionLayer
from complexinterface import ZoomableWidgetInterface
......@@ -123,6 +124,7 @@ class ComplexTimelineWidget(gtk.VBox, ZoomableWidgetInterface):
# common LayerInfoList
self.layerInfoList = LayerInfoList(instance.PiTiVi.current.timeline)
instance.PiTiVi.playground.connect('position', self._playgroundPositionCb)
for layer in self.layerInfoList:
layer.composition.connect('start-duration-changed',
self._layerStartDurationChangedCb)
......@@ -176,8 +178,9 @@ class ComplexTimelineWidget(gtk.VBox, ZoomableWidgetInterface):
def toolBarZoomChangedCb(self, unused_toolbar, zoomratio):
self.setZoomRatio(zoomratio)
## timeline position callback
## PlayGround timeline position callback
def timelinePositionChanged(self, value, frame):
# for the time being we only inform the ruler
self.topLayer.timelinePositionChanged(value, frame)
def _playgroundPositionCb(self, unused_playground, smartbin, value):
if isinstance(smartbin, SmartTimelineBin):
# for the time being we only inform the ruler
self.topLayer.timelinePositionChanged(value, frame=-1)
......@@ -137,9 +137,6 @@ class PitiviMainWindow(gtk.Window):
# Viewer
self.viewer = PitiviViewer()
# connect viewer's timeline position callback to the timeline widget
self.viewer.addTimelinePositionCallback(self.timeline.timelinePositionChanged)
hpaned.pack1(self.sourcefactories, resize=False, shrink=False)
hpaned.pack2(self.viewer, resize=True, shrink=False)
......
......@@ -73,9 +73,6 @@ class TimelineWidget(gtk.VBox):
gst.debug("state:%s" % event.state)
self.hscroll.emit("scroll-event", event)
def timelinePositionChanged(self, value, frame):
self.complexview.timelinePositionChanged(value, frame)
class SimpleTimelineContentWidget(gtk.HBox):
""" Widget for Simple Timeline content display """
def __init__(self, twidget):
......
......@@ -63,13 +63,11 @@ class PitiviViewer(gtk.VBox):
# TODO remove/replace the signal when closing/opening projects
instance.PiTiVi.current.sources.connect("tmp_is_ready", self._tmpIsReadyCb)
# Only set the check time timeout in certain cases...
self.checktimeoutid = 0
self.positionChangedCallbacks = []
instance.PiTiVi.connect("new-project", self._newProjectCb)
instance.PiTiVi.playground.connect("current-state", self._currentStateCb)
instance.PiTiVi.playground.connect("bin-added", self._binAddedCb)
instance.PiTiVi.playground.connect("bin-removed", self._binRemovedCb)
instance.PiTiVi.playground.connect("position", self._playgroundPositionCb)
instance.PiTiVi.current.settings.connect("settings-changed",
self._settingsChangedCb)
......@@ -241,11 +239,8 @@ class PitiviViewer(gtk.VBox):
def _sliderButtonPressCb(self, slider, unused_event):
gst.info("button pressed")
self.moving_slider = True
if self.checktimeoutid:
gobject.source_remove(self.checktimeoutid)
self.checktimeoutid = 0
self.valuechangedid = slider.connect("value-changed", self._sliderValueChangedCb)
instance.PiTiVi.playground.current.set_state(gst.STATE_PAUSED)
instance.PiTiVi.playground.pause()
return False
def _sliderButtonReleaseCb(self, slider, unused_event):
......@@ -254,11 +249,11 @@ class PitiviViewer(gtk.VBox):
if self.valuechangedid:
slider.disconnect(self.valuechangedid)
self.valuechangedid = 0
if not self.checktimeoutid:
gst.debug("adding checktime again")
self.checktimeoutid = gobject.timeout_add(300, self._checkTimeCb)
# revert to previous state
instance.PiTiVi.playground.current.set_state(self.currentState)
if self.currentState == gst.STATE_PAUSED:
instance.PiTiVi.playground.pause()
else:
instance.PiTiVi.playground.play()
return False
def _sliderValueChangedCb(self, slider):
......@@ -266,7 +261,6 @@ class PitiviViewer(gtk.VBox):
value = long(slider.get_value())
gst.info(time_to_string(value))
self._doSeek(value)
#instance.PiTiVi.playground.seekInCurrent(value)
def _sliderScrollCb(self, unused_slider, event):
# calculate new seek position
......@@ -277,7 +271,6 @@ class PitiviViewer(gtk.VBox):
else:
seekvalue = min(self.current_time + gst.SECOND / 2, instance.PiTiVi.playground.current.length)
self._doSeek(seekvalue)
#instance.PiTiVi.playground.seekInCurrent(seekvalue)
else:
# frame scrolling, frame by frame
gst.info("scroll direction:%s" % event.direction)
......@@ -288,7 +281,6 @@ class PitiviViewer(gtk.VBox):
gst.info("scrolling forward")
seekvalue = min(self.current_frame + 1, instance.PiTiVi.playground.current.length)
self._doSeek(seekvalue, gst.FORMAT_DEFAULT)
#instance.PiTiVi.playground.seekInCurrent(seekvalue, gst.FORMAT_DEFAULT)
def _seekTimeoutCb(self):
self.currentlySeeking = False
......@@ -304,33 +296,6 @@ class PitiviViewer(gtk.VBox):
elif format == gst.FORMAT_TIME:
self.requested_time = value
## timeout functions for checking current time
## TODO : check_time timeout should in fact be in the playground to be more generic
def _checkTimeCb(self):
# check time callback
gst.log("checking time")
if instance.PiTiVi.playground.current == instance.PiTiVi.playground.default:
return True
# don't check time if the timeline is not playing
cur = self.current_time
currentframe = self.current_frame
if True: #not isinstance(instance.PiTiVi.playground.current, SmartTimelineBin):
pending, state, result = instance.PiTiVi.playground.current.get_state(10)
if not state in [gst.STATE_PAUSED, gst.STATE_PLAYING]:
return
try:
cur, format = instance.PiTiVi.playground.current.query_position(gst.FORMAT_TIME)
except:
instance.PiTiVi.playground.current.warning("couldn't get position")
cur = 0
# if the current_time or the length has changed, update time
if not float(instance.PiTiVi.playground.current.length) == self.posadjust.upper or not cur == self.current_time or not currentframe == self.current_frame:
self.posadjust.upper = float(instance.PiTiVi.playground.current.length)
self._newTime(cur, currentframe)
return True
def _newTime(self, value, frame=-1):
gst.info("value:%s, frame:%d" % (gst.TIME_ARGS(value), frame))
self.current_time = value
......@@ -338,19 +303,8 @@ class PitiviViewer(gtk.VBox):
self.timelabel.set_markup("<tt>%s / %s</tt>" % (time_to_string(value), time_to_string(instance.PiTiVi.playground.current.length)))
if not self.moving_slider:
self.posadjust.set_value(float(value))
if isinstance(instance.PiTiVi.playground.current, SmartTimelineBin):
self._triggerTimelinePositionCallbacks(value, frame)
return False
def _triggerTimelinePositionCallbacks(self, value, frame = -1):
for callback in self.positionChangedCallbacks:
callback(value, frame)
def addTimelinePositionCallback(self, function):
""" Set the function that will be called whenever the timeline position has changed """
self.positionChangedCallbacks.append(function)
## gtk.ComboBox callbacks for sources
def _comboboxChangedCb(self, cbox):
......@@ -439,6 +393,10 @@ class PitiviViewer(gtk.VBox):
## Playground callbacks
def _playgroundPositionCb(self, playground, smartbin, pos):
self._newTime(pos)
print smartbin, pos
def _currentPlaygroundChangedCb(self, playground, smartbin):
if not smartbin == playground.default:
if isinstance(smartbin, SmartTimelineBin):
......@@ -487,14 +445,8 @@ class PitiviViewer(gtk.VBox):
def _currentStateCb(self, playground, state):
gst.info("current state changed : %s" % state)
if state == int(gst.STATE_PLAYING):
if not isinstance(playground.current, SmartDefaultBin) and not self.checktimeoutid:
gst.info("adding checktime")
self.checktimeoutid = gobject.timeout_add(300, self._checkTimeCb)
self.playpause_button.setPause()
elif state == int(gst.STATE_PAUSED):
if not isinstance(playground.current, SmartDefaultBin) and not self.checktimeoutid:
gst.info("adding checktime")
self.checktimeoutid = gobject.timeout_add(300, self._checkTimeCb)
self.playpause_button.setPlay()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment