[pitivi] timeline: Set the layout's size only when needed



commit 75b3597dc6eb34156e22b00e8e05ae3bf01f4900
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Tue Nov 1 16:33:56 2016 +0100

    timeline: Set the layout's size only when needed
    
    The LayersLayout's size, along with the layers_vbox.props.width_request,
    were being set when the Timeline got its allocation. This was not
    optimal and caused strange vertical scroll because the vertical
    adjustment is being controlled by both the LayersLayout and the layers
    controls's viewport.
    
    Now the size of the scrollable area of the LayersLayout is set in a
    single place, when the layers_vbox gets its size allocation. The
    layers_vbox is flagged automatically for size renegotiation in two
    cases: when the heights of its Layer children change, and when the
    timeline duration changes and we manually set the height_request of the
    layers_vbox.
    
    Fixes https://phabricator.freedesktop.org/T7435
    
    Reviewed-by: Thibault Saunier <tsaunier gnome org>
    Differential Revision: https://phabricator.freedesktop.org/D1436

 pitivi/timeline/timeline.py |   70 ++++++++++++++++++++++---------------------
 tests/test_mainwindow.py    |    2 +-
 2 files changed, 37 insertions(+), 35 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index accf448..032713c 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -227,6 +227,8 @@ class LayersLayout(Gtk.Layout, Zoomable, Loggable):
         Zoomable.__init__(self)
         Loggable.__init__(self)
 
+        self._timeline = timeline
+
         self.snap_position = 0
         self.playhead_position = 0
 
@@ -237,7 +239,16 @@ class LayersLayout(Gtk.Layout, Zoomable, Loggable):
         self.marquee = Marquee(timeline)
         self.put(self.marquee, 0, 0)
 
+        self.layers_vbox.connect("size-allocate", self.__size_allocate_cb)
+
+    def zoomChanged(self):
+        # The width of the area/workspace changes when the zoom level changes.
+        self.update_width()
+        # Required so the playhead is redrawn.
+        self.queue_draw()
+
     def do_draw(self, cr):
+        """Draws the children and indicators."""
         Gtk.Layout.do_draw(self, cr)
 
         self.__draw_playhead(cr)
@@ -272,6 +283,26 @@ class LayersLayout(Gtk.Layout, Zoomable, Loggable):
         cr.line_to(xpos, height)
         cr.stroke()
 
+    def update_width(self):
+        """Updates the width of the area and the width of the layers_vbox."""
+        ges_timeline = self._timeline.ges_timeline
+        view_width = self.get_allocated_width()
+        space_at_the_end = view_width * 2 / 3
+        duration = 0 if not ges_timeline else ges_timeline.props.duration
+        width = self.nsToPixel(duration) + space_at_the_end
+        width = max(view_width, width)
+
+        self.log("Updating the width_request of the layers_vbox: %s", width)
+        # This triggers a renegotiation of the size, meaning
+        # layers_vbox's "size-allocate" will be emitted, see __size_allocate_cb.
+        self.layers_vbox.props.width_request = width
+
+    def __size_allocate_cb(self, unused_widget, allocation):
+        """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
+
 
 class Timeline(Gtk.EventBox, Zoomable, Loggable):
     """Container for the the layers controls and representation.
@@ -439,10 +470,10 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self.connect("button-release-event", self._button_release_event_cb)
         self.connect("motion-notify-event", self._motion_notify_event_cb)
 
-        self.queue_draw()
+        self.layout.update_width()
 
     def _durationChangedCb(self, ges_timeline, pspec):
-        self.queue_draw()
+        self.layout.update_width()
 
     def scrollToPlayhead(self, align=None, when_not_in_view=False):
         """Scrolls so that the playhead is in view.
@@ -454,7 +485,6 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
                 the playhead is not in view.
         """
         self.debug("Scrolling to playhead")
-        self.__setLayoutSize()
         layout_width = self.layout.get_allocation().width
         if when_not_in_view:
             x = self.nsToPixel(self.__last_position) - self.hadj.get_value()
@@ -516,28 +546,9 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         natural = SEPARATOR_HEIGHT + count * (LAYER_HEIGHT + SEPARATOR_HEIGHT)
         return minimum, natural
 
-    def __setLayoutSize(self):
-        if self.ges_timeline:
-            width = self._timelineLengthInPixels()
-            if self.draggingElement:
-                width = max(width, self.layout.props.width)
-
-            self.layout.layers_vbox.props.width_request = width
-            self.layout.set_size(width, len(self.ges_timeline.get_layers()) * 200)
-
-    def do_size_allocate(self, request):
-        self.__setLayoutSize()
-        Gtk.EventBox.do_size_allocate(self, request)
-
     # ------------- #
     # util methods  #
     # ------------- #
-    def _timelineLengthInPixels(self):
-        if self.ges_timeline is None:
-            return 100
-
-        space_at_the_end = self.layout.get_allocation().width * 2 / 3
-        return self.nsToPixel(self.ges_timeline.props.duration) + space_at_the_end
 
     def _getParentOfType(self, widget, _type):
         """Gets a clip from a child widget.
@@ -598,13 +609,9 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
                 Zoomable.zoomOut()
             else:
                 Zoomable.zoomIn()
-            self.__setLayoutSize()
-            if delta_y:
-                # The zoom level changed.
-                self.queue_draw()
-                # Scroll so position remains in place.
-                x, unused_y = event_widget.translate_coordinates(self.layout, event.x, event.y)
-                self.hadj.set_value(self.nsToPixel(position) - x)
+            # Scroll so position remains in place.
+            x, unused_y = event_widget.translate_coordinates(self.layout, event.x, event.y)
+            self.hadj.set_value(self.nsToPixel(position) - x)
         else:
             if delta_y > 0:
                 # Scroll right.
@@ -1019,7 +1026,6 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self.zoomed_fitted = False
 
         self.updatePosition()
-        self.queue_draw()
 
     def set_best_zoom_ratio(self, allow_zoom_in=False):
         """Sets the zoom level so that the entire timeline is in view."""
@@ -1221,7 +1227,6 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
                 ges_layer = self.createLayer(priority)
                 position = self.editing_context.new_position
                 self.editing_context.edit_to(position, ges_layer)
-            self.layout.props.width = self._timelineLengthInPixels()
 
             self.editing_context.finish()
 
@@ -1236,8 +1241,6 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         self._setSeparatorsPrelight(False)
         self.__on_separators = []
 
-        self.queue_draw()
-
     def __endMovingLayer(self):
         self.app.action_log.commit("move layer")
         self.__moving_layer = None
@@ -1583,7 +1586,6 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         hadj.set_value(x)
 
         self.timeline.updatePosition()
-        self.timeline.queue_draw()
         return False
 
     def _deleteSelected(self, unused_action, unused_parameter):
diff --git a/tests/test_mainwindow.py b/tests/test_mainwindow.py
index 413f8a0..512acb6 100644
--- a/tests/test_mainwindow.py
+++ b/tests/test_mainwindow.py
@@ -123,7 +123,7 @@ class TestMainWindow(common.TestCase):
         """
         self.__loading_failure(has_proxy=False)
 
-    def test_loading_project_wth_proxy(self):
+    def test_loading_project_with_proxy(self):
         """
         Test loading failure with proxies
         """


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