[libhandy/leaflet-natural-unfolded: 3/4] leaflet: Properly handle natural size



commit 3bed9bbf9e0dbd321891637968c8cb86670349f8
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Tue Jan 21 12:07:18 2020 +0100

    leaflet: Properly handle natural size
    
    When unfolded, children were automatically allocated their natural size,
    whether it would fit or not. This properly handles natural size
    repartition.
    
    Fixes https://source.puri.sm/Librem5/libhandy/issues/189.

 src/hdy-leaflet.c | 53 +++++++++++++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 20 deletions(-)
---
diff --git a/src/hdy-leaflet.c b/src/hdy-leaflet.c
index dce8e0fe..e144e86e 100644
--- a/src/hdy-leaflet.c
+++ b/src/hdy-leaflet.c
@@ -1863,19 +1863,23 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
   HdyLeafletPrivate *priv = hdy_leaflet_get_instance_private (self);
   GtkOrientation orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
   gboolean is_horizontal = orientation == GTK_ORIENTATION_HORIZONTAL;
+  GtkRequestedSize *sizes;
   GtkAllocation remaining_alloc;
   GList *directed_children, *children;
   HdyLeafletChildInfo *child_info;
-  gint homogeneous_size = 0, min_size, extra_size;
+  gint homogeneous_size = 0, min_size = 0, extra_size = 0;
   gint per_child_extra, n_extra_widgets;
   gint n_visible_children, n_expand_children;
   gboolean box_homogeneous;
+  gint i;
 
   directed_children = get_directed_children (self);
 
   box_homogeneous = (priv->homogeneous[HDY_FOLD_UNFOLDED][GTK_ORIENTATION_HORIZONTAL] && is_horizontal) ||
                     (priv->homogeneous[HDY_FOLD_UNFOLDED][GTK_ORIENTATION_VERTICAL] && !is_horizontal);
 
+  /* Compute the number of visible and expanded children. */
+
   n_visible_children = n_expand_children = 0;
   for (children = directed_children; children; children = children->next) {
     child_info = children->data;
@@ -1899,30 +1903,39 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
     if (is_horizontal) {
       homogeneous_size = allocation->width / n_visible_children;
       n_expand_children = allocation->width % n_visible_children;
-      min_size = allocation->width - n_expand_children;
+      extra_size = allocation->width - n_expand_children;
     }
     else {
       homogeneous_size = allocation->height / n_visible_children;
       n_expand_children = allocation->height % n_visible_children;
-      min_size = allocation->height - n_expand_children;
+      extra_size = allocation->height - n_expand_children;
     }
   }
   else {
-    min_size = 0;
-    if (is_horizontal) {
-      for (children = directed_children; children; children = children->next) {
-        child_info = children->data;
+    sizes = g_newa (GtkRequestedSize, n_visible_children);
 
-        min_size += child_info->nat.width;
-      }
-    }
-    else {
-      for (children = directed_children; children; children = children->next) {
-        child_info = children->data;
+    i = 0;
+    for (children = directed_children; children; children = children->next) {
+      child_info = children->data;
+
+      if (!child_info->visible)
+        continue;
 
-        min_size += child_info->nat.height;
+      if (is_horizontal) {
+        sizes[i].minimum_size = child_info->min.width;
+        sizes[i].natural_size = child_info->nat.width;
+      } else {
+        sizes[i].minimum_size = child_info->min.height;
+        sizes[i].natural_size = child_info->nat.height;
       }
+      min_size += sizes[i].minimum_size;
+      i++;
     }
+
+    if (is_horizontal)
+      extra_size = gtk_distribute_natural_allocation (MAX (0, allocation->width - min_size), 
n_visible_children, sizes);
+    else
+      extra_size = gtk_distribute_natural_allocation (MAX (0, allocation->height - min_size), 
n_visible_children, sizes);
   }
 
   remaining_alloc.x = 0;
@@ -1930,10 +1943,6 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
   remaining_alloc.width = allocation->width;
   remaining_alloc.height = allocation->height;
 
-  extra_size = is_horizontal ?
-    remaining_alloc.width - min_size :
-    remaining_alloc.height - min_size;
-
   per_child_extra = 0, n_extra_widgets = 0;
   if (n_expand_children > 0) {
     per_child_extra = extra_size / n_expand_children;
@@ -1941,6 +1950,8 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
   }
 
   /* Compute children allocation */
+
+  i = 0;
   for (children = directed_children; children; children = children->next) {
     child_info = children->data;
 
@@ -1959,7 +1970,7 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
         }
       }
       else {
-        child_info->alloc.width = child_info->nat.width;
+        child_info->alloc.width = sizes[i].minimum_size;
         if (gtk_widget_compute_expand (child_info->widget, orientation)) {
           child_info->alloc.width += per_child_extra;
           if (n_extra_widgets > 0) {
@@ -1982,7 +1993,7 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
         }
       }
       else {
-        child_info->alloc.height = child_info->nat.height;
+        child_info->alloc.height = sizes[i].minimum_size;
         if (gtk_widget_compute_expand (child_info->widget, orientation)) {
           child_info->alloc.height += per_child_extra;
           if (n_extra_widgets > 0) {
@@ -1996,6 +2007,8 @@ hdy_leaflet_size_allocate_unfolded (GtkWidget     *widget,
       remaining_alloc.y += child_info->alloc.height;
       remaining_alloc.height -= child_info->alloc.height;
     }
+
+    i++;
   }
 
   hdy_leaflet_size_allocate_unfolded_animate (self, allocation);


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