[pitivi/groups: 4/4] timeline/elements: Adds support for grouping / ungrouping.
- From: Mathieu Duponchelle <mathieudu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi/groups: 4/4] timeline/elements: Adds support for grouping / ungrouping.
- Date: Mon, 15 Jul 2013 21:55:09 +0000 (UTC)
commit 4a132621bf94669f109f91f2605c583bcff447b6
Author: Mathieu Duponchelle <mathieu duponchelle epitech eu>
Date: Wed Jul 10 22:22:44 2013 +0200
timeline/elements: Adds support for grouping / ungrouping.
pitivi/timeline/elements.py | 29 ++++++++++++---
pitivi/timeline/timeline.py | 81 +++++++++++++++++++++++++++++--------------
2 files changed, 78 insertions(+), 32 deletions(-)
---
diff --git a/pitivi/timeline/elements.py b/pitivi/timeline/elements.py
index 6eb075c..75fb7a5 100644
--- a/pitivi/timeline/elements.py
+++ b/pitivi/timeline/elements.py
@@ -33,7 +33,7 @@ import os
import cairo
from gi.repository import Clutter, Gtk, GtkClutter, Cogl, GES, Gdk, Gst, GstController, GLib
-from pitivi.utils.timeline import Zoomable, EditingContext, Selection, SELECT, UNSELECT, Selected
+from pitivi.utils.timeline import Zoomable, EditingContext, Selection, SELECT, UNSELECT, SELECT_ADD, Selected
from previewers import VideoPreviewer, BORDER_WIDTH
import pitivi.configure as configure
@@ -751,7 +751,6 @@ class Line(Clutter.Actor):
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:
@@ -767,7 +766,6 @@ class Line(Clutter.Actor):
def _enterEventCb(self, actor, event):
self.timelineElement.set_reactive(False)
self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND1))
- self.timelineElement.timeline._container.reactive = False
def _leaveEventCb(self, actor, event):
self._ungrab()
@@ -872,7 +870,6 @@ class Keyframe(Clutter.Actor):
self.timelineElement.set_reactive(True)
self.set_background_color(Clutter.Color.new(0, 255, 0, 255))
self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))
- self.timelineElement.timeline._container.reactive = True
def remove(self):
# Can't remove edge keyframes !
@@ -904,7 +901,6 @@ class Keyframe(Clutter.Actor):
self.timelineElement.set_reactive(False)
self.set_background_color(Clutter.Color.new(0, 0, 0, 255))
self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.HAND1))
- self.timelineElement.timeline._container.reactive = False
def _leaveEventCb(self, actor, event):
self._unselect()
@@ -1020,7 +1016,28 @@ class URISourceElement(TimelineElement):
# Callbacks
def _clickedCb(self, action, actor):
#TODO : Let's be more specific, masks etc ..
- self.timeline.selection.setToObj(self.bElement, SELECT)
+
+ children = self.bElement.get_toplevel_parent().get_children(True)
+ selection = filter(lambda elem: isinstance(elem, GES.Source), children)
+
+ mode = SELECT
+
+ if self.timeline._container.controlMask and not self.bElement.selected:
+ mode = SELECT_ADD
+ self.timeline.current_group.add(self.bElement.get_toplevel_parent())
+ elif self.timeline._container.controlMask:
+ self.timeline.current_group.remove(self.bElement.get_toplevel_parent())
+ mode = UNSELECT
+ elif not self.bElement.selected.selected:
+ GES.Container.ungroup(self.timeline.current_group, False)
+ self.timeline.current_group = GES.Group()
+ self.timeline.current_group.add(self.bElement.get_toplevel_parent())
+
+ children = self.bElement.get_toplevel_parent().get_children(True)
+ selection = filter(lambda elem: isinstance(elem, GES.Source), children)
+
+ self.timeline.selection.setSelection(selection, mode)
+
return False
def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 9b90b27..7a2f700 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -30,7 +30,7 @@ from gi.repository import Gst, GES, GObject, Clutter, Gtk, GLib, Gdk
from pitivi.autoaligner import AlignmentProgressDialog, AutoAligner
from pitivi.check import missing_soft_deps
-from pitivi.utils.timeline import Zoomable, Selection, UNSELECT
+from pitivi.utils.timeline import Zoomable, Selection, SELECT, UNSELECT
from pitivi.settings import GlobalSettings
from pitivi.dialogs.depsmanager import DepsManager
from pitivi.dialogs.prefs import PreferencesDialog
@@ -149,6 +149,8 @@ class TimelineStage(Clutter.ScrollActor, Zoomable):
Clutter.ScrollActor.__init__(self)
Zoomable.__init__(self)
self.bTimeline = None
+ self.current_group = GES.Group()
+
self._container = container
self.elements = []
self.ghostClips = []
@@ -195,10 +197,6 @@ class TimelineStage(Clutter.ScrollActor, Zoomable):
self.zoomChanged()
- # Stage was clicked with nothing under the pointer
- def emptySelection(self):
- self.selection.setSelection(self.selection.getSelectedTrackElements(), UNSELECT)
-
"""
@param element: the ui_element for which we want to find the sibling.
Will iterate over ui_elements to get the possible uri source with the same parent clip.
@@ -315,14 +313,14 @@ class TimelineStage(Clutter.ScrollActor, Zoomable):
yE1 = element.props.y
yE2 = element.props.y + element.props.height
- return self._overlap((x1, x2), (xE1, xE2)) and self._overlap((y1, y2), (yE1, yE2))
+ return self._segmentsOverlap((x1, x2), (xE1, xE2)) and self._segmentsOverlap((y1, y2), (yE1, yE2))
- def _overlap(self, a, b):
+ def _segmentsOverlap(self, a, b):
x = max(a[0], b[0])
y = min(a[1], b[1])
return x < y
- def _translate(self, event):
+ def _translateToTimelineContext(self, event):
event.x -= CONTROL_WIDTH
event.x += self._scroll_point.x
event.y += self._scroll_point.y
@@ -532,9 +530,14 @@ class TimelineStage(Clutter.ScrollActor, Zoomable):
def _dragBeginCb(self, actor, event):
self.drawMarquee = (self.getActorUnderPointer() == self)
+
if not self.drawMarquee:
return
+ if self.current_group:
+ GES.Container.ungroup(self.current_group, False)
+ self.current_group = GES.Group()
+
self.dragBeginStartX = event.x - CONTROL_WIDTH + self._scroll_point.x
self.dragBeginStartY = event.y + self._scroll_point.y
self.marquee.set_size(0, 0)
@@ -545,10 +548,9 @@ class TimelineStage(Clutter.ScrollActor, Zoomable):
if not self.drawMarquee:
return False
- x, y, width, height = self._translate(event)
+ x, y, width, height = self._translateToTimelineContext(event)
self.marquee.set_position(x, y)
-
self.marquee.set_size(width, height)
return False
@@ -557,14 +559,27 @@ class TimelineStage(Clutter.ScrollActor, Zoomable):
if not self.drawMarquee:
return
- x, y, width, height = self._translate(event)
+ self.drawMarquee = False
+ x, y, width, height = self._translateToTimelineContext(event)
elements = set({})
for element in self.elements:
if self._elementIsInLasso(element, x, y, x + width, y + height):
elements.add(element.bElement.get_toplevel_parent())
+ elements = list(elements)
+ selection = []
+
+ if elements:
+ self.current_group = GES.Group()
+ for element in elements:
+ self.current_group.add(element)
+ children = self.current_group.get_children(True)
+ #Let's only get the actual sources that we display
+ selection = filter(lambda elem: isinstance(elem, GES.Source), children)
+
+ self.selection.setSelection(selection, SELECT)
self.marquee.hide()
# snapping indicator
@@ -659,7 +674,6 @@ class Timeline(Gtk.VBox, Zoomable):
self._projectmanager = None
self._project = None
self.pipeline = None
- self.reactive = True
self._createUi()
self._createActions()
@@ -1060,20 +1074,44 @@ class Timeline(Gtk.VBox, Zoomable):
if self.bTimeline:
self.app.action_log.begin("ungroup")
- for clip in self.timeline.selection:
- clip.ungroup(False)
+ containers = set({})
+
+ for obj in self.timeline.selection:
+ toplevel = obj.get_toplevel_parent()
+ if toplevel == self.timeline.current_group:
+ for child in toplevel.get_children(False):
+ containers.add(child)
+ else:
+ containers.add(toplevel)
+
+ for container in containers:
+ GES.Container.ungroup(container, False)
- self.bTimeline.commit()
self.app.action_log.commit()
+ self.bTimeline.commit()
def _groupSelected(self, unused_action):
if self.bTimeline:
self.app.action_log.begin("group")
- GES.Container.group(self.timeline.selection)
+ containers = set({})
+
+ for obj in self.timeline.selection:
+ toplevel = obj.get_toplevel_parent()
+ if toplevel == self.timeline.current_group:
+ for child in toplevel.get_children(False):
+ containers.add(child)
+ toplevel.ungroup(False)
+ else:
+ containers.add(toplevel)
+
+ if containers:
+ group = GES.Container.group(list(containers))
+
+ self.timeline.current_group = GES.Group()
- self.app.action_log.commit()
self.bTimeline.commit()
+ self.app.action_log.commit()
def _alignSelected(self, unused_action):
if "NumPy" in missing_soft_deps:
@@ -1181,15 +1219,6 @@ class Timeline(Gtk.VBox, Zoomable):
if self.app:
self._seeker.seek(position)
- # As actors are set to not reactive when keyframes are edited, get_actor_at_pos
- # would return stage and we would wrongly empty our selection.
- if not self.reactive:
- return
-
- actor = self.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, event.x, event.y)
- if actor == stage:
- self.timeline.emptySelection()
-
def _releasedCb(self, stage, event):
self.timeline._snapEndedCb()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]