[pitivi] Reimplement the transformation box
- From: Thibault Saunier <tsaunier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Reimplement the transformation box
- Date: Wed, 16 Sep 2015 15:51:02 +0000 (UTC)
commit 45ea0377618660efabf0982d595f16849766f9f0
Author: Thibault Saunier <tsaunier gnome org>
Date: Sat Jun 13 18:35:09 2015 +0200
Reimplement the transformation box
Summary:
For the time being there is no visual indicator, but the
user can manipulate the video in the viewer with the
following shortcut:
* Dragging the in the viewer while a clip is selected at the current
playback position will move the image
* Scrolling in the viewer in the same condition will 'zoom in/out'
meaning that it will actually changed the size of the video, keeping
aspect ratio
* Scrolling with the shift modifier will change the height
* Scrolling with the control modifier will change the width
Depends on D267
Reviewers: Mathieu_Du, aleb
Differential Revision: https://phabricator.freedesktop.org/D268
data/ui/cliptransformation.ui | 235 ++++------------------------------------
pitivi/clipproperties.py | 155 +++++++++++----------------
pitivi/viewer.py | 122 ++++++++++++++++++++--
3 files changed, 200 insertions(+), 312 deletions(-)
---
diff --git a/data/ui/cliptransformation.ui b/data/ui/cliptransformation.ui
index 86553e2..1035f20 100644
--- a/data/ui/cliptransformation.ui
+++ b/data/ui/cliptransformation.ui
@@ -2,64 +2,29 @@
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
- <object class="GtkAdjustment" id="crop_bottom_adjustment">
- <property name="upper">1</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
- </object>
- <object class="GtkAdjustment" id="crop_left_adjustment">
- <property name="upper">1</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
- </object>
- <object class="GtkAdjustment" id="crop_right_adjustment">
- <property name="upper">1</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
- </object>
- <object class="GtkAdjustment" id="crop_top_adjustment">
- <property name="upper">1</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
- </object>
<object class="GtkAdjustment" id="height_adjustment">
- <property name="upper">100</property>
- <property name="value">0.5</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
+ <property name="lower">-9999999999</property>
+ <property name="upper">9999999999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="position_x_adjustment">
- <property name="lower">-1</property>
- <property name="upper">2</property>
- <property name="value">0.5</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
+ <property name="lower">-9999999999</property>
+ <property name="upper">9999999999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="position_y_adjustment">
- <property name="lower">-1</property>
- <property name="upper">2</property>
- <property name="value">0.5</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
- </object>
- <object class="GtkAdjustment" id="rotation_adjustment">
- <property name="lower">-999.99000000000001</property>
- <property name="upper">999.99000000000001</property>
+ <property name="lower">-9999999999</property>
+ <property name="upper">9999999999</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="width_adjustment">
- <property name="upper">100</property>
- <property name="value">0.5</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
- </object>
- <object class="GtkAdjustment" id="zoom_adjustment">
- <property name="lower">0.10000000000000001</property>
- <property name="upper">1</property>
- <property name="value">1</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">0.10000000000000001</property>
+ <property name="lower">-9999999999</property>
+ <property name="upper">9999999999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
</object>
<object class="GtkBox" id="transform_box">
<property name="visible">True</property>
@@ -96,45 +61,6 @@
</packing>
</child>
<child>
- <object class="GtkFrame" id="frame4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkScale" id="zoom_scale">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="adjustment">zoom_adjustment</property>
- <property name="round_digits">1</property>
- <property name="draw_value">False</property>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Viewer Zoom</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
<object class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -167,8 +93,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
+ <property name="progress_pulse_step">1</property>
<property name="adjustment">position_x_adjustment</property>
- <property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
@@ -194,8 +120,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
+ <property name="progress_pulse_step">1</property>
<property name="adjustment">position_y_adjustment</property>
- <property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
@@ -258,8 +184,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
+ <property name="input_purpose">digits</property>
<property name="adjustment">width_adjustment</property>
- <property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
@@ -286,7 +212,6 @@
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="adjustment">height_adjustment</property>
- <property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
@@ -316,124 +241,12 @@
<property name="position">3</property>
</packing>
</child>
- <child>
- <object class="GtkFrame" id="frame2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="xscale">0</property>
- <child>
- <object class="GtkGrid" id="grid1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="row_spacing">3</property>
- <property name="column_spacing">3</property>
- <child>
- <object class="GtkSpinButton" id="crop_left_spinbtn">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">•</property>
- <property name="adjustment">crop_left_adjustment</property>
- <property name="digits">2</property>
- <property name="numeric">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="crop_top_spinbtn">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">•</property>
- <property name="adjustment">crop_top_adjustment</property>
- <property name="digits">2</property>
- <property name="numeric">True</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="crop_bottom_spinbtn">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">•</property>
- <property name="adjustment">crop_bottom_adjustment</property>
- <property name="digits">2</property>
- <property name="numeric">True</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="crop_right_spinbtn">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">•</property>
- <property name="adjustment">crop_right_adjustment</property>
- <property name="digits">2</property>
- <property name="numeric">True</property>
- </object>
- <packing>
- <property name="left_attach">3</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Crop</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- </packing>
- </child>
+ </object>
+ <object class="GtkAdjustment" id="zoom_adjustment">
+ <property name="lower">0.10000000000000001</property>
+ <property name="upper">1</property>
+ <property name="value">1</property>
+ <property name="step_increment">0.01</property>
+ <property name="page_increment">0.10000000000000001</property>
</object>
</interface>
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index d33ffbf..a8c2c50 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -30,8 +30,6 @@ from gettext import gettext as _
from pitivi.configure import get_ui_dir
-from pitivi.dialogs.depsmanager import DepsManager
-
from pitivi.utils.ui import EFFECT_TARGET_ENTRY
from pitivi.utils.loggable import Loggable
from pitivi.utils.ui import PADDING, SPACING
@@ -74,10 +72,10 @@ class ClipProperties(Gtk.Box, Loggable):
self.infobar_box.show()
self.pack_start(self.infobar_box, False, False, 0)
- # Transformation boxed DISABLED
- # self.transformation_expander = TransformationProperties(instance, instance.action_log)
- # self.transformation_expander.set_vexpand(False)
- # vbox.pack_start(self.transformation_expander, False, False, 0)
+ self.transformation_expander = TransformationProperties(app, app.action_log)
+ self.transformation_expander.set_vexpand(False)
+ self.pack_start(self.transformation_expander, False, False, 0)
+ self.transformation_expander.show_all()
effects_properties_manager = EffectsPropertiesManager(app)
self.effect_expander = EffectProperties(
@@ -95,9 +93,8 @@ class ClipProperties(Gtk.Box, Loggable):
if project:
self.effect_expander._connectTimelineSelection(
self.app.gui.timeline_ui.timeline)
- # Transformation boxed DISABLED
- # if self.transformation_expander:
- # self.transformation_expander.timeline = self.app.gui.timeline_ui.timeline
+ if self.transformation_expander:
+ self.transformation_expander.timeline = self.app.gui.timeline_ui.timeline
def _getProject(self):
return self._project
@@ -192,8 +189,8 @@ class EffectProperties(Gtk.Expander, Loggable):
activatedcell = Gtk.CellRendererToggle()
activatedcell.props.xpad = PADDING
activatedcell.connect("toggled", self._effectActiveToggleCb)
- activatedcol = self.treeview.insert_column_with_attributes(-1,
- _("Active"), activatedcell,
active=COL_ACTIVATED)
+ self.treeview.insert_column_with_attributes(-1,
+ _("Active"), activatedcell, active=COL_ACTIVATED)
typecol = Gtk.TreeViewColumn(_("Type"))
typecol.set_spacing(SPACING)
@@ -551,7 +548,7 @@ class EffectProperties(Gtk.Expander, Loggable):
self._effect_config_ui.show_all()
-class TransformationProperties(Gtk.Expander):
+class TransformationProperties(Gtk.Expander, Loggable):
"""
Widget for viewing and configuring speed
"""
@@ -561,9 +558,11 @@ class TransformationProperties(Gtk.Expander):
def __init__(self, app, action_log):
Gtk.Expander.__init__(self)
+ Loggable.__init__(self)
self.action_log = action_log
self.app = app
self._timeline = None
+ self.source = None
self._selected_clip = None
self.spin_buttons = {}
self.default_values = {}
@@ -580,59 +579,55 @@ class TransformationProperties(Gtk.Expander):
self.hide()
def _initButtons(self):
- self.zoom_scale = self.builder.get_object("zoom_scale")
- self.zoom_scale.connect("value-changed", self._zoomViewerCb)
clear_button = self.builder.get_object("clear_button")
clear_button.connect("clicked", self._defaultValuesCb)
- self._getAndConnectToEffect("xpos_spinbtn", "tilt_x")
- self._getAndConnectToEffect("ypos_spinbtn", "tilt_y")
+ self.__setupSpinButton("xpos_spinbtn", "posx")
+ self.__setupSpinButton("ypos_spinbtn", "posy")
- self._getAndConnectToEffect("width_spinbtn", "scale_x")
- self._getAndConnectToEffect("height_spinbtn", "scale_y")
-
- self._getAndConnectToEffect("crop_left_spinbtn", "clip_left")
- self._getAndConnectToEffect("crop_right_spinbtn", "clip_right")
- self._getAndConnectToEffect("crop_top_spinbtn", "clip_top")
- self._getAndConnectToEffect("crop_bottom_spinbtn", "clip_bottom")
- self.connectSpinButtonsToFlush()
+ self.__setupSpinButton("width_spinbtn", "width")
+ self.__setupSpinButton("height_spinbtn", "height")
def _zoomViewerCb(self, scale):
self.app.gui.viewer.setZoom(scale.get_value())
def _expandedCb(self, expander, params):
if self._selected_clip:
- self.effect = self._findOrCreateEffect("frei0r-filter-scale0tilt")
- self._updateSpinButtons()
+ self.source = self._selected_clip.find_track_element(None,
+ GES.VideoSource)
+ self.__setSource()
self.set_expanded(self.get_expanded())
- self._updateBoxVisibility()
- self.zoom_scale.set_value(1.0)
else:
- if self.get_expanded():
- DepsManager(self.app)
self.set_expanded(False)
def _defaultValuesCb(self, widget):
- self.disconnectSpinButtonsFromFlush()
for name, spinbtn in list(self.spin_buttons.items()):
spinbtn.set_value(self.default_values[name])
- self.connectSpinButtonsToFlush()
- # FIXME Why are we looking at the gnl object directly?
- self.effect.gnl_object.props.active = False
- def disconnectSpinButtonsFromFlush(self):
- for spinbtn in list(self.spin_buttons.values()):
- spinbtn.disconnect_by_func(self._flushPipeLineCb)
+ def __sourcePropertyChangedCb(self, source, element, param):
+ try:
+ spin = self.spin_buttons[param.name]
+ except KeyError:
+ return
- def connectSpinButtonsToFlush(self):
- for spinbtn in list(self.spin_buttons.values()):
- spinbtn.connect("output", self._flushPipeLineCb)
+ res, value = self.source.get_child_property(param.name)
+ if spin.get_value() != value:
+ spin.set_value(value)
def _updateSpinButtons(self):
for name, spinbtn in list(self.spin_buttons.items()):
- spinbtn.set_value(self.effect.get_property(name))
+ res, value = self.source.get_child_property(name)
+ assert(res)
+ if name == "width":
+ self.default_values[name] = self.app.project_manager.current_project.videowidth
+ elif name == "height":
+ self.default_values[name] = self.app.project_manager.current_project.videoheight
+ else:
+ self.default_values[name] = 0
+ spinbtn.set_value(value)
+ self.source.connect("deep-notify", self.__sourcePropertyChangedCb)
- def _getAndConnectToEffect(self, widget_name, property_name):
+ def __setupSpinButton(self, widget_name, property_name):
"""
Create a spinbutton widget and connect its signals to change property
values. While focused, disable the timeline actions' sensitivity.
@@ -640,88 +635,60 @@ class TransformationProperties(Gtk.Expander):
spinbtn = self.builder.get_object(widget_name)
spinbtn.connect("output", self._onValueChangedCb, property_name)
self.spin_buttons[property_name] = spinbtn
- self.default_values[property_name] = spinbtn.get_value()
def _onValueChangedCb(self, spinbtn, prop):
- value = spinbtn.get_value()
+ if not self.source:
+ return
- # FIXME Why are we looking at the gnl object directly?
- if value != self.default_values[prop] and not self.effect.get_gnlobject().props.active:
- self.effect.get_gnlobject().props.active = True
+ value = spinbtn.get_value()
- if value != self.effect.get_property(prop):
+ res, cvalue = self.source.get_child_property(prop)
+ if value != cvalue:
self.action_log.begin("Transformation property change")
- self.effect.set_property(prop, value)
+ self.source.set_child_property(prop, value)
self.action_log.commit()
- box = self.app.gui.viewer.internal.box
+ self.app.project_manager.current_project.pipeline.commit_timeline()
- # update box when values are changed in the spin boxes,
- # so no point is selected
- if box and box.clicked_point == 0:
- box.update_from_effect(self.effect)
-
- def _flushPipeLineCb(self, widget):
- self.app.project_manager.current_project.pipeline.flushSeek()
+ def __setSource(self):
+ if self.source:
+ try:
+ self.source.disconnect_by_func(self.__sourcePropertyChangedCb)
+ except TypeError:
+ pass
+ if self.get_expanded() and self._selected_clip:
+ self.source = self._selected_clip.find_track_element(None,
+ GES.VideoSource)
- def _findEffect(self, name):
- for effect in self._selected_clip.get_children(False):
- if isinstance(effect, GES.BaseEffect):
- if name in effect.get_property("bin-description"):
- self.effect = effect
- return effect.get_element()
-
- def _findOrCreateEffect(self, name):
- effect = self._findEffect(name)
- if not effect:
- effect = GES.Effect.new(bin_description=name)
- self._selected_clip.add(effect)
- tracks = self.app.project_manager.current_project.timeline.get_tracks(
- )
- effect = self._findEffect(name)
- # disable the effect on default
- a = self.effect.get_gnlobject()
- self.effect = list(list(a.elements())[0].elements())[1]
- self.effect.get_gnlobject().props.active = False
- self.app.gui.viewer.internal.set_transformation_properties(self)
- effect.freeze_notify()
- return self.effect
+ self._updateSpinButtons()
+ else:
+ self.source = None
def _selectionChangedCb(self, timeline):
if self.timeline and len(self.timeline.selection.selected) > 0:
# choose last selected clip
- # TODO: hide effects properties when multiple clips are selected
+ # TODO: hide source properties when multiple clips are selected
for clip in self.timeline.selection.selected:
pass
if clip != self._selected_clip:
self._selected_clip = clip
- self.effect = None
self.show()
- if self.get_expanded():
- self.effect = self._findOrCreateEffect(
- "frei0r-filter-scale0tilt")
- self._updateSpinButtons()
+ self.__setSource()
else:
# Deselect
if self._selected_clip:
self._selected_clip = None
- self.zoom_scale.set_value(1.0)
self.app.project_manager.current_project.pipeline.flushSeek()
- self.effect = None
+ self.__setSource()
self.hide()
- self._updateBoxVisibility()
-
- def _updateBoxVisibility(self):
- if self.get_expanded() and self._selected_clip:
- self.app.gui.viewer.internal.show_box()
- else:
- self.app.gui.viewer.internal.hide_box()
def _getTimeline(self):
return self._timeline
def _setTimeline(self, timeline):
+ if self.timeline:
+ self.timeline.selection.disconnect_by_func(self._selectionChangedCb)
self._timeline = timeline
if timeline:
self._timeline.selection.connect(
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index 0efca82..ed02a74 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -24,17 +24,15 @@ from gi.repository import Gdk
from gi.repository import Gst
from gi.repository import GObject
from gi.repository import GES
-import cairo
from gettext import gettext as _
from time import time
-from math import pi
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.ui import SPACING, hex_to_rgb
+from pitivi.utils.ui import SPACING
from pitivi.utils.widgets import TimeWidget
GlobalSettings.addConfigSection("viewer")
@@ -141,7 +139,7 @@ class ViewerContainer(Gtk.Box, Loggable):
self.sink.props.sink = Gst.ElementFactory.make("gtkglsink", None)
self.pipeline.setSink(self.sink)
- self.target = ViewerWidget(self.sink, self.app.settings)
+ self.target = ViewerWidget(self.sink, self.app)
if self.docked:
self.pack_start(self.target, True, True, 0)
@@ -480,6 +478,109 @@ class ViewerContainer(Gtk.Box, Loggable):
self.system.uninhibitScreensaver(self.INHIBIT_REASON)
+class TransformationBox(Gtk.EventBox, Loggable):
+ def __init__(self, app):
+ Gtk.EventBox.__init__(self)
+ Loggable.__init__(self)
+
+ self.app = app
+ self.__editSource = None
+ self.__startDraggingPosition = None
+ self.add_events(Gdk.EventMask.SCROLL_MASK)
+
+ def __setupEditSource(self):
+ if self.__editSource:
+ return
+ elif self.app.project_manager.current_project.pipeline.getState() != Gst.State.PAUSED:
+ return
+
+ try:
+ position = self.app.project_manager.current_project.pipeline.getPosition()
+ except:
+ return False
+
+ self.__editSource = None
+ for clip in self.app.project_manager.current_project.timeline.ui.selection.selected:
+ if clip.props.start <= position and position <= clip.props.start + clip.props.duration:
+ video_source = clip.find_track_elements(None, GES.TrackType.VIDEO, GES.VideoSource)
+ if video_source and self.__editSource:
+ video_source = None
+ break
+
+ try:
+ self.__editSource = video_source[0]
+ except IndexError:
+ continue
+
+ def do_event(self, event):
+ if event.type == Gdk.EventType.ENTER_NOTIFY and event.mode == Gdk.CrossingMode.NORMAL:
+ self.__setupEditSource()
+ if self.__editSource:
+ self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND1))
+ elif event.type == Gdk.EventType.BUTTON_RELEASE:
+ self.__startDraggingPosition = None
+ elif event.type == Gdk.EventType.LEAVE_NOTIFY and event.mode == Gdk.CrossingMode.NORMAL:
+ self.get_window().set_cursor(None)
+ self.__startDraggingPosition = None
+ self.__editSource = None
+ self.__startEditSourcePosition = None
+ elif event.type == Gdk.EventType.BUTTON_PRESS:
+ self.__setupEditSource()
+ if self.__editSource:
+ res_x, current_x = self.__editSource.get_child_property("posx")
+ res_y, current_y = self.__editSource.get_child_property("posy")
+
+ if res_x and res_y:
+ event_widget = Gtk.get_event_widget(event)
+ x, y = event_widget.translate_coordinates(self, event.x, event.y)
+ self.__startEditSourcePosition = (current_x, current_y)
+ self.__startDraggingPosition = (x, y)
+ elif event.type == Gdk.EventType.MOTION_NOTIFY:
+ if self.__startDraggingPosition and self.__editSource:
+ event_widget = Gtk.get_event_widget(event)
+ x, y = event_widget.translate_coordinates(self, event.x, event.y)
+ self.__editSource.set_child_property("posx",
+ self.__startEditSourcePosition[0] +
+ (x - self.__startDraggingPosition[0]))
+
+ self.__editSource.set_child_property("posy", self.__startEditSourcePosition[1] +
+ (y - self.__startDraggingPosition[1]))
+ self.app.project_manager.current_project.pipeline.commit_timeline()
+ elif event.type == Gdk.EventType.SCROLL:
+ if self.__editSource:
+ res, delta_x, delta_y = event.get_scroll_deltas()
+ if not res:
+ res, direction = event.get_scroll_direction()
+ if not res:
+ self.error("Could not get scroll delta")
+ return True
+
+ if direction == Gdk.ScrollDirection.UP:
+ delta_y = -1.0
+ elif direction == Gdk.ScrollDirection.DOWN:
+ delta_y = 1.0
+ else:
+ self.error("Could not handle %s scroll event" % direction)
+ return True
+
+ delta_y = delta_y * -1.0
+ width = self.__editSource.get_child_property("width")[1]
+ height = self.__editSource.get_child_property("height")[1]
+ if event.get_state()[1] & Gdk.ModifierType.SHIFT_MASK:
+ height += delta_y
+ elif event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK:
+ width += delta_y
+ else:
+ width += delta_y
+ height += delta_y
+
+ self.__editSource.set_child_property("width", width)
+ self.__editSource.set_child_property("height", height)
+ self.app.project_manager.current_project.pipeline.commit_timeline()
+
+ return True
+
+
class ViewerWidget(Gtk.AspectFrame, Loggable):
"""
@@ -491,24 +592,28 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
__gsignals__ = {}
- def __init__(self, sink, settings=None):
+ def __init__(self, sink, 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)
# We only work with a gtkglsink inside a glsinkbin
self.drawing_area = sink.props.sink.props.widget
# We keep the ViewerWidget hidden initially, or the desktop wallpaper
# would show through the non-double-buffered widget!
- self.add(self.drawing_area)
+ self.add(self.__transformationBox)
+ self.__transformationBox.add(self.drawing_area)
self.drawing_area.show()
self.seeker = Seeker()
- self.settings = settings
+ if app:
+ self.settings = app.settings
+ self.app = app
self.box = None
self.stored = False
self.area = None
@@ -518,6 +623,9 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
self.pipeline = None
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]