From f568484846586f4cd2bdfc1b07a77b31d39f6dca Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Sun, 1 Jul 2007 21:12:21 +0000 Subject: [PATCH] Add gtk_extended_layout_set_baseline_offset to allow widget to adjust 2007-07-01 Mathias Hasselmann * 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 | 118 ++++++++++++++++++++-------------- gtk/gtklabel.c | 15 ++++- 6 files changed, 121 insertions(+), 54 deletions(-) diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout index ea674c8d41..1a19bd6c10 100644 --- a/ChangeLog.gtk-extended-layout +++ b/ChangeLog.gtk-extended-layout @@ -1,3 +1,14 @@ +2007-07-01 Mathias Hasselmann + + * 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 * tests/testextendedlayout.c: Invalidate previously selected diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index d131ecebc4..0fbdfa5ae9 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -1328,6 +1328,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 2760fec48b..f53bd9fd5d 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); } /** @@ -165,6 +165,30 @@ gtk_extended_layout_get_baselines (GtkExtendedLayout *layout, return iface->get_baselines(layout, baselines); } +/** + * 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 diff --git a/gtk/gtkextendedlayout.h b/gtk/gtkextendedlayout.h index 6b4a31a2f7..485d5de40b 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 a0b32d3b4d..b885185cf8 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; @@ -131,17 +127,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, @@ -188,15 +173,15 @@ gtk_hbox_size_request (GtkWidget *widget, if (nvis_children > 0) { GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget); - gint i_child; + gint effective_baseline, i; + gint *baselines = NULL; - g_free (priv->baselines); - priv->baselines = g_new0 (gint, nvis_children); - - 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); - priv->effective_baseline = MAX (priv->effective_baseline, priv->baselines[i_child]); + gtk_extended_layout_set_baseline_offset (layout, 0); + baselines[i] = gtk_extended_layout_get_single_baseline (layout, priv->baseline_policy); + + 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; - - if (GTK_BASELINE_NONE != priv->baseline_policy) - { - GtkRequisition child_requisition; - - dy = MAX (0, (priv->effective_baseline - priv->baselines[i_child])); - gtk_widget_size_request (child->widget, &child_requisition); - - child_allocation.y += dy; - child_allocation.height = child_requisition.height; - } - gtk_widget_size_allocate (child->widget, &child_allocation); - if (GTK_BASELINE_NONE != priv->baseline_policy) - child_allocation.y -= dy; + if (GTK_BASELINE_NONE != priv->baseline_policy && + GTK_IS_EXTENDED_LAYOUT (child->widget) && + GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget)) + { + 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); + + effective_baseline = MAX (effective_baseline, baselines[i]); + } + else + baselines[i] = 0; if (GTK_PACK_START == packing) x += child_width + box->spacing; else x -= child_width + box->spacing; - } + } /* packing */ - ++i_child; + ++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; + + 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 d4cf8aafe3..24ac08e19c 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; @@ -2322,6 +2323,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); @@ -2356,9 +2358,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; @@ -4319,6 +4320,13 @@ gtk_label_extended_layout_get_baselines (GtkExtendedLayout *layout, return num_lines; } +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) { @@ -4326,6 +4334,7 @@ gtk_label_extended_layout_interface_init (GtkExtendedLayoutIface *iface) 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__