[pitivi] timeline/elements: Moving a line now moves the adjacent keyframes.
- From: Jean-François Fortin Tam <jfft src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] timeline/elements: Moving a line now moves the adjacent keyframes.
- Date: Mon, 8 Jul 2013 00:52:07 +0000 (UTC)
commit 0836b54a2dc3f572b1a0ed094c9e6f387ab782b1
Author: Mathieu Duponchelle <mathieu duponchelle epitech eu>
Date: Tue Jun 25 23:28:19 2013 +0200
timeline/elements: Moving a line now moves the adjacent keyframes.
pitivi/timeline/elements.py | 115 +++++++++++++++++++++++++++++++++----------
1 files changed, 89 insertions(+), 26 deletions(-)
---
diff --git a/pitivi/timeline/elements.py b/pitivi/timeline/elements.py
index 2df4785..c333a59 100644
--- a/pitivi/timeline/elements.py
+++ b/pitivi/timeline/elements.py
@@ -448,16 +448,22 @@ class TimelineElement(Clutter.Actor, Zoomable):
keyframe.set_z_position(2)
keyframe.set_position(x, y)
- def drawLines(self):
- for line in self.lines:
- self.remove_child(line)
+ def drawLines(self, line=None):
+ for line_ in self.lines:
+ if line_ != line:
+ self.remove_child(line_)
- self.lines = []
+ if line:
+ self.lines = [line]
+ else:
+ self.lines = []
lastKeyframe = None
for keyframe in self.keyframes:
- if lastKeyframe:
- self._createLine(keyframe.value, lastKeyframe.value)
+ if lastKeyframe and (not line or lastKeyframe != line.previousKeyframe):
+ self._createLine(keyframe, lastKeyframe, None)
+ elif lastKeyframe:
+ self._createLine(keyframe, lastKeyframe, line)
lastKeyframe = keyframe
def updateKeyframes(self):
@@ -509,19 +515,21 @@ class TimelineElement(Clutter.Actor, Zoomable):
self.keyframes.append(keyframe)
self.setKeyframePosition(keyframe, value)
- def _createLine(self, value, lastPoint):
- line = Line(self)
- adj = self.nsToPixel(value.timestamp - lastPoint.timestamp)
- opp = (lastPoint.value - value.value) * EXPANDED_SIZE
+ def _createLine(self, keyframe, lastKeyframe, line):
+ if not line:
+ line = Line(self, keyframe, lastKeyframe)
+ self.lines.append(line)
+ self.add_child(line)
+
+ adj = self.nsToPixel(keyframe.value.timestamp - lastKeyframe.value.timestamp)
+ opp = (lastKeyframe.value.value - keyframe.value.value) * EXPANDED_SIZE
hyp = math.sqrt(adj ** 2 + opp ** 2)
sinX = opp / hyp
line.props.width = hyp
line.props.height = 6
line.props.rotation_angle_z = math.degrees(math.asin(sinX))
- line.props.x = self.nsToPixel(lastPoint.timestamp)
- line.props.y = EXPANDED_SIZE - (EXPANDED_SIZE * lastPoint.value)
- self.lines.append(line)
- self.add_child(line)
+ line.props.x = self.nsToPixel(lastKeyframe.value.timestamp)
+ line.props.y = EXPANDED_SIZE - (EXPANDED_SIZE * lastKeyframe.value.value)
line.canvas.invalidate()
def _createGhostclip(self):
@@ -631,7 +639,7 @@ class Gradient(Clutter.Actor):
class Line(Clutter.Actor):
- def __init__(self, timelineElement):
+ def __init__(self, timelineElement, keyframe, lastKeyframe):
Clutter.Actor.__init__(self)
self.timelineElement = timelineElement
@@ -642,11 +650,23 @@ class Line(Clutter.Actor):
self.set_content(self.canvas)
self.set_reactive(True)
- self.connect("button-press-event", self._clickedCb)
+ self.gotDragged = False
+
+ self.dragAction = Clutter.DragAction()
+ self.add_action(self.dragAction)
+
+ self.dragAction.connect("drag-begin", self._dragBeginCb)
+ self.dragAction.connect("drag-end", self._dragEndCb)
+ self.dragAction.connect("drag-progress", self._dragProgressCb)
+
+ self.connect("button-release-event", self._clickedCb)
self.connect("motion-event", self._motionEventCb)
self.connect("enter-event", self._enterEventCb)
self.connect("leave-event", self._leaveEventCb)
+ self.previousKeyframe = lastKeyframe
+ self.nextKeyframe = keyframe
+
def _drawCb(self, canvas, cr, width, height):
cr.set_operator(cairo.OPERATOR_CLEAR)
cr.paint()
@@ -662,7 +682,15 @@ class Line(Clutter.Actor):
y -= self.timelineElement.props.y
return x, y
+ def _ungrab(self):
+ self.timelineElement.set_reactive(True)
+
self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))
+ self.timelineElement.timeline._container.reactive = True
+
def _clickedCb(self, actor, event):
+ if self.gotDragged:
+ self.gotDragged = False
+ return
x, y = self.transposeXY(event.x, event.y)
value = 1.0 - (y / EXPANDED_SIZE)
value = max(0.0, value)
@@ -676,13 +704,35 @@ class Line(Clutter.Actor):
self.timelineElement.timeline._container.reactive = False
def _leaveEventCb(self, actor, event):
- self.timelineElement.set_reactive(True)
-
self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))
- self.timelineElement.timeline._container.reactive = True
+ self._ungrab()
def _motionEventCb(self, actor, event):
pass
+ def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
+ self.dragBeginStartX = event_x
+ self.dragBeginStartY = event_y
+ self.origY = self.props.y
+ self.previousKeyframe.startDrag(event_x, event_y, self)
+ self.nextKeyframe.startDrag(event_x, event_y, self)
+
+ def _dragProgressCb(self, action, actor, delta_x, delta_y):
+ self.gotDragged = True
+ coords = self.dragAction.get_motion_coords()
+ delta_x = coords[0] - self.dragBeginStartX
+ delta_y = coords[1] - self.dragBeginStartY
+
+ self.previousKeyframe.updateValue(0, delta_y)
+ self.nextKeyframe.updateValue(0, delta_y)
+
+ return False
+
+ def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
+ self.previousKeyframe.endDrag()
+ self.nextKeyframe.endDrag()
+ if self.timelineElement.timeline.getActorUnderPointer() != self:
+ self._ungrab()
+
class Keyframe(Clutter.Actor):
"""
@@ -740,7 +790,7 @@ class Keyframe(Clutter.Actor):
def _leaveEventCb(self, actor, event):
self._unselect()
- def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
+ def startDrag(self, event_x, event_y, line=None):
self.dragBeginStartX = event_x
self.dragBeginStartY = event_y
self.lastTs = self.value.timestamp
@@ -749,11 +799,12 @@ class Keyframe(Clutter.Actor):
self.duration = self.timelineElement.bElement.props.duration
self.inpoint = self.timelineElement.bElement.props.in_point
self.start = self.timelineElement.bElement.props.start
+ self.line = line
- def _dragProgressCb(self, action, actor, delta_x, delta_y):
- coords = self.dragAction.get_motion_coords()
- delta_x = coords[0] - self.dragBeginStartX
- delta_y = coords[1] - self.dragBeginStartY
+ def endDrag(self):
+ self.line = None
+
+ def updateValue(self, delta_x, delta_y):
newTs = self.tsStart + Zoomable.pixelToNs(delta_x)
newValue = self.valueStart - (delta_y / EXPANDED_SIZE)
@@ -776,13 +827,25 @@ class Keyframe(Clutter.Actor):
# Resort the keyframes list each time. Should be cheap as there should never be too much
keyframes,
# if optimization is needed, check if resorting is needed, should not be in 99 % of the cases.
self.timelineElement.keyframes = sorted(self.timelineElement.keyframes, key=lambda keyframe:
keyframe.value.timestamp)
- self.timelineElement.drawLines()
+ self.timelineElement.drawLines(self.line)
# This will update the viewer. nifty.
- self.timelineElement.timeline._container.seekInPosition(newTs + self.start)
+ if not self.line:
+ self.timelineElement.timeline._container.seekInPosition(newTs + self.start)
+
+ def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
+ self.startDrag(event_x, event_y)
+
+ def _dragProgressCb(self, action, actor, delta_x, delta_y):
+ coords = self.dragAction.get_motion_coords()
+ delta_x = coords[0] - self.dragBeginStartX
+ delta_y = coords[1] - self.dragBeginStartY
+
+ self.updateValue(delta_x, delta_y)
return False
def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
+ self.endDrag()
if self.timelineElement.timeline.getActorUnderPointer() != self:
self._unselect()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]