diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout index cd4af71b95..f3f3cdd781 100644 --- a/ChangeLog.gtk-extended-layout +++ b/ChangeLog.gtk-extended-layout @@ -1,8 +1,19 @@ 2007-06-28 Mathias Hasselmann - * gtk/gtkhbox.c, gtk/gtkhbox.h, gtk/gtk.symbols, - tests/testextendedlayout.c: Initial, buggish implementation - of baseline alignment in GtkHBox. + * gtk/gtkhbox.c: Merge separate, but nearly identical child allocation + code for start and end packing into one single loop. This should avoid + programming errors caused by extensive code duplication, as they happend + to me with the previous commit. Maybe some advanced compiler is able + to do the trivial loop unrolling. + * tests/testextendedlayout.c: Use exteriour guides instead of + separators to identify GtkHBox allocation and extend the baseline + alignment tests for GtkHBox. + +2007-06-28 Mathias Hasselmann + + * gtk/gtkhbox.c, gtk/gtkhbox.h, gtk/gtk.symbols: + Initial, buggish implementation of baseline alignment in GtkHBox. + * tests/testextendedlayout.c: Add baseline alignment tests. 2007-06-28 Mathias Hasselmann diff --git a/gtk/gtkhbox.c b/gtk/gtkhbox.c index ef685131c7..24ee1fd9e7 100644 --- a/gtk/gtkhbox.c +++ b/gtk/gtkhbox.c @@ -157,6 +157,20 @@ gtk_hbox_get_property (GObject *object, } } +static gboolean +debug_wanted (GtkWidget *widget) +{ + while (widget) + { + if (g_object_get_data (G_OBJECT (widget), "debug-wanted")) + return TRUE; + + widget = gtk_widget_get_parent (widget); + } + + return FALSE; +} + static void gtk_hbox_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -238,6 +252,11 @@ gtk_hbox_size_request (GtkWidget *widget, requisition->width += child_requisition.width + child->padding * 2; } +if (debug_wanted (child->widget)) + g_debug("%s[%d:%s]: baseline=%d (%d)", + gtk_widget_get_name (widget), i_child, G_OBJECT_TYPE_NAME (child->widget), + priv->baselines[i_child], priv->effective_baseline); + child_requisition.height += MAX (0, (priv->effective_baseline - priv->baselines[i_child])); requisition->height = MAX (requisition->height, child_requisition.height); @@ -294,12 +313,11 @@ gtk_hbox_size_allocate (GtkWidget *widget, { GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget); GtkAllocation child_allocation; - gint child_width; + GtkPackType packing; gint i_child; gint width; gint extra; - gint x; if (box->homogeneous) { @@ -319,147 +337,100 @@ gtk_hbox_size_allocate (GtkWidget *widget, extra = 0; } - x = allocation->x + GTK_CONTAINER (box)->border_width; child_allocation.y = allocation->y + GTK_CONTAINER (box)->border_width; child_allocation.height = MAX (1, (gint) allocation->height - (gint) GTK_CONTAINER (box)->border_width * 2); - children = box->children; - while (children) - { - child = children->data; - children = children->next; + for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) + { + gint x, dy; - if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget)) - { - if (box->homogeneous) - { - if (nvis_children == 1) - child_width = width; - else - child_width = extra; + if (GTK_PACK_START == packing) + x = allocation->x + GTK_CONTAINER (box)->border_width; + else + x = allocation->x + allocation->width - GTK_CONTAINER (box)->border_width; - nvis_children -= 1; - width -= extra; - } - else - { - GtkRequisition child_requisition; + i_child = 0; + children = box->children; + while (children) + { + child = children->data; + children = children->next; - gtk_widget_get_child_requisition (child->widget, &child_requisition); - - child_width = child_requisition.width + child->padding * 2; - - if (child->expand) - { - if (nexpand_children == 1) - child_width += width; - else - child_width += extra; - - nexpand_children -= 1; - width -= extra; - } - } - - if (child->fill) - { - child_allocation.width = MAX (1, (gint) child_width - (gint) child->padding * 2); - child_allocation.x = x + child->padding; - } - else - { - GtkRequisition child_requisition; - - gtk_widget_get_child_requisition (child->widget, &child_requisition); - child_allocation.width = child_requisition.width; - child_allocation.x = x + (child_width - child_allocation.width) / 2; - } - - if (direction == GTK_TEXT_DIR_RTL) - child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; - - gtk_widget_size_allocate (child->widget, &child_allocation); - - x += child_width + box->spacing; - } - } - - x = allocation->x + allocation->width - GTK_CONTAINER (box)->border_width; - - children = box->children; - while (children) - { - child = children->data; - children = children->next; - - if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget)) - { - GtkRequisition child_requisition; - gtk_widget_get_child_requisition (child->widget, &child_requisition); - - if (box->homogeneous) + if (GTK_WIDGET_VISIBLE (child->widget)) { - if (nvis_children == 1) - child_width = width; - else - child_width = extra; - - nvis_children -= 1; - width -= extra; - } - else - { - child_width = child_requisition.width + child->padding * 2; - - if (child->expand) + if ((child->pack == packing)) { - if (nexpand_children == 1) - child_width += width; + GtkRequisition child_requisition; + gint child_width; + + gtk_widget_get_child_requisition (child->widget, &child_requisition); + + if (box->homogeneous) + { + if (nvis_children == 1) + child_width = width; + else + child_width = extra; + + nvis_children -= 1; + width -= extra; + } else - child_width += extra; + { + child_width = child_requisition.width + child->padding * 2; - nexpand_children -= 1; - width -= extra; + if (child->expand) + { + if (nexpand_children == 1) + child_width += width; + else + child_width += extra; + + nexpand_children -= 1; + width -= extra; + } + } + + if (child->fill) + { + child_allocation.width = MAX (1, (gint) child_width - (gint) child->padding * 2); + child_allocation.x = x + child->padding; + } + else + { + child_allocation.width = child_requisition.width; + child_allocation.x = x + (child_width - child_allocation.width) / 2; + } + + if (GTK_PACK_END == packing) + child_allocation.x -= child_width; + + if (GTK_TEXT_DIR_RTL == direction) + child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; + + dy = MAX (0, (priv->effective_baseline - priv->baselines[i_child])); + +if (debug_wanted (child->widget)) + g_debug("%s[%d:%s]: dy=%d, y=%d, height:%d", + gtk_widget_get_name (widget), i_child, G_OBJECT_TYPE_NAME (child->widget), + dy, child_allocation.y, child_allocation.height); + + child_allocation.y += dy; + child_allocation.height -= dy; + + gtk_widget_size_allocate (child->widget, &child_allocation); + + child_allocation.height += dy; + child_allocation.y -= dy; + + if (GTK_PACK_START == packing) + x += child_width + box->spacing; + else + x -= child_width + box->spacing; } + + ++i_child; } - - if (child->fill) - { - child_allocation.width = MAX (1, (gint)child_width - (gint)child->padding * 2); - child_allocation.x = x + child->padding - child_width; - } - else - { - child_allocation.width = child_requisition.width; - child_allocation.x = x + (child_width - child_allocation.width) / 2 - child_width; - } - - if (direction == GTK_TEXT_DIR_RTL) - child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; - - gtk_widget_size_allocate (child->widget, &child_allocation); - - x -= (child_width + box->spacing); - } - } - - i_child = 0; - children = box->children; - while (children) - { - child = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (child->widget)) - { - gint offset; - - offset = MAX (0, (priv->effective_baseline - priv->baselines[i_child])); - - child->widget->allocation.y += offset; - child->widget->allocation.height -= offset; - - ++i_child; } } } diff --git a/tests/testextendedlayout.c b/tests/testextendedlayout.c index 8450849ed4..c24fff4f87 100644 --- a/tests/testextendedlayout.c +++ b/tests/testextendedlayout.c @@ -341,7 +341,7 @@ create_baseline_test (TestSuite *suite) } static TestCase* -create_baseline_test_bin (TestSuite *suite) +create_baseline_test2 (TestSuite *suite) { GtkWidget *bin; GtkWidget *label; @@ -366,10 +366,16 @@ create_baseline_test_bin (TestSuite *suite) NULL }; + const gchar *names[] = + { + "default", "baseline", "baseline and bottom-padding", + "baseline and top-padding", "baseline and border-width" + }; + TestCase *test = test_case_new (suite, "Baseline Alignment II", gtk_alignment_new (0.5, 0.5, 0.0, 0.0)); - table = gtk_table_new (G_N_ELEMENTS (types) + 6, + table = gtk_table_new (G_N_ELEMENTS (types) + 4, G_N_ELEMENTS (markup), FALSE); @@ -400,25 +406,24 @@ create_baseline_test_bin (TestSuite *suite) } } - gtk_table_attach (GTK_TABLE (table), gtk_hseparator_new (), - 0, G_N_ELEMENTS (markup), - G_N_ELEMENTS (types), G_N_ELEMENTS (types) + 1, - GTK_FILL, GTK_FILL, 0, 0); - - for (i = 0; i < 6; i += 2) + for (i = 0; i < 5; ++i) { + label = gtk_label_new (names[i]); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + hbox = gtk_hbox_new (FALSE, 6); - gtk_hbox_set_baseline_policy (GTK_HBOX (hbox), GTK_BASELINE_FIRST); + test_case_append_guide (test, hbox, GUIDE_EXTERIOUR_BOTH, -1); + g_object_set_data (G_OBJECT (hbox), "debug-wanted", TRUE); + gtk_widget_set_name (hbox, names[i]); - gtk_table_attach (GTK_TABLE (table), hbox, - 0, G_N_ELEMENTS (markup), - G_N_ELEMENTS (types) + i + 1, - G_N_ELEMENTS (types) + i + 2, + if (i > 0) + gtk_hbox_set_baseline_policy (GTK_HBOX (hbox), GTK_BASELINE_FIRST); + + gtk_table_attach (GTK_TABLE (table), label, 0, 1, + G_N_ELEMENTS (types) + i, G_N_ELEMENTS (types) + i + 1, GTK_FILL, GTK_FILL, 0, 0); - gtk_table_attach (GTK_TABLE (table), gtk_hseparator_new (), - 0, G_N_ELEMENTS (markup), - G_N_ELEMENTS (types) + i + 2, - G_N_ELEMENTS (types) + i + 3, + gtk_table_attach (GTK_TABLE (table), hbox, 1, G_N_ELEMENTS (markup), + G_N_ELEMENTS (types) + i, G_N_ELEMENTS (types) + i + 1, GTK_FILL, GTK_FILL, 0, 0); for (j = 0; markup[j]; ++j) @@ -428,13 +433,26 @@ create_baseline_test_bin (TestSuite *suite) test_case_append_guide (test, label, GUIDE_BASELINE, G_N_ELEMENTS (types)); - if (0 == j && i >= 2) + if (0 == j && i > 1) { bin = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - gtk_alignment_set_padding (GTK_ALIGNMENT (bin), 0, 0, 0, 0); -// i < 3 ? 20 : 0, i > 3 ? 20 : 0, 0, 0); - gtk_container_add (GTK_CONTAINER (bin), label); + switch (i) + { + case 2: + gtk_alignment_set_padding (GTK_ALIGNMENT (bin), 0, 25, 0, 0); + break; + + case 3: + gtk_alignment_set_padding (GTK_ALIGNMENT (bin), 25, 0, 0, 0); + break; + + case 4: + gtk_container_set_border_width (GTK_CONTAINER (bin), 12); + break; + } + + gtk_container_add (GTK_CONTAINER (bin), label); gtk_box_pack_start (GTK_BOX (hbox), bin, FALSE, TRUE, 0); } else @@ -914,7 +932,7 @@ test_suite_new () test_suite_append (self, create_natural_size_test (self)); test_suite_append (self, create_height_for_width_test (self)); test_suite_append (self, create_baseline_test (self)); - test_suite_append (self, create_baseline_test_bin (self)); + test_suite_append (self, create_baseline_test2 (self)); self->results = gtk_tree_store_new (COLUNN_COUNT, G_TYPE_STRING, PANGO_TYPE_WEIGHT,