[pitivi] pipeline: Get rid of Seeker
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] pipeline: Get rid of Seeker
- Date: Thu, 17 Dec 2015 10:03:53 +0000 (UTC)
commit f9a143a9b56bbc3c33364636a99814bc7fc7d964
Author: Alexandru Băluț <alexandru balut gmail com>
Date: Fri Nov 13 23:33:01 2015 +0100
pipeline: Get rid of Seeker
Fixes https://phabricator.freedesktop.org/T3055
Reviewed-by: Thibault Saunier <tsaunier gnome org>
Differential Revision: https://phabricator.freedesktop.org/D565
pitivi/mediafilespreviewer.py | 2 +-
pitivi/project.py | 31 ++++++-------
pitivi/timeline/ruler.py | 19 ++++++--
pitivi/timeline/timeline.py | 10 ++--
pitivi/titleeditor.py | 9 ++--
pitivi/transitions.py | 6 +-
pitivi/utils/pipeline.py | 95 +++++++++-------------------------------
pitivi/utils/widgets.py | 1 -
pitivi/viewer.py | 62 +++++++++++---------------
9 files changed, 91 insertions(+), 144 deletions(-)
---
diff --git a/pitivi/mediafilespreviewer.py b/pitivi/mediafilespreviewer.py
index 6e257c2..d258c52 100644
--- a/pitivi/mediafilespreviewer.py
+++ b/pitivi/mediafilespreviewer.py
@@ -108,7 +108,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
# Gui elements:
# Drawing area for video output
- self.preview_video = ViewerWidget(self.player.video_sink)
+ self.preview_video = ViewerWidget(self.player)
self.preview_video.props.hexpand = minimal
self.preview_video.props.vexpand = minimal
self.preview_video.show_all()
diff --git a/pitivi/project.py b/pitivi/project.py
index a0e9af0..a30ba49 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -24,34 +24,34 @@
Project related classes
"""
+import datetime
import os
+import pwd
+import tarfile
+import time
+
from gi.repository import GstPbutils
from gi.repository import GES
from gi.repository import Gst
from gi.repository import Gtk
from gi.repository import GLib
from gi.repository import GObject
-import tarfile
-from time import time
-from datetime import datetime
from gettext import gettext as _
-from pwd import getpwuid
from pitivi.configure import get_ui_dir
+from pitivi.preset import AudioPresetManager, VideoPresetManager
+from pitivi.render import CachedEncoderList
from pitivi.undo.undo import UndoableAction
-from pitivi.utils.validate import has_validate, create_monitor
-from pitivi.utils.misc import quote_uri, path_from_uri, isWritable, unicode_error_dialog
-from pitivi.utils.pipeline import PipelineError, Seeker
from pitivi.utils.loggable import Loggable
-from pitivi.utils.pipeline import Pipeline
-from pitivi.utils.widgets import FractionWidget
+from pitivi.utils.misc import quote_uri, path_from_uri, isWritable, unicode_error_dialog
+from pitivi.utils.pipeline import Pipeline, PipelineError
from pitivi.utils.ripple_update_group import RippleUpdateGroup
from pitivi.utils.ui import frame_rates, audio_rates,\
audio_channels, beautify_time_delta, get_combo_value, set_combo_value,\
pixel_aspect_ratios, display_aspect_ratios, SPACING
-from pitivi.preset import AudioPresetManager, VideoPresetManager
-from pitivi.render import CachedEncoderList
+from pitivi.utils.validate import has_validate, create_monitor
+from pitivi.utils.widgets import FractionWidget
DEFAULT_NAME = _("New Project")
@@ -592,7 +592,7 @@ class ProjectManager(GObject.Object, Loggable):
project = Project(self.app, name=DEFAULT_NAME)
# setting default values for project metadata
- project.author = getpwuid(os.getuid()).pw_gecos.split(",")[0]
+ project.author = pwd.getpwuid(os.getuid()).pw_gecos.split(",")[0]
project.createTimeline()
project._ensureTracks()
@@ -604,7 +604,7 @@ class ProjectManager(GObject.Object, Loggable):
project.pipeline.connect("died", self._pipelineDied)
project.setModificationState(False)
self.emit("new-project-loaded", self.current_project, emission)
- self.time_loaded = time()
+ self.time_loaded = time.time()
return True
@@ -680,7 +680,7 @@ class ProjectManager(GObject.Object, Loggable):
self.emit("new-project-loaded", self.current_project, True)
if self.__missing_uris:
self.current_project.setModificationState(True)
- self.time_loaded = time()
+ self.time_loaded = time.time()
class Project(Loggable, GES.Project):
@@ -726,7 +726,6 @@ class Project(Loggable, GES.Project):
self.log("name:%s, uri:%s", name, uri)
self.pipeline = None
self.timeline = None
- self.seeker = Seeker()
self.uri = uri
self.loaded = False
self._at_least_one_asset_missing = False
@@ -1696,7 +1695,7 @@ class ProjectSettingsDialog(object):
if self.project.year:
year = int(self.project.year)
else:
- year = datetime.now().year
+ year = datetime.datetime.now().year
self.year_spinbutton.get_adjustment().set_value(year)
def updateProject(self):
diff --git a/pitivi/timeline/ruler.py b/pitivi/timeline/ruler.py
index 52af7ff..14f4575 100644
--- a/pitivi/timeline/ruler.py
+++ b/pitivi/timeline/ruler.py
@@ -33,7 +33,6 @@ from gettext import gettext as _
from pitivi import configure
from pitivi.utils.loggable import Loggable
-from pitivi.utils.pipeline import Seeker
from pitivi.utils.timeline import Zoomable
from pitivi.utils.ui import NORMAL_FONT, PLAYHEAD_WIDTH, set_cairo_color, time_to_string, beautify_length
@@ -92,6 +91,9 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
Displays a series of consecutive intervals. For each interval its beginning
time is shown. If zoomed in enough, shows the frames in alternate colors.
+
+ @type timeline: L{pitivi.timeline.timeline.TimelineContainer}
+ @type _pipeline: L{pitivi.utils.pipeline.Pipeline}
"""
def __init__(self, timeline, hadj):
@@ -101,7 +103,7 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
self.log("Creating new ScaleRuler")
self.timeline = timeline
- self._seeker = Seeker()
+ self._pipeline = None
self.hadj = hadj
hadj.connect("value-changed", self._hadjValueChangedCb)
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK |
@@ -135,7 +137,8 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
# Timeline position changed method
def setPipeline(self, pipeline):
- pipeline.connect('position', self.timelinePositionCb)
+ self._pipeline = pipeline
+ self._pipeline.connect('position', self.timelinePositionCb)
def timelinePositionCb(self, unused_pipeline, position):
self.position = position
@@ -188,9 +191,12 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
return False
def do_button_press_event(self, event):
+ if not self._pipeline:
+ return False
+
self.debug("button pressed at x:%d", event.x)
position = self.pixelToNs(event.x + self.pixbuf_offset)
- self._seeker.seek(position)
+ self._pipeline.simple_seek(position)
return False
def do_button_release_event(self, event):
@@ -199,12 +205,15 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
return False
def do_motion_notify_event(self, event):
+ if not self._pipeline:
+ return False
+
position = self.pixelToNs(event.x + self.pixbuf_offset)
seek_mask = (Gdk.ModifierType.BUTTON3_MASK |
Gdk.ModifierType.BUTTON1_MASK)
if event.state & seek_mask:
self.debug("motion at event.x %d", event.x)
- self._seeker.seek(position)
+ self._pipeline.simple_seek(position)
human_time = beautify_length(position)
cur_frame = int(position / self.ns_per_frame) + 1
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 3903791..2bdc136 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -212,6 +212,8 @@ class Marquee(Gtk.Box, Loggable):
class Timeline(Gtk.EventBox, Zoomable, Loggable):
"""
Contains the layer controls and the layers representation.
+
+ @type _project: L{pitivi.project.Project}
"""
__gtype_name__ = "PitiviTimeline"
@@ -684,7 +686,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
x -= CONTROL_WIDTH
x += self.hadj.get_value()
position = max(0, self.pixelToNs(x))
- self._project.seeker.seek(position)
+ self._project.pipeline.simple_seek(position)
def __scroll(self, event):
# determine how much to move the canvas
@@ -1720,14 +1722,14 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
# shortcuts
if event.keyval == Gdk.KEY_Left:
if self._shiftMask:
- self._seeker.seekRelative(0 - Gst.SECOND)
+ self._project.pipeline.seekRelative(0 - Gst.SECOND)
else:
self._project.pipeline.stepFrame(self._framerate, -1)
self.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
return True
elif event.keyval == Gdk.KEY_Right:
if self._shiftMask:
- self._seeker.seekRelative(Gst.SECOND)
+ self._project.pipeline.seekRelative(Gst.SECOND)
else:
self._project.pipeline.stepFrame(self._framerate, 1)
self.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
@@ -1778,7 +1780,6 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
"""
assert self._project is project
if self._project:
- self._seeker = self._project.seeker
self.ruler.setPipeline(self._project.pipeline)
self.ruler.setProjectFrameRate(self._project.videorate)
@@ -1805,7 +1806,6 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
pass # We were not connected no problem
self.timeline._pipeline = None
- self._seeker = None
self.setProject(project)
diff --git a/pitivi/titleeditor.py b/pitivi/titleeditor.py
index 5325c0d..34b9eea 100644
--- a/pitivi/titleeditor.py
+++ b/pitivi/titleeditor.py
@@ -30,7 +30,6 @@ from gettext import gettext as _
from pitivi.configure import get_ui_dir
from pitivi.utils.loggable import Loggable
-from pitivi.utils.pipeline import Seeker
from pitivi.utils.timeline import SELECT
from pitivi.utils.ui import argb_to_gdk_rgba, gdk_rgba_to_argb
@@ -48,6 +47,7 @@ class TitleEditor(Loggable):
Widget for configuring the selected title.
@type app: L{Pitivi}
+ @type _project: L{pitivi.project.Project}
"""
def __init__(self, app):
@@ -56,7 +56,7 @@ class TitleEditor(Loggable):
self.action_log = app.action_log
self.settings = {}
self.source = None
- self.seeker = Seeker()
+ self._project = None
self._selection = None
self._setting_props = False
@@ -229,7 +229,7 @@ class TitleEditor(Loggable):
def _propertyChangedCb(self, source, unused_gstelement, pspec):
if self._setting_props:
- self.seeker.flush()
+ self._project.pipeline.flushSeek()
return
value = self.source.get_child_property(pspec.name)[1]
@@ -263,7 +263,7 @@ class TitleEditor(Loggable):
return
self.background_color_button.set_rgba(color)
- self.seeker.flush()
+ self._project.pipeline.flushSeek()
def _newProjectLoadedCb(self, app, project, unused_fully_loaded):
if self._selection is not None:
@@ -272,6 +272,7 @@ class TitleEditor(Loggable):
if project:
self._selection = project.timeline.ui.selection
self._selection.connect('selection-changed', self._selectionChangedCb)
+ self._project = project
def _selectionChangedCb(self, selection):
selected_clip = selection.getSingleClip(GES.TitleClip)
diff --git a/pitivi/transitions.py b/pitivi/transitions.py
index dd5e37a..7fd56ad 100644
--- a/pitivi/transitions.py
+++ b/pitivi/transitions.py
@@ -182,7 +182,7 @@ class TransitionsListWidget(Gtk.Box, Loggable):
self.app.write_action("element-set-asset", {
"asset-id": transition_asset.get_id(),
"element-name": self.element.get_name()})
- self.app.project_manager.current_project.seeker.flush(True)
+ self.app.project_manager.current_project.pipeline.flushSeek()
return True
@@ -191,14 +191,14 @@ class TransitionsListWidget(Gtk.Box, Loggable):
self.debug("User changed the border property to %s", value)
self.element.set_border(int(value))
self.app.project_manager.current_project.setModificationState(True)
- self.app.project_manager.current_project.seeker.flush(True)
+ self.app.project_manager.current_project.pipeline.flushSeek()
def _invertCheckboxCb(self, widget):
value = widget.get_active()
self.debug("User changed the invert property to %s", value)
self.element.set_inverted(value)
self.app.project_manager.current_project.setModificationState(True)
- self.app.project_manager.current_project.seeker.flush()
+ self.app.project_manager.current_project.pipeline.flushSeek()
def _borderTypeChangedCb(self, widget):
self.__updateBorderScale(widget == self.border_mode_loop)
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index c7323aa..8fe0e88 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -24,6 +24,7 @@
"""
High-level pipelines
"""
+
import os
from gi.repository import GLib
@@ -57,52 +58,6 @@ class PipelineError(Exception):
pass
-class Seeker(GObject.Object, Loggable):
-
- """
- The Seeker is a singleton helper class to do various seeking
- operations in the pipeline.
- """
-
- _instance = None
-
- __gsignals__ = {
- "seek": (GObject.SIGNAL_RUN_LAST, None, (GObject.TYPE_UINT64,)),
- "seek-relative": (GObject.SIGNAL_RUN_LAST, None, (GObject.TYPE_INT64,)),
- }
-
- def __new__(cls, *args, **kwargs):
- """
- Override the new method to return the singleton instance if available.
- Otherwise, create one.
- """
- if not cls._instance:
- cls._instance = super(Seeker, cls).__new__(cls, *args, **kwargs)
- return cls._instance
-
- def __init__(self):
- GObject.Object.__init__(self)
- Loggable.__init__(self)
-
- def seek(self, position):
- position = max(0, position)
- try:
- self.emit('seek', position)
- except PipelineError as e:
- self.error("Error while seeking to position: %s, reason: %s",
- format_ns(position), e)
-
- def seekRelative(self, time):
- time = int(time)
- try:
- self.emit('seek-relative', time)
- except PipelineError:
- self.error("Error while seeking %s relative", time)
-
- def flush(self):
- self.seekRelative(0)
-
-
class SimplePipeline(GObject.Object, Loggable):
"""
@@ -117,6 +72,8 @@ class SimplePipeline(GObject.Object, Loggable):
- C{position} : The current position of the pipeline changed.
- C{eos} : The Pipeline has finished playing.
- C{error} : An error happened.
+
+ @type _pipeline: L{Gst.Pipeline}
"""
__gsignals__ = PIPELINE_SIGNALS
@@ -191,7 +148,7 @@ class SimplePipeline(GObject.Object, Loggable):
return
try:
- self.seekRelative(0)
+ self.simple_seek(self.getPosition())
except PipelineError as e:
self.warning("Could not flush because: %s", e)
pass
@@ -397,9 +354,13 @@ class SimplePipeline(GObject.Object, Loggable):
# clamp between [0, duration]
position = max(0, min(position, self.getDuration()))
- res = self._pipeline.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
- Gst.SeekType.SET, position,
- Gst.SeekType.NONE, -1)
+ res = self._pipeline.seek(1.0,
+ Gst.Format.TIME,
+ Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
+ Gst.SeekType.SET,
+ position,
+ Gst.SeekType.NONE,
+ -1)
self._addWaitingForAsyncDoneTimeout()
if not res:
@@ -411,7 +372,10 @@ class SimplePipeline(GObject.Object, Loggable):
self.emit('position', position)
def seekRelative(self, time_delta):
- self.simple_seek(self.getPosition() + time_delta)
+ try:
+ self.simple_seek(self.getPosition() + int(time_delta))
+ except PipelineError:
+ self.error("Error while seeking %s relative", time_delta)
# Private methods
@@ -568,12 +532,11 @@ class Pipeline(GES.Pipeline, SimplePipeline):
"""
Helper to handle GES.Pipeline through the SimplePipeline API
- and handle the Seeker properly
"""
__gsignals__ = PIPELINE_SIGNALS
- def __init__(self, app, pipeline=None):
+ def __init__(self, app):
GES.Pipeline.__init__(self)
SimplePipeline.__init__(self, self)
@@ -583,9 +546,6 @@ class Pipeline(GES.Pipeline, SimplePipeline):
self._commit_wanted = False
self._timeline = None
- self._seeker = Seeker()
- self._seeker.connect("seek", self._seekCb)
- self._seeker.connect("seek-relative", self._seekRelativeCb)
if "watchdog" in os.environ.get("PITIVI_UNSTABLE_FEATURES", ''):
watchdog = Gst.ElementFactory.make("watchdog", None)
@@ -618,13 +578,8 @@ class Pipeline(GES.Pipeline, SimplePipeline):
@postcondition: The L{Pipeline} will no longer be usable.
"""
- self._seeker.disconnect_by_func(self._seekRelativeCb)
- self._seeker.disconnect_by_func(self._seekCb)
SimplePipeline.release(self)
- def _seekRelativeCb(self, unused_seeker, time_delta):
- self.seekRelative(time_delta)
-
def stepFrame(self, framerate, frames_offset):
"""
Seek backwards or forwards a certain amount of frames (frames_offset).
@@ -649,33 +604,27 @@ class Pipeline(GES.Pipeline, SimplePipeline):
new_pos / float(Gst.SECOND))
self.simple_seek(new_pos)
- def _seekCb(self, unused_seeker, position):
- """
- The app's main seek method used when the user seeks manually.
-
- We clamp the seeker position so that it cannot go past 0 or the
- end of the timeline.
- """
- self.simple_seek(position)
-
def simple_seek(self, position):
if self._timeline.is_empty():
+ # Nowhere to seek.
return
if self._rendering():
raise PipelineError("Trying to seek while rendering")
st = Gst.Structure.new_empty("seek")
-
if self.getState() == Gst.State.PLAYING:
st.set_value("playback_time", float(
self.getPosition()) / Gst.SECOND)
-
st.set_value("start", float(position / Gst.SECOND))
st.set_value("flags", "accurate+flush")
self.app.write_action(st)
- SimplePipeline.simple_seek(self, position)
+ try:
+ SimplePipeline.simple_seek(self, position)
+ except PipelineError as e:
+ self.error("Error while seeking to position: %s, reason: %s",
+ format_ns(position), e)
def _busMessageCb(self, bus, message):
if message.type == Gst.MessageType.ASYNC_DONE:
diff --git a/pitivi/utils/widgets.py b/pitivi/utils/widgets.py
index 47e292b..f50d09c 100644
--- a/pitivi/utils/widgets.py
+++ b/pitivi/utils/widgets.py
@@ -316,7 +316,6 @@ class TimeWidget(TextWidget, DynamicWidget):
# We were given a frame number. Convert from the project framerate.
frame_no = int(timecode)
nanosecs = frame_no / float(self._framerate) * Gst.SECOND
- # The seeker won't like floating point nanoseconds!
return int(nanosecs)
def setWidgetValue(self, timeNanos, send_signal=True):
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index 1392bdc..26311f8 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -31,7 +31,7 @@ from time import time
from pitivi.settings import GlobalSettings
from pitivi.utils.loggable import Loggable
from pitivi.utils.misc import format_ns
-from pitivi.utils.pipeline import AssetPipeline, Seeker
+from pitivi.utils.pipeline import AssetPipeline
from pitivi.utils.ui import SPACING
from pitivi.utils.widgets import TimeWidget
@@ -66,7 +66,10 @@ class ViewerContainer(Gtk.Box, Loggable):
"""
A wiget holding a viewer and the controls.
+
+ @type pipeline: L{pitivi.utils.pipeline.SimplePipeline}
"""
+
__gtype_name__ = 'ViewerContainer'
__gsignals__ = {
"activate-playback-controls": (GObject.SignalFlags.RUN_LAST,
@@ -87,7 +90,6 @@ class ViewerContainer(Gtk.Box, Loggable):
self.pipeline = None
self.docked = True
- self.seeker = Seeker()
self.target = None
self._compactMode = False
@@ -123,7 +125,7 @@ class ViewerContainer(Gtk.Box, Loggable):
self.debug("New pipeline: %r", pipeline)
self.pipeline = pipeline
if position:
- self.seeker.seek(position)
+ self.pipeline.simple_seek(position)
self.pipeline.connect("state-change", self._pipelineStateChangedCb)
self.pipeline.connect("position", self._positionCb)
@@ -139,7 +141,7 @@ class ViewerContainer(Gtk.Box, Loggable):
self.sink = self.pipeline.createSink()
self.pipeline.setSink(self.sink)
- self.target = ViewerWidget(self.sink, self.app)
+ self.target = ViewerWidget(self.pipeline, self.app)
if self.docked:
self.pack_start(self.target, True, True, 0)
@@ -296,7 +298,7 @@ class ViewerContainer(Gtk.Box, Loggable):
def _entryActivateCb(self, unused_entry):
nanoseconds = self.timecode_entry.getWidgetValue()
- self.seeker.seek(nanoseconds)
+ self.app.project_manager.current_project.pipeline.simple_seek(nanoseconds)
self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
# Active Timeline calllbacks
@@ -311,25 +313,25 @@ class ViewerContainer(Gtk.Box, Loggable):
self.app.gui.focusTimeline()
def _goToStartCb(self, unused_button):
- self.seeker.seek(0)
+ self.app.project_manager.current_project.pipeline.simple_seek(0)
self.app.gui.focusTimeline()
self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.START, when_not_in_view=True)
def _backCb(self, unused_button):
# Seek backwards one second
- self.seeker.seekRelative(0 - Gst.SECOND)
+ self.app.project_manager.current_project.pipeline.seekRelative(0 - Gst.SECOND)
self.app.gui.focusTimeline()
self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.END, when_not_in_view=True)
def _forwardCb(self, unused_button):
# Seek forward one second
- self.seeker.seekRelative(Gst.SECOND)
+ self.app.project_manager.current_project.pipeline.seekRelative(Gst.SECOND)
self.app.gui.focusTimeline()
self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.START, when_not_in_view=True)
def _goToEndCb(self, unused_button):
end = self.app.project_manager.current_project.pipeline.getDuration()
- self.seeker.seek(end)
+ self.app.project_manager.current_project.pipeline.simple_seek(end)
self.app.gui.focusTimeline()
self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
@@ -368,7 +370,7 @@ class ViewerContainer(Gtk.Box, Loggable):
self.settings.viewerWidth, self.settings.viewerHeight)
if self.pipeline:
self.pipeline.pause()
- self.seeker.seek(position)
+ self.pipeline.simple_seek(position)
def dock(self):
if self.docked:
@@ -393,7 +395,7 @@ class ViewerContainer(Gtk.Box, Loggable):
self.external_window.hide()
if position:
self.pipeline.pause()
- self.seeker.seek(position)
+ self.pipeline.simple_seek(position)
def _toggleFullscreen(self, widget):
if widget.get_active():
@@ -491,6 +493,8 @@ class TransformationBox(Gtk.EventBox, Loggable):
self.app = app
self.__editSource = None
self.__startDraggingPosition = None
+ self.__startEditSourcePosition = None
+
self.add_events(Gdk.EventMask.SCROLL_MASK)
def __setupEditSource(self):
@@ -613,56 +617,42 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
"""
Widget for displaying a GStreamer video sink.
- @ivar settings: The settings of the application.
- @type settings: L{GlobalSettings}
+ @type _pipeline: L{pitivi.utils.pipeline.SimplePipeline}
"""
__gsignals__ = {}
- def __init__(self, sink, app=None):
+ def __init__(self, pipeline, app=None):
# Prevent black frames and flickering while resizing or changing focus:
# The aspect ratio gets overridden by setDisplayAspectRatio.
Gtk.AspectFrame.__init__(self, xalign=0.5, yalign=0.5,
ratio=4.0 / 3.0, obey_child=False)
Loggable.__init__(self)
- self.__transformationBox = TransformationBox(app)
+
+ self._pipeline = pipeline
+
+ transformation_box = TransformationBox(app)
+ self.add(transformation_box)
# We only work with a gtkglsink inside a glsinkbin
+ sink = pipeline.video_sink
try:
self.drawing_area = sink.props.sink.props.widget
except AttributeError:
self.drawing_area = sink.props.widget
+ self.drawing_area.show()
+ transformation_box.add(self.drawing_area)
# We keep the ViewerWidget hidden initially, or the desktop wallpaper
# would show through the non-double-buffered widget!
- self.add(self.__transformationBox)
- self.__transformationBox.add(self.drawing_area)
-
- self.drawing_area.show()
-
- self.seeker = Seeker()
- if app:
- self.settings = app.settings
- self.app = app
- self.box = None
- self.stored = False
- self.area = None
- self.zoom = 1.0
- self.sink = sink
- self.transformation_properties = None
- self._setting_ratio = False
- self.__startDraggingPosition = None
- self.__startEditSourcePosition = None
- self.__editSource = None
def setDisplayAspectRatio(self, ratio):
- self._setting_ratio = True
self.set_property("ratio", float(ratio))
def _sizeCb(self, unused_widget, unused_area):
# The transformation box is cleared when using regular rendering
# so we need to flush the pipeline
- self.seeker.flush()
+ self._pipeline.flushSeek()
def do_get_preferred_width(self):
# Do not let a chance for Gtk to choose video natural size
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]