]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkbox.c
gtk: remove "gboolean homogeneous" from gtk_box_new()
[~andy/gtk] / gtk / gtkbox.c
index e8310c50c52a19353055fa7879b88d08955fdf9a..707f4ffa559c34ba425e5077eefc9ac2868fa5a7 100644 (file)
@@ -28,7 +28,7 @@
  * SECTION:gtkbox
  * @Short_description: Base class for box containers
  * @Title: GtkBox
- * @See_also:i #GtkHBox, #GtkVBox, #GtkFrame, #GtkTable, #GtkLayout
+ * @See_also: #GtkHBox, #GtkVBox, #GtkFrame, #GtkTable, #GtkLayout
  *
  * GtkBox is an widget which encapsulates functionality for a
  * particular kind of container, one that organizes a variable number of
  * of the GtkBox are forced to get the same amount of space.
  *
  * Use gtk_box_set_spacing() to determine how much space will be
- * minimally placed between all children in the GtkBox.
+ * minimally placed between all children in the GtkBox. Note that
+ * spacing is added <emphasis>between</emphasis> the children, while
+ * padding added by gtk_box_pack_start() or gtk_box_pack_end() is added
+ * <emphasis>on either side</emphasis> of the widget it belongs to.
  *
  * Use gtk_box_reorder_child() to move a GtkBox child to a different
  * place in the box.
  * Use gtk_box_set_child_packing() to reset the #GtkBox:expand,
  * #GtkBox:fill and #GtkBox:padding child properties.
  * Use gtk_box_query_child_packing() to query these fields.
+ *
+ * <note>
+ * <para>
+ * Note that a single-row or single-column #GtkGrid provides exactly the
+ * same functionality as #GtkBox.
+ * </para>
+ * </note>
  */
 
 #include "config.h"
@@ -78,6 +88,7 @@
 #include "gtkbox.h"
 #include "gtkorientable.h"
 #include "gtksizerequest.h"
+#include "gtktypeutils.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 
@@ -141,6 +152,10 @@ struct _GtkBoxChild
 static void gtk_box_size_allocate         (GtkWidget              *widget,
                                            GtkAllocation          *allocation);
 
+static void gtk_box_compute_expand     (GtkWidget      *widget,
+                                        gboolean       *hexpand,
+                                        gboolean       *vexpand);
+
 static void gtk_box_set_property       (GObject        *object,
                                         guint           prop_id,
                                         const GValue   *value,
@@ -149,7 +164,6 @@ static void gtk_box_get_property       (GObject        *object,
                                         guint           prop_id,
                                         GValue         *value,
                                         GParamSpec     *pspec);
-
 static void gtk_box_add                (GtkContainer   *container,
                                         GtkWidget      *widget);
 static void gtk_box_remove             (GtkContainer   *container,
@@ -207,6 +221,7 @@ gtk_box_class_init (GtkBoxClass *class)
   widget_class->get_preferred_height           = gtk_box_get_preferred_height;
   widget_class->get_preferred_height_for_width = gtk_box_get_preferred_height_for_width;
   widget_class->get_preferred_width_for_height = gtk_box_get_preferred_width_for_height;
+  widget_class->compute_expand                 = gtk_box_compute_expand;
 
   container_class->add = gtk_box_add;
   container_class->remove = gtk_box_remove;
@@ -391,7 +406,7 @@ count_expand_children (GtkBox *box,
       if (gtk_widget_get_visible (child->widget))
        {
          *visible_children += 1;
-         if (child->expand)
+         if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
            *expand_children += 1;
        }
     }
@@ -569,7 +584,7 @@ gtk_box_size_allocate (GtkWidget     *widget,
            {
              child_size = sizes[i].minimum_size + child->padding * 2;
 
-             if (child->expand)
+             if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
                {
                  child_size += extra;
 
@@ -641,6 +656,56 @@ gtk_box_size_allocate (GtkWidget     *widget,
     }
 }
 
+static void
+gtk_box_compute_expand (GtkWidget      *widget,
+                        gboolean       *hexpand_p,
+                        gboolean       *vexpand_p)
+{
+  GtkBoxPrivate  *private = GTK_BOX (widget)->priv;
+  GList       *children;
+  GtkBoxChild *child;
+  gboolean our_expand;
+  gboolean opposite_expand;
+  GtkOrientation opposite_orientation;
+
+  if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
+    opposite_orientation = GTK_ORIENTATION_VERTICAL;
+  else
+    opposite_orientation = GTK_ORIENTATION_HORIZONTAL;
+
+  our_expand = FALSE;
+  opposite_expand = FALSE;
+
+  for (children = private->children; children; children = children->next)
+    {
+      child = children->data;
+
+      /* we don't recurse into children anymore as soon as we know
+       * expand=TRUE in an orientation
+       */
+
+      if (child->expand || (!our_expand && gtk_widget_compute_expand (child->widget, private->orientation)))
+        our_expand = TRUE;
+
+      if (!opposite_expand && gtk_widget_compute_expand (child->widget, opposite_orientation))
+        opposite_expand = TRUE;
+
+      if (our_expand && opposite_expand)
+        break;
+    }
+
+  if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      *hexpand_p = our_expand;
+      *vexpand_p = opposite_expand;
+    }
+  else
+    {
+      *hexpand_p = opposite_expand;
+      *vexpand_p = our_expand;
+    }
+}
+
 static GType
 gtk_box_child_type (GtkContainer   *container)
 {
@@ -1038,7 +1103,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
                {
                  child_size = sizes[i].minimum_size + child->padding * 2;
 
-                 if (child->expand)
+                 if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
                    {
                      child_size += extra;
 
@@ -1176,7 +1241,6 @@ gtk_box_get_preferred_height_for_width (GtkWidget *widget,
 /**
  * gtk_box_new:
  * @orientation: the box' orientation.
- * @homogeneous: %TRUE if all children are to be given equal space allocations.
  * @spacing: the number of pixels to place by default between children.
  *
  * Creates a new #GtkBox.
@@ -1187,13 +1251,11 @@ gtk_box_get_preferred_height_for_width (GtkWidget *widget,
  **/
 GtkWidget*
 gtk_box_new (GtkOrientation orientation,
-             gboolean       homogeneous,
              gint           spacing)
 {
   return g_object_new (GTK_TYPE_BOX,
                        "orientation", orientation,
                        "spacing",     spacing,
-                       "homogeneous", homogeneous ? TRUE : FALSE,
                        NULL);
 }
 
@@ -1201,22 +1263,22 @@ gtk_box_new (GtkOrientation orientation,
  * gtk_box_pack_start:
  * @box: a #GtkBox
  * @child: the #GtkWidget to be added to @box
- * @expand: %TRUE if the new child is to be given extra space allocated to
- * @box.  The extra space will be divided evenly between all children of
- * @box that use this option
+ * @expand: %TRUE if the new child is to be given extra space allocated
+ *     to @box. The extra space will be divided evenly between all children
+ *     that use this option
  * @fill: %TRUE if space given to @child by the @expand option is
- *   actually allocated to @child, rather than just padding it.  This
- *   parameter has no effect if @expand is set to %FALSE.  A child is
- *   always allocated the full height of a #GtkHBox and the full width 
- *   of a #GtkVBox. This option affects the other dimension
+ *     actually allocated to @child, rather than just padding it.  This
+ *     parameter has no effect if @expand is set to %FALSE.  A child is
+ *     always allocated the full height of a #GtkHBox and the full width
+ *     of a #GtkVBox. This option affects the other dimension
  * @padding: extra space in pixels to put between this child and its
  *   neighbors, over and above the global amount specified by
- *   #GtkBox:spacing property.  If @child is a widget at one of the 
- *   reference ends of @box, then @padding pixels are also put between 
+ *   #GtkBox:spacing property.  If @child is a widget at one of the
+ *   reference ends of @box, then @padding pixels are also put between
  *   @child and the reference edge of @box
  *
  * Adds @child to @box, packed with reference to the start of @box.
- * The @child is packed after any other child packed with reference 
+ * The @child is packed after any other child packed with reference
  * to the start of @box.
  */
 void
@@ -1535,8 +1597,20 @@ gtk_box_set_child_packing (GtkBox      *box,
   gtk_widget_freeze_child_notify (child);
   if (list)
     {
-      child_info->expand = expand != FALSE;
-      gtk_widget_child_notify (child, "expand");
+      gboolean expanded;
+
+      expanded = expand != FALSE;
+
+      /* avoid setting expand if unchanged, since queue_compute_expand
+       * can be expensive-ish
+       */
+      if (child_info->expand != expanded)
+        {
+          child_info->expand = expand != FALSE;
+          gtk_widget_queue_compute_expand (GTK_WIDGET (box));
+          gtk_widget_child_notify (child, "expand");
+        }
+
       child_info->fill = fill != FALSE;
       gtk_widget_child_notify (child, "fill");
       child_info->padding = padding;