[gtk+] headerbar: support expand property for children



commit 0015ebc4a8f269f6888fcacef3e83e3167241d67
Author: Ray Strode <rstrode redhat com>
Date:   Fri Jun 24 07:53:49 2016 -0400

    headerbar: support expand property for children
    
    The header bar currently ignores the expand property on its
    children. This commit changes the code to honor that property.
    
    It divvies up any free space and distributes it equally to packed
    children (with any left over space given out a pixel at a time
    on a first come, first serve basis).
    
    This commit also adds support for the title widget to be made
    expandable.
    
    It accomplishes this by using up the padding the title widget
    is centered with.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=724332

 docs/reference/gtk/migrating-3xtoy.xml |    7 ++++
 gtk/gtkheaderbar.c                     |   59 ++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gtk/migrating-3xtoy.xml b/docs/reference/gtk/migrating-3xtoy.xml
index b546cba..f140a4a 100644
--- a/docs/reference/gtk/migrating-3xtoy.xml
+++ b/docs/reference/gtk/migrating-3xtoy.xml
@@ -426,5 +426,12 @@
       and #GtkScrolledWindow:max-content-height will allow control over the
       size of the scrolled window.
     </para>
+
+    <para>
+      GtkHeaderBar now respects the hexpand property for its custom title
+      widget and its packed children. This change may inadvertently cause the
+      layout of those children to change, if they unintentionally had hexpand
+      set before.
+    </para>
   </section>
 </chapter>
diff --git a/gtk/gtkheaderbar.c b/gtk/gtkheaderbar.c
index 031199b..47fb70c 100644
--- a/gtk/gtkheaderbar.c
+++ b/gtk/gtkheaderbar.c
@@ -997,7 +997,11 @@ gtk_header_bar_allocate_contents (GtkCssGadget        *gadget,
   gint nvis_children;
   gint title_minimum_size;
   gint title_natural_size;
+  gboolean title_expands;
   gint start_width, end_width;
+  gint uniform_expand_bonus[2] = { 0 };
+  gint leftover_expand_bonus[2] = { 0 };
+  gint nexpand_children[2] = { 0 };
   gint side[2];
   GList *l;
   gint i;
@@ -1024,6 +1028,9 @@ gtk_header_bar_allocate_contents (GtkCssGadget        *gadget,
       if (!gtk_widget_get_visible (child->widget))
         continue;
 
+      if (gtk_widget_compute_expand (child->widget, GTK_ORIENTATION_HORIZONTAL))
+        nexpand_children[child->pack_type]++;
+
       gtk_widget_get_preferred_width_for_height (child->widget,
                                                  height,
                                                  &sizes[i].minimum_size,
@@ -1050,6 +1057,8 @@ gtk_header_bar_allocate_contents (GtkCssGadget        *gadget,
                                                &title_natural_size);
   width -= title_natural_size;
 
+  title_expands = gtk_widget_compute_expand (title_widget, GTK_ORIENTATION_HORIZONTAL);
+
   start_width = 0;
   if (priv->titlebar_start_box != NULL)
     {
@@ -1095,6 +1104,31 @@ gtk_header_bar_allocate_contents (GtkCssGadget        *gadget,
         }
     }
 
+  /* figure out how much space is left on each side of the title,
+   * and earkmark that space for the expanded children.
+   *
+   * If the title itself is expanded, then it gets half the spoils
+   * from each side.
+   */
+  for (packing = GTK_PACK_START; packing <= GTK_PACK_END; packing++)
+    {
+      gint side_free_space;
+
+      side_free_space = allocation->width / 2 - title_natural_size / 2 - side[packing];
+
+      if (side_free_space > 0 && nexpand_children[packing] > 0)
+        {
+          width -= side_free_space;
+
+          if (title_expands)
+            side_free_space -= side_free_space / 2;
+
+          side[packing] += side_free_space;
+          uniform_expand_bonus[packing] = side_free_space / nexpand_children[packing];
+          leftover_expand_bonus[packing] = side_free_space % nexpand_children[packing];
+        }
+    }
+
   /* allocate the children on both sides of the title */
   for (packing = GTK_PACK_START; packing <= GTK_PACK_END; packing++)
     {
@@ -1117,6 +1151,22 @@ gtk_header_bar_allocate_contents (GtkCssGadget        *gadget,
 
           child_size = sizes[i].minimum_size;
 
+          /* if this child is expanded, give it extra space from the reserves */
+          if (gtk_widget_compute_expand (child->widget, GTK_ORIENTATION_HORIZONTAL))
+            {
+              gint expand_bonus;
+
+              expand_bonus = uniform_expand_bonus[packing];
+
+              if (leftover_expand_bonus[packing] > 0)
+                {
+                  expand_bonus++;
+                  leftover_expand_bonus[packing]--;
+                }
+
+              child_size += expand_bonus;
+            }
+
           child_allocation.width = child_size;
 
           if (packing == GTK_PACK_START)
@@ -1153,6 +1203,15 @@ gtk_header_bar_allocate_contents (GtkCssGadget        *gadget,
   child_allocation.x = allocation->x + (allocation->width - child_size) / 2;
   child_allocation.width = child_size;
 
+  /* if the title widget is expanded, then grow it by all the available
+   * free space, and recenter it
+   */
+  if (title_expands && width > 0)
+    {
+      child_allocation.width += width;
+      child_allocation.x -= width / 2;
+    }
+
   if (allocation->x + side[0] > child_allocation.x)
     child_allocation.x = allocation->x + side[0];
   else if (allocation->x + allocation->width - side[1] < child_allocation.x + child_allocation.width)


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