[pitivi] timeline: Add a button for adding a layer



commit 0eaade41261f98bf10dbfc11029886e55d6f1dba
Author: Yash Agrawal <yagrawal900 gmail com>
Date:   Fri Feb 15 13:15:00 2019 +0530

    timeline: Add a button for adding a layer
    
    Fixes #2063

 pitivi/timeline/timeline.py | 47 ++++++++++++++++++++++++++++++++++-----------
 tests/test_undo_timeline.py | 35 ++++++++++++++++++++++++++++++---
 2 files changed, 68 insertions(+), 14 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 5271d21f..5ea93410 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -278,7 +278,8 @@ class LayersLayout(Gtk.Layout, Zoomable, Loggable):
         """Sets the size of the scrollable area to fit the layers_vbox."""
         self.log("The size of the layers_vbox changed: %sx%s", allocation.width, allocation.height)
         self.props.width = allocation.width
-        self.props.height = allocation.height
+        # The additional space is for the 'Add layer' button.
+        self.props.height = allocation.height + LAYER_HEIGHT / 2
 
 
 class Timeline(Gtk.EventBox, Zoomable, Loggable):
@@ -324,6 +325,12 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         scrolled_window.add(self._layers_controls_vbox)
         hbox.pack_start(scrolled_window, False, False, 0)
 
+        self.add_layer_button = Gtk.Button.new_with_label("Add layer")
+        self.add_layer_button.props.margin = SPACING
+        self.add_layer_button.set_halign(Gtk.Align.CENTER)
+        self.add_layer_button.show()
+        self._layers_controls_vbox.pack_end(self.add_layer_button, False, False, 0)
+
         self.get_style_context().add_class("Timeline")
         self.props.expand = True
         self.get_accessible().set_name("timeline canvas")
@@ -1085,23 +1092,27 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
             self.debug("Layers still being shuffled, not updating widgets: %s", priorities)
             return
         self.debug("Updating layers widgets positions")
-        for ges_layer in self.ges_timeline.get_layers():
+        self.__update_separator(0)
+        for ges_layer in ges_layers:
             self.__update_layer(ges_layer)
+            self.__update_separator(ges_layer.props.priority + 1)
+
+    def __update_separator(self, priority):
+        """Sets the position of the separators in their parent."""
+        position = priority * 2
+        controls_separator, layers_separator = self._separators[priority]
+        vbox = self._layers_controls_vbox
+        vbox.child_set_property(controls_separator, "position", position)
+        vbox = self.layout.layers_vbox
+        vbox.child_set_property(layers_separator, "position", position)
 
     def __update_layer(self, ges_layer):
         """Sets the position of the layer and its controls in their parent."""
         position = ges_layer.props.priority * 2 + 1
-
-        # Update the position of the LayerControls and Layer widgets and
-        # also the position of the separators below them.
-        controls_separator, layers_separator = self._separators[ges_layer.props.priority + 1]
-        vbox = self.layout.layers_vbox
-        vbox.child_set_property(ges_layer.ui, "position", position)
-        vbox.child_set_property(layers_separator, "position", position + 1)
-
         vbox = self._layers_controls_vbox
         vbox.child_set_property(ges_layer.control_ui, "position", position)
-        vbox.child_set_property(controls_separator, "position", position + 1)
+        vbox = self.layout.layers_vbox
+        vbox.child_set_property(ges_layer.ui, "position", position)
 
     def _remove_layer(self, ges_layer):
         self.info("Removing layer: %s", ges_layer.props.priority)
@@ -1620,6 +1631,13 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         self.app.shortcuts.add("timeline.paste-clips", ["<Primary>v"],
                                _("Paste selected clips"))
 
+        self.add_layer_action = Gio.SimpleAction.new("add-layer", None)
+        self.timeline.add_layer_button.connect("clicked", self.__add_layer_cb)
+        self.add_layer_action.connect("activate", self.__add_layer_cb)
+        group.add_action(self.add_layer_action)
+        self.app.shortcuts.add("timeline.add-layer", ["<Primary>n"],
+                               _("Add layer"))
+
         if in_devel():
             self.gapless_action = Gio.SimpleAction.new("toggle-gapless-mode", None)
             self.gapless_action.connect("activate", self._gaplessmode_toggled_cb)
@@ -1837,6 +1855,13 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
             self.__copied_group = copied_group_shallow_copy.copy(True)
             copied_group_shallow_copy.ungroup(recursive=False)
 
+    def __add_layer_cb(self, unused_action, unused_parameter):
+        with self.app.action_log.started("add layer",
+                    finalizing_action=CommitTimelineFinalizingAction(self._project.pipeline),
+                    toplevel=True):
+            priority = len(self.ges_timeline.get_layers())
+            self.timeline.create_layer(priority)
+
     def _alignSelectedCb(self, unused_action, unused_parameter):
         if not self.ges_timeline:
             return
diff --git a/tests/test_undo_timeline.py b/tests/test_undo_timeline.py
index 99cdff38..28e88dcf 100644
--- a/tests/test_undo_timeline.py
+++ b/tests/test_undo_timeline.py
@@ -21,7 +21,6 @@ from unittest import mock
 
 from gi.repository import Gdk
 from gi.repository import GES
-from gi.repository import GLib
 from gi.repository import Gst
 from gi.repository import GstController
 from gi.repository import Gtk
@@ -361,6 +360,38 @@ class TestLayerObserver(BaseTestUndoTimeline):
         self.action_log.redo()
         self.assertFalse(clip1 in self.getTimelineClips())
 
+    def test_layer_added(self):
+        self.setup_timeline_container()
+        layers = self.timeline.get_layers()
+        self.assertEqual(len(layers), 1)
+
+        clip = GES.TitleClip()
+        self.layer.add_clip(clip)
+
+        self.timeline_container.add_layer_action.emit("activate", None)
+
+        layers = self.timeline.get_layers()
+        self.assertEqual(len(layers), 2)
+        self.assertEqual(layers[0], self.layer)
+        self.check_layers(layers)
+        self.assertEqual(layers[0].get_clips(), [clip])
+        self.assertEqual(layers[1].get_clips(), [])
+
+        self.action_log.undo()
+        layers = self.timeline.get_layers()
+        self.assertEqual(len(layers), 1)
+        self.assertEqual(layers[0], self.layer)
+        self.check_layers(layers)
+        self.assertEqual(layers[0].get_clips(), [clip])
+
+        self.action_log.redo()
+        layers = self.timeline.get_layers()
+        self.assertEqual(len(layers), 2)
+        self.assertEqual(layers[0], self.layer)
+        self.check_layers(layers)
+        self.assertEqual(layers[0].get_clips(), [clip])
+        self.assertEqual(layers[1].get_clips(), [])
+
     def test_ungroup_group_clip(self):
         # This test is in TestLayerObserver because the relevant operations
         # recorded are clip-added and clip-removed.
@@ -1065,8 +1096,6 @@ class TestDragDropUndo(BaseTestUndoTimeline):
         self.assertEqual(layers[0].get_clips(), [])
         self.assertEqual(layers[1].get_clips(), [clip])
 
-        return clip, event, timeline_ui
-
     def test_clip_dragged_to_create_layer_above_denied(self):
         """Checks clip dropped onto the separator above without hovering."""
         clip, event, timeline_ui = self.clip_dragged_to_create_layer(False)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]