[gtk+/extended-layout-jhs: 29/64] Add gtk_extended_layout_set_baseline_offset to allow widget to adjust



commit 3c351a8f928d9548a0375e04c3d56004a40175e7
Author: Mathias Hasselmann <mathias hasselmann gmx de>
Date:   Sun Jul 1 21:12:21 2007 +0000

    Add gtk_extended_layout_set_baseline_offset to allow widget to adjust
    
    2007-07-01  Mathias Hasselmann  <mathias hasselmann gmx de>
    
    	* gtk/gtk.symbols, gtk/gtkextendedlayout.c, gtk/gtkextendedlayout.h:
    	Add gtk_extended_layout_set_baseline_offset to allow widget to adjust
    	their baselines to the findings of their parent container.
    	* gtk/gtkhbox.c: Use gtk_extended_layout_set_baseline_offset to obey
    	the uniform height constraint of the horizontal box. Do not cache
    	baselines found during requisition evaluation, as baselines can
    	change, when assigning a widget more space than requested.
    	* gtk/gtklabel.c: Implement gtk_extended_layout_set_baseline_offset.
    
    svn path=/branches/extended-layout/; revision=18330

 ChangeLog.gtk-extended-layout |   11 ++++
 gtk/gtk.symbols               |    1 +
 gtk/gtkextendedlayout.c       |   26 +++++++++-
 gtk/gtkextendedlayout.h       |    4 ++
 gtk/gtkhbox.c                 |  112 ++++++++++++++++++++++++-----------------
 gtk/gtklabel.c                |   15 ++++-
 6 files changed, 118 insertions(+), 51 deletions(-)
---
diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout
index aa3f4ad..608847d 100644
--- a/ChangeLog.gtk-extended-layout
+++ b/ChangeLog.gtk-extended-layout
@@ -1,5 +1,16 @@
 2007-07-01  Mathias Hasselmann  <mathias hasselmann gmx de>
 
+	* gtk/gtk.symbols, gtk/gtkextendedlayout.c, gtk/gtkextendedlayout.h:
+	Add gtk_extended_layout_set_baseline_offset to allow widget to adjust
+	their baselines to the findings of their parent container.
+	* gtk/gtkhbox.c: Use gtk_extended_layout_set_baseline_offset to obey
+	the uniform height constraint of the horizontal box. Do not cache
+	baselines found during requisition evaluation, as baselines can
+	change, when assigning a widget more space than requested.
+	* gtk/gtklabel.c: Implement gtk_extended_layout_set_baseline_offset.
+
+2007-07-01  Mathias Hasselmann  <mathias hasselmann gmx de>
+
 	* tests/testextendedlayout.c: Invalidate previously selected
 	widget when choosing another one, to avoid drawing artifacts.
 
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 28ae853..dcca18e 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -1292,6 +1292,7 @@ gtk_extended_layout_get_height_for_width
 gtk_extended_layout_get_width_for_height
 gtk_extended_layout_get_natural_size
 gtk_extended_layout_get_baselines
+gtk_extended_layout_set_baseline_offset
 gtk_extended_layout_get_single_baseline
 gtk_extended_layout_get_padding
 #endif
diff --git a/gtk/gtkextendedlayout.c b/gtk/gtkextendedlayout.c
index 2760fec..f53bd9f 100644
--- a/gtk/gtkextendedlayout.c
+++ b/gtk/gtkextendedlayout.c
@@ -135,7 +135,7 @@ gtk_extended_layout_get_natural_size (GtkExtendedLayout *layout,
   iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout);
 
   g_return_if_fail (iface->get_natural_size);
-  return iface->get_natural_size(layout, requisition);
+  iface->get_natural_size(layout, requisition);
 }
 
 /**
@@ -166,6 +166,30 @@ gtk_extended_layout_get_baselines (GtkExtendedLayout  *layout,
 }
 
 /**
+ * gtk_extended_layout_set_baseline_offset:
+ * @layout: a #GtkExtendedLayout
+ * @offset: the offset to consider
+ *
+ * Informs the layout item about the offset it should apply to its baselines,
+ * to properly align them with all other baseline aware children of its parent.
+ *
+ * Since: 2.14
+ **/
+void
+gtk_extended_layout_set_baseline_offset (GtkExtendedLayout *layout,
+                                         gint               offset)
+{
+  GtkExtendedLayoutIface *iface;
+
+  g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout));
+
+  iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout);
+
+  g_return_if_fail (iface->set_baseline_offset);
+  iface->set_baseline_offset (layout, offset);
+}
+
+/**
  * gtk_extended_layout_get_single_baseline:
  * @layout: a #GtkExtendedLayout
  * @policy: specifies the policy for choosing a baseline
diff --git a/gtk/gtkextendedlayout.h b/gtk/gtkextendedlayout.h
index 6b4a31a..485d5de 100644
--- a/gtk/gtkextendedlayout.h
+++ b/gtk/gtkextendedlayout.h
@@ -74,6 +74,8 @@ struct _GtkExtendedLayoutIface
                                                      GtkRequisition     *requisition);
   gint                      (*get_baselines)        (GtkExtendedLayout  *layout,
                                                      gint              **baselines);
+  void                      (*set_baseline_offset)  (GtkExtendedLayout  *layout,
+                                                     gint                offset);
   void                      (*get_padding)          (GtkExtendedLayout  *layout,
                                                      GtkBorder          *padding);
 };
@@ -89,6 +91,8 @@ void                      gtk_extended_layout_get_natural_size     (GtkExtendedL
                                                                     GtkRequisition     *requisition);
 gint                      gtk_extended_layout_get_baselines        (GtkExtendedLayout  *layout,
                                                                     gint              **baselines);
+void                      gtk_extended_layout_set_baseline_offset  (GtkExtendedLayout  *layout,
+                                                                    gint                offset);
 gint                      gtk_extended_layout_get_single_baseline  (GtkExtendedLayout  *layout,
                                                                     GtkBaselinePolicy   policy);
 void                      gtk_extended_layout_get_padding          (GtkExtendedLayout  *layout,
diff --git a/gtk/gtkhbox.c b/gtk/gtkhbox.c
index a0b32d3..b885185 100644
--- a/gtk/gtkhbox.c
+++ b/gtk/gtkhbox.c
@@ -43,11 +43,8 @@ typedef struct _GtkHBoxPrivate GtkHBoxPrivate;
 struct _GtkHBoxPrivate
 {
   GtkBaselinePolicy baseline_policy;
-  gint effective_baseline;
-  gint *baselines;
 };
 
-static void gtk_hbox_dispose       (GObject        *object);
 static void gtk_hbox_set_property  (GObject        *object,
 		                    guint           prop_id,
 		                    const GValue   *value,
@@ -74,7 +71,6 @@ gtk_hbox_class_init (GtkHBoxClass *class)
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 
-  gobject_class->dispose = gtk_hbox_dispose;
   gobject_class->set_property = gtk_hbox_set_property;
   gobject_class->get_property = gtk_hbox_get_property;
 
@@ -132,17 +128,6 @@ gtk_hbox_set_property (GObject      *object,
 }
 
 static void 
-gtk_hbox_dispose (GObject    *object)
-{
-  GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (object);
-
-  g_free (priv->baselines);
-  priv->baselines = NULL;
-
-  G_OBJECT_CLASS (gtk_hbox_parent_class)->dispose (object);
-}
-
-static void 
 gtk_hbox_get_property (GObject    *object,
 		       guint       prop_id,
 		       GValue     *value,
@@ -188,15 +173,15 @@ gtk_hbox_size_request (GtkWidget      *widget,
   if (nvis_children > 0)
     {
       GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget);
-      gint i_child;
-
-      g_free (priv->baselines);
-      priv->baselines = g_new0 (gint, nvis_children);
+      gint effective_baseline, i;
+      gint *baselines = NULL;
 
-      priv->effective_baseline = 0;
       if (priv->baseline_policy != GTK_BASELINE_NONE)
         {
-          i_child = 0;
+          baselines = g_newa (gint, nvis_children);
+          effective_baseline = 0;
+
+          i = 0;
           children = box->children;
           while (children)
             {
@@ -205,20 +190,25 @@ gtk_hbox_size_request (GtkWidget      *widget,
 
               if (GTK_WIDGET_VISIBLE (child->widget))
                 {
-                  if (GTK_IS_EXTENDED_LAYOUT (child->widget))
+                  if (GTK_IS_EXTENDED_LAYOUT (child->widget) &&
+                      GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget))
                     {
-                      priv->baselines[i_child] = gtk_extended_layout_get_single_baseline (
-                        GTK_EXTENDED_LAYOUT (child->widget), priv->baseline_policy);
+                      GtkExtendedLayout *layout = GTK_EXTENDED_LAYOUT (child->widget);
+
+                      gtk_extended_layout_set_baseline_offset (layout, 0);
+                      baselines[i] = gtk_extended_layout_get_single_baseline (layout, priv->baseline_policy);
 
-                      priv->effective_baseline = MAX (priv->effective_baseline, priv->baselines[i_child]);
+                      effective_baseline = MAX (effective_baseline, baselines[i]);
                     }
+                  else
+                    baselines[i] = 0;
 
-                  ++i_child;
+                  ++i;
                 }
             }
         }
 
-      i_child = 0;
+      i = 0;
       children = box->children;
       while (children)
         {
@@ -242,10 +232,15 @@ gtk_hbox_size_request (GtkWidget      *widget,
                   requisition->width += child_requisition.width + child->padding * 2;
                 }
 
-              child_requisition.height += MAX (0, (priv->effective_baseline - priv->baselines[i_child]));
+              if (baselines)
+                {
+                  gint padding = MAX (effective_baseline - baselines[i], 0);
+                  child_requisition.height += padding;
+                }
+
               requisition->height = MAX (requisition->height, child_requisition.height);
 
-              ++i_child;
+              ++i;
             }
         }
 
@@ -298,12 +293,16 @@ gtk_hbox_size_allocate (GtkWidget     *widget,
     {
       GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget);
       GtkAllocation child_allocation;
+      gint effective_baseline, i;
       GtkPackType packing;
-      gint i_child;
+      gint *baselines;
 
       gint width;
       gint extra;
 
+      baselines = g_newa (gint, nvis_children);
+      effective_baseline = 0;
+
       if (box->homogeneous)
 	{
 	  width = (allocation->width -
@@ -334,7 +333,7 @@ gtk_hbox_size_allocate (GtkWidget     *widget,
           else
             x = allocation->x + allocation->width - GTK_CONTAINER (box)->border_width;
 
-          i_child = 0;
+          i = 0;
           children = box->children;
           while (children)
             {
@@ -346,7 +345,7 @@ gtk_hbox_size_allocate (GtkWidget     *widget,
                   if ((child->pack == packing))
                     {
                       GtkRequisition child_requisition;
-                      gint child_width, dy;
+                      gint child_width;
 
                       gtk_widget_get_child_requisition (child->widget, &child_requisition);
 
@@ -393,34 +392,53 @@ gtk_hbox_size_allocate (GtkWidget     *widget,
                       if (GTK_TEXT_DIR_RTL == direction)
                         child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
 
+                      gtk_widget_size_allocate (child->widget, &child_allocation);
 
-                      if (GTK_BASELINE_NONE != priv->baseline_policy)
+                      if (GTK_BASELINE_NONE != priv->baseline_policy &&
+                          GTK_IS_EXTENDED_LAYOUT (child->widget) &&
+                          GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget))
                         {
-                          GtkRequisition child_requisition;
+                          GtkExtendedLayout *layout = GTK_EXTENDED_LAYOUT (child->widget);
 
-                          dy = MAX (0, (priv->effective_baseline - priv->baselines[i_child]));
-                          gtk_widget_size_request (child->widget, &child_requisition);
+                          gtk_extended_layout_set_baseline_offset (layout, 0);
+                          baselines[i] = gtk_extended_layout_get_single_baseline (layout, priv->baseline_policy);
 
-                          child_allocation.y += dy;
-                          child_allocation.height = child_requisition.height;
+                          effective_baseline = MAX (effective_baseline, baselines[i]);
                         }
-
-                      gtk_widget_size_allocate (child->widget, &child_allocation);
-
-                      if (GTK_BASELINE_NONE != priv->baseline_policy)
-                        child_allocation.y -= dy;
+                      else
+                        baselines[i] = 0;
 
                       if (GTK_PACK_START == packing)
                         x += child_width + box->spacing;
                       else
                         x -= child_width + box->spacing;
-                    }
+                    } /* packing */
+
+                  ++i;
+                } /* visible */
+            } /* while children */
+        } /* for packing */
+
+      if (GTK_BASELINE_NONE != priv->baseline_policy)
+        {
+          i = 0;
+          children = box->children;
+          while (children)
+            {
+              child = children->data;
+              children = children->next;
 
-                  ++i_child;
+              if (GTK_IS_EXTENDED_LAYOUT (child->widget) &&
+                  GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget))
+                {
+                  gint dy = MAX (0, effective_baseline - baselines[i]);
+                  gtk_extended_layout_set_baseline_offset (GTK_EXTENDED_LAYOUT (child->widget), dy);
                 }
+
+              ++i;
             }
-        }
-    }
+        } /* baseline_policy */
+    } /* nvis_children */
 }
 
 /**
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 45e3465..ab304f6 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -54,6 +54,7 @@ typedef struct
   gint wrap_width;
   gint width_chars;
   gint max_width_chars;
+  gint baseline_offset;
 }
 GtkLabelPrivate;
 
@@ -2318,6 +2319,7 @@ get_layout_location (GtkLabel  *label,
   GtkLabelPrivate *priv;
   gfloat xalign;
   gint req_width, x, y;
+  gfloat dy;
   
   misc = GTK_MISC (label);
   widget = GTK_WIDGET (label);
@@ -2352,9 +2354,8 @@ get_layout_location (GtkLabel  *label,
   else
     x = MIN (x, widget->allocation.x + widget->allocation.width - misc->xpad);
 
-  y = floor (widget->allocation.y + (gint)misc->ypad 
-             + MAX (((widget->allocation.height - widget->requisition.height) * misc->yalign),
-	     0));
+  dy = (widget->allocation.height - widget->requisition.height) * misc->yalign;
+  y = floor (widget->allocation.y + (gint)misc->ypad + priv->baseline_offset + MAX (dy, 0));
 
   if (xp)
     *xp = x;
@@ -4316,12 +4317,20 @@ gtk_label_extended_layout_get_baselines (GtkExtendedLayout  *layout,
 }
 
 static void
+gtk_label_extended_layout_set_baseline_offset (GtkExtendedLayout *layout,
+                                               gint               offset)
+{
+  GTK_LABEL_GET_PRIVATE (layout)->baseline_offset = offset;
+}
+
+static void
 gtk_label_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
 {
   iface->get_features = gtk_label_extended_layout_get_features;
   iface->get_height_for_width = gtk_label_extended_layout_get_height_for_width;
   iface->get_natural_size = gtk_label_extended_layout_get_natural_size;
   iface->get_baselines = gtk_label_extended_layout_get_baselines;
+  iface->set_baseline_offset = gtk_label_extended_layout_set_baseline_offset;
 }
 
 #define __GTK_LABEL_C__



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