[gnome-builder] column-layout: be friendlier when dealing with long lists



commit 89317da598a8a1510db045c7663efe4ab5ea8708
Author: Christian Hergert <chergert redhat com>
Date:   Sat Sep 17 13:32:58 2016 -0700

    column-layout: be friendlier when dealing with long lists
    
    We don't want to clip long lists too short (by having to use
    max-content-height) nor do we want them to be super long. This uses some
    fairly naive heuristics to try to do the right thing.

 contrib/egg/egg-column-layout.c |   58 ++++++++++++++++++++++++++++++++-------
 1 files changed, 48 insertions(+), 10 deletions(-)
---
diff --git a/contrib/egg/egg-column-layout.c b/contrib/egg/egg-column-layout.c
index dc2d01c..81e9cfb 100644
--- a/contrib/egg/egg-column-layout.c
+++ b/contrib/egg/egg-column-layout.c
@@ -23,6 +23,7 @@ typedef struct
   GtkWidget      *widget;
   GtkAllocation   alloc;
   GtkRequisition  req;
+  GtkRequisition  min_req;
   gint            priority;
 } EggColumnLayoutChild;
 
@@ -69,12 +70,17 @@ egg_column_layout_layout (EggColumnLayout *self,
   gint n_columns = 0;
   gint border_width;
   gint column;
+  gint orig_height;
   guint i;
 
   g_assert (EGG_IS_COLUMN_LAYOUT (self));
   g_assert (width > 0);
   g_assert (tallest_column != NULL);
 
+#if 0
+  g_print ("width: %d  height: %d", width, height);
+#endif
+
   /*
    * We want to layout the children in a series of columns, but try to
    * fill up each column before spilling into the next column.
@@ -101,27 +107,42 @@ egg_column_layout_layout (EggColumnLayout *self,
 
       child = &g_array_index (priv->children, EggColumnLayoutChild, i);
 
-      gtk_widget_get_preferred_height_for_width (child->widget, priv->column_width, NULL, 
&child->req.height);
+      gtk_widget_get_preferred_height_for_width (child->widget,
+                                                 priv->column_width,
+                                                 &child->min_req.height,
+                                                 &child->req.height);
 
-      if (i != 0)
-        total_height += priv->row_spacing;
-      total_height += child->req.height;
+      /*
+       * If this is a huge scrolling list, then we will clamp the
+       * size we care about to 2/3 the screen size.
+       */
+
+      if (child->req.height > 1000)
+        total_height += 1000;
+      else
+        total_height += child->req.height;
     }
 
+  if (priv->children->len > 0)
+    total_height += priv->row_spacing * (priv->children->len - 1);
+
   if (total_height <= height)
     n_columns = 1;
   else
     n_columns = MAX (1, (width - (border_width * 2)) / (priv->column_width + priv->column_spacing));
 
+  orig_height = (height != 0) ? (height - (border_width * 2)) : total_height / n_columns;
+
   for (column = 0, i = 0; column < n_columns; column++)
     {
       GtkAllocation alloc;
+      gint child_height;
       gint j = 0;
 
       alloc.x = border_width + (priv->column_width * column) + (column * priv->column_spacing);
       alloc.y = border_width;
       alloc.width = priv->column_width;
-      alloc.height = (height != 0) ? (height - (border_width * 2)) : total_height / n_columns;
+      alloc.height = orig_height;
 
       for (; i < priv->children->len; i++, j++)
         {
@@ -140,13 +161,30 @@ egg_column_layout_layout (EggColumnLayout *self,
            * If the child requisition is taller than the space we have left in
            * this column, we need to spill over to the next column.
            */
-          if ((j != 0) && (child->req.height > alloc.height) && (column < (n_columns - 1)))
-            break;
+          if (child->req.height > alloc.height)
+            {
+              /*
+               * But if there is enough to satisfy the min height for the group, and
+               * we have at least half the available height left, go ahead and keep
+               * making progress.
+               */
+              if (child->min_req.height < alloc.height && (alloc.height * 2 > orig_height))
+                {
+                  child_height = alloc.height;
+                  goto do_allocate;
+                }
+
+              break;
+            }
+
+          child_height = child->req.height;
+
+        do_allocate:
 
           child->alloc.x = alloc.x;
           child->alloc.y = alloc.y;
           child->alloc.width = priv->column_width;
-          child->alloc.height = child->req.height;
+          child->alloc.height = child_height;
 
 #if 0
           g_print ("Allocating child to: [%d] %d,%d %dx%d\n",
@@ -157,8 +195,8 @@ egg_column_layout_layout (EggColumnLayout *self,
                    child->alloc.height);
 #endif
 
-          alloc.y += child->req.height + priv->row_spacing;
-          alloc.height -= child->req.height + priv->row_spacing;
+          alloc.y += child->alloc.height + priv->row_spacing;
+          alloc.height -= child->alloc.height + priv->row_spacing;
 
           if (alloc.y > real_tallest_column)
             real_tallest_column = alloc.y;


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