[gtk+/extended-layout-jhs: 34/64] Implement and test natural size support for GtkVBox. Cleanup issues found
- From: Johannes Schmid <jhs src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/extended-layout-jhs: 34/64] Implement and test natural size support for GtkVBox. Cleanup issues found
- Date: Wed, 25 Nov 2009 11:21:46 +0000 (UTC)
commit 9e57247d9a930e2a5e30d80ded4a17bd4a1da026
Author: Mathias Hasselmann <mathias hasselmann gmx de>
Date: Wed Jul 18 12:57:09 2007 +0000
Implement and test natural size support for GtkVBox. Cleanup issues found
2007-07-16 Mathias Hasselmann <mathias hasselmann gmx de>
* gtk/gtkvbox.c, tests/testextendedlayout.c:
Implement and test natural size support for GtkVBox.
* gtk/gtkhbox.c: Cleanup issues found when implementing
natural size for GtkVBox.
svn path=/branches/extended-layout/; revision=18492
ChangeLog.gtk-extended-layout | 7 +
gtk/gtkhbox.c | 17 +--
gtk/gtkvbox.c | 301 +++++++++++++++++++++++++----------------
tests/testextendedlayout.c | 85 ++++++++----
4 files changed, 255 insertions(+), 155 deletions(-)
---
diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout
index 277e5b8..22391f2 100644
--- a/ChangeLog.gtk-extended-layout
+++ b/ChangeLog.gtk-extended-layout
@@ -1,3 +1,10 @@
+2007-07-16 Mathias Hasselmann <mathias hasselmann gmx de>
+
+ * gtk/gtkvbox.c, tests/testextendedlayout.c:
+ Implement and test natural size support for GtkVBox.
+ * gtk/gtkhbox.c: Cleanup issues found when implementing
+ natural size for GtkVBox.
+
2007-07-15 Mathias Hasselmann <mathias hasselmann gmx de>
* tests/testextendedlayout.c: Improve test result grouping.
diff --git a/gtk/gtkhbox.c b/gtk/gtkhbox.c
index 6ce6d41..1775cf9 100644
--- a/gtk/gtkhbox.c
+++ b/gtk/gtkhbox.c
@@ -290,19 +290,15 @@ gtk_hbox_size_allocate (GtkWidget *widget,
GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget);
GtkPackType packing;
-
GtkTextDirection direction;
gint border_width;
GtkAllocation child_allocation;
-
gint *natural_requisitions;
gint *minimum_requisitions;
- gint natural_width;
- gint minimum_width;
-
gint available, natural, extra;
+ gint natural_width;
gint i;
direction = gtk_widget_get_direction (widget);
@@ -312,8 +308,8 @@ gtk_hbox_size_allocate (GtkWidget *widget,
natural_requisitions = g_newa (gint, nvis_children);
minimum_requisitions = g_newa (gint, nvis_children);
- children = box->children;
i = 0;
+ children = box->children;
while (children)
{
@@ -344,13 +340,10 @@ gtk_hbox_size_allocate (GtkWidget *widget,
}
}
- minimum_width = widget->requisition.width - border_width * 2 -
- (nvis_children - 1) * box->spacing;
-
if (box->homogeneous)
{
available = (allocation->width - border_width * 2 -
- (nvis_children - 1) * box->spacing);
+ (nvis_children - 1) * box->spacing);
extra = available / nvis_children;
natural = 0;
}
@@ -390,7 +383,7 @@ gtk_hbox_size_allocate (GtkWidget *widget,
if (GTK_WIDGET_VISIBLE (child->widget))
{
- if ((child->pack == packing))
+ if (child->pack == packing)
{
gint child_width;
@@ -425,7 +418,7 @@ gtk_hbox_size_allocate (GtkWidget *widget,
if (child->fill)
{
- child_allocation.width = MAX (1, (gint) child_width - (gint) child->padding * 2);
+ child_allocation.width = MAX (1, child_width - (gint)child->padding * 2);
child_allocation.x = x + child->padding;
}
else
diff --git a/gtk/gtkvbox.c b/gtk/gtkvbox.c
index 65633d8..e84911e 100644
--- a/gtk/gtkvbox.c
+++ b/gtk/gtkvbox.c
@@ -26,6 +26,7 @@
#include <config.h>
#include "gtkvbox.h"
+#include "gtkextendedlayout.h"
#include "gtkintl.h"
#include "gtkalias.h"
@@ -35,7 +36,11 @@ static void gtk_vbox_size_request (GtkWidget *widget,
static void gtk_vbox_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
-G_DEFINE_TYPE (GtkVBox, gtk_vbox, GTK_TYPE_BOX)
+static void gtk_vbox_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkVBox, gtk_vbox, GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+ gtk_vbox_extended_layout_interface_init))
static void
gtk_vbox_class_init (GtkVBoxClass *class)
@@ -126,15 +131,11 @@ gtk_vbox_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkBox *box;
- GtkBoxChild *child;
- GList *children;
- GtkAllocation child_allocation;
+
gint nvis_children;
gint nexpand_children;
- gint child_height;
- gint height;
- gint extra;
- gint y;
+ GtkBoxChild *child;
+ GList *children;
box = GTK_BOX (widget);
widget->allocation = *allocation;
@@ -158,142 +159,206 @@ gtk_vbox_size_allocate (GtkWidget *widget,
if (nvis_children > 0)
{
+ GtkPackType packing;
+ gint border_width;
+
+ GtkAllocation child_allocation;
+ gint *natural_requisitions;
+ gint *minimum_requisitions;
+
+ gint available, natural, extra;
+ gint natural_height;
+ gint i;
+
+ border_width = GTK_CONTAINER (box)->border_width;
+
+ natural_height = 0;
+ natural_requisitions = g_newa (gint, nvis_children);
+ minimum_requisitions = g_newa (gint, nvis_children);
+
+ i = 0;
+ children = box->children;
+
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ if (GTK_WIDGET_VISIBLE (child->widget))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_size_request (child->widget, &child_requisition);
+ minimum_requisitions[i] = child_requisition.height;
+
+ if (GTK_IS_EXTENDED_LAYOUT (child->widget) &&
+ GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
+ {
+ gtk_extended_layout_get_natural_size (
+ GTK_EXTENDED_LAYOUT (child->widget),
+ &child_requisition);
+ natural_requisitions[i] =
+ child_requisition.height -
+ minimum_requisitions[i];
+ }
+ else
+ natural_requisitions[i] = 0;
+
+ natural_height += natural_requisitions[i++];
+ }
+ }
+
if (box->homogeneous)
{
- height = (allocation->height -
- GTK_CONTAINER (box)->border_width * 2 -
- (nvis_children - 1) * box->spacing);
- extra = height / nvis_children;
+ available = (allocation->height - border_width * 2 -
+ (nvis_children - 1) * box->spacing);
+ extra = available / nvis_children;
+ natural = 0;
}
else if (nexpand_children > 0)
{
- height = (gint) allocation->height - (gint) widget->requisition.height;
- extra = height / nexpand_children;
+ available = (gint)allocation->height - widget->requisition.height;
+ natural = MAX (0, MIN (available, natural_height));
+ available -= natural;
+
+ extra = MAX (0, available / nexpand_children);
}
else
{
- height = 0;
+ available = 0;
+ natural = 0;
extra = 0;
}
- y = allocation->y + GTK_CONTAINER (box)->border_width;
- child_allocation.x = allocation->x + GTK_CONTAINER (box)->border_width;
- child_allocation.width = MAX (1, (gint) allocation->width - (gint) GTK_CONTAINER (box)->border_width * 2);
-
- children = box->children;
- while (children)
- {
- child = children->data;
- children = children->next;
-
- if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
- {
- if (box->homogeneous)
- {
- if (nvis_children == 1)
- child_height = height;
- else
- child_height = extra;
-
- nvis_children -= 1;
- height -= extra;
- }
- else
- {
- GtkRequisition child_requisition;
-
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
- child_height = child_requisition.height + child->padding * 2;
-
- if (child->expand)
- {
- if (nexpand_children == 1)
- child_height += height;
- else
- child_height += extra;
-
- nexpand_children -= 1;
- height -= extra;
- }
- }
-
- if (child->fill)
- {
- child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
- child_allocation.y = y + child->padding;
- }
- else
- {
- GtkRequisition child_requisition;
-
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
- child_allocation.height = child_requisition.height;
- child_allocation.y = y + (child_height - child_allocation.height) / 2;
- }
-
- gtk_widget_size_allocate (child->widget, &child_allocation);
-
- y += child_height + box->spacing;
- }
- }
+ child_allocation.x = allocation->x + border_width;
+ child_allocation.width = MAX (1, (gint) allocation->width - (gint) border_width * 2);
- y = allocation->y + allocation->height - GTK_CONTAINER (box)->border_width;
+ for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
+ {
+ gint y;
- children = box->children;
- while (children)
- {
- child = children->data;
- children = children->next;
+ if (GTK_PACK_START == packing)
+ y = allocation->y + border_width;
+ else
+ y = allocation->y + allocation->height - border_width;
- if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget))
- {
- GtkRequisition child_requisition;
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
+ i = 0;
+ children = box->children;
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
- if (box->homogeneous)
+ if (GTK_WIDGET_VISIBLE (child->widget))
{
- if (nvis_children == 1)
- child_height = height;
- else
- child_height = extra;
+ if (child->pack == packing)
+ {
+ gint child_height;
+
+ if (box->homogeneous)
+ {
+ if (nvis_children == 1)
+ child_height = available;
+ else
+ child_height = extra;
+
+ nvis_children -= 1;
+ available -= extra;
+ }
+ else
+ {
+ child_height = minimum_requisitions[i] + child->padding * 2;
+
+ if (child->expand)
+ {
+ if (nexpand_children == 1)
+ child_height += available;
+ else
+ child_height += extra;
+
+ nexpand_children -= 1;
+ available -= extra;
+ }
+ }
+
+ if (natural_height > 0)
+ child_height += natural * natural_requisitions[i] / natural_height;
+
+ if (child->fill)
+ {
+ child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
+ child_allocation.y = y + child->padding;
+ }
+ else
+ {
+ child_allocation.height = minimum_requisitions[i];
+ child_allocation.y = y + (child_height - child_allocation.height) / 2;
+ }
- nvis_children -= 1;
- height -= extra;
- }
- else
- {
- child_height = child_requisition.height + child->padding * 2;
+ if (GTK_PACK_END == packing)
+ child_allocation.y -= child_height;
- if (child->expand)
- {
- if (nexpand_children == 1)
- child_height += height;
+ gtk_widget_size_allocate (child->widget, &child_allocation);
+
+ if (GTK_PACK_START == packing)
+ y += child_height + box->spacing;
else
- child_height += extra;
+ y -= child_height + box->spacing;
+ } /* packing */
+
+ ++i;
+ } /* visible */
+ } /* while children */
+ } /* for packing */
+ } /* nvis_children */
+}
- nexpand_children -= 1;
- height -= extra;
- }
- }
+static GtkExtendedLayoutFeatures
+gtk_vbox_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+ return GTK_EXTENDED_LAYOUT_NATURAL_SIZE;
+}
- if (child->fill)
- {
- child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
- child_allocation.y = y + child->padding - child_height;
- }
- else
- {
- child_allocation.height = child_requisition.height;
- child_allocation.y = y + (child_height - child_allocation.height) / 2 - child_height;
- }
+static void
+gtk_vbox_extended_layout_get_natural_size (GtkExtendedLayout *layout,
+ GtkRequisition *requisition)
+{
+ GtkBox *box = GTK_BOX (layout);
- gtk_widget_size_allocate (child->widget, &child_allocation);
+ GtkRequisition child_requisition;
+ GtkBoxChild *child;
+ GList *children;
- y -= (child_height + box->spacing);
- }
+ requisition->width = GTK_CONTAINER (box)->border_width * 2;
+ requisition->height = GTK_CONTAINER (box)->border_width * 2;
+
+ children = box->children;
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ if (GTK_WIDGET_VISIBLE (child->widget))
+ {
+ if (GTK_IS_EXTENDED_LAYOUT (child->widget) &&
+ GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
+ gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (child->widget),
+ &child_requisition);
+ else
+ gtk_widget_size_request (child->widget, &child_requisition);
+
+ requisition->width += MAX (child_requisition.width, requisition->width);
+ requisition->height = child_requisition.height;
}
}
}
+static void
+gtk_vbox_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
+{
+ iface->get_features = gtk_vbox_extended_layout_get_features;
+ iface->get_natural_size = gtk_vbox_extended_layout_get_natural_size;
+}
+
#define __GTK_VBOX_C__
#include "gtkaliasdef.c"
diff --git a/tests/testextendedlayout.c b/tests/testextendedlayout.c
index d2bc53e..d5d3421 100644
--- a/tests/testextendedlayout.c
+++ b/tests/testextendedlayout.c
@@ -214,34 +214,53 @@ test_case_append_guide (TestCase *self,
static void
append_natural_size_box (TestCase *test,
- GtkWidget *vbox,
+ GtkWidget *parent,
+ gboolean vertical,
const gchar *caption,
PangoEllipsizeMode ellipsize)
{
- GtkWidget *hbox;
+ GtkWidget *box;
GtkWidget *button;
GtkWidget *label;
- hbox = gtk_hbox_new (FALSE, 12);
+ box = vertical ?
+ gtk_vbox_new (FALSE, 12):
+ gtk_hbox_new (FALSE, 12);
label = gtk_label_new ("The small Button");
+ gtk_label_set_angle (GTK_LABEL (label), vertical ? 90 : 0);
gtk_label_set_ellipsize (GTK_LABEL (label), ellipsize);
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), label);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
test_case_append_guide (test, button, GUIDE_EXTERIOUR_VERTICAL, 0);
+ test_case_append_guide (test, label, GUIDE_EXTERIOUR_VERTICAL, -1);
+
+ label = gtk_label_new ("The large Button");
+ gtk_label_set_angle (GTK_LABEL (label), vertical ? 90 : 0);
- button = gtk_button_new_with_label ("The large Button");
- gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ button = gtk_button_new ();
+ gtk_container_add (GTK_CONTAINER (button), label);
+ gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
test_case_append_guide (test, button, GUIDE_EXTERIOUR_VERTICAL, 1);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), caption);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+ if (vertical)
+ {
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 1.0);
+ gtk_label_set_angle (GTK_LABEL (label), 90);
+ }
+ else
+ {
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_label_set_angle (GTK_LABEL (label), 0);
+ }
+
+ gtk_box_pack_start (GTK_BOX (parent), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (parent), box, FALSE, TRUE, 0);
}
static gboolean
@@ -298,36 +317,49 @@ shrink_paned (GtkWidget *button,
}
static TestCase*
-create_natural_size_test (TestSuite *suite)
+create_natural_size_test (TestSuite *suite,
+ gboolean vertical)
{
- GtkWidget *vbox, *hint, *button;
+ GtkWidget *box, *hint, *button;
- TestCase *test = test_case_new (suite, "Natural Size", NULL,
- gtk_hpaned_new ());
+ TestCase *test = test_case_new (suite, "Natural Size",
+ vertical ? "GtkVBox" : "GtkHBox",
+ vertical ? gtk_vpaned_new () : gtk_hpaned_new ());
gtk_container_set_border_width (GTK_CONTAINER (test->widget), 6);
- vbox = gtk_vbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
- gtk_paned_pack1 (GTK_PANED (test->widget), vbox, TRUE, TRUE);
+ box = vertical ?
+ gtk_hbox_new (FALSE, 12):
+ gtk_vbox_new (FALSE, 12);
- append_natural_size_box (test, vbox,
+ gtk_container_set_border_width (GTK_CONTAINER (box), 6);
+ gtk_paned_pack1 (GTK_PANED (test->widget), box, TRUE, TRUE);
+
+ append_natural_size_box (test, box, vertical,
"<b>No ellipsizing</b>",
PANGO_ELLIPSIZE_NONE);
- append_natural_size_box (test, vbox,
+ append_natural_size_box (test, box, vertical,
"<b>Ellipsizing at start</b>",
PANGO_ELLIPSIZE_START);
- append_natural_size_box (test, vbox,
+ append_natural_size_box (test, box, vertical,
"<b>Ellipsizing in the middle</b>",
PANGO_ELLIPSIZE_MIDDLE);
- append_natural_size_box (test, vbox,
+ append_natural_size_box (test, box, vertical,
"<b>Ellipsizing at end</b>",
PANGO_ELLIPSIZE_END);
button = gtk_button_new_with_label ("Shrink to check ellipsing");
- gtk_label_set_angle (GTK_LABEL (GTK_BIN (button)->child), -90);
g_signal_connect (button, "clicked", G_CALLBACK (shrink_paned), test->widget);
- hint = gtk_alignment_new (1.0, 0.5, 0.0, 1.0);
+ if (vertical)
+ {
+ hint = gtk_alignment_new (0.5, 1.0, 1.0, 0.0);
+ }
+ else
+ {
+ hint = gtk_alignment_new (1.0, 0.5, 0.0, 1.0);
+ gtk_label_set_angle (GTK_LABEL (GTK_BIN (button)->child), -90);
+ }
+
gtk_container_set_border_width (GTK_CONTAINER (hint), 6);
gtk_container_add (GTK_CONTAINER (hint), button);
gtk_paned_pack2 (GTK_PANED (test->widget), hint, FALSE, FALSE);
@@ -1418,11 +1450,13 @@ update_status (TestSuite *suite,
g_string_append_printf (status, " (%s)", widget_name);
g_string_append_printf (status,
- ":\npos=%dx%d; size=%dx%d",
+ ":\npos=%dx%d; size=%dx%d req=%dx%d",
child->allocation.x,
child->allocation.y,
child->allocation.width,
- child->allocation.height);
+ child->allocation.height,
+ child->requisition.width,
+ child->requisition.height);
if (GTK_IS_EXTENDED_LAYOUT (child))
{
@@ -1694,7 +1728,8 @@ test_suite_new ()
TestSuite* self = g_new0 (TestSuite, 1);
test_suite_setup_ui (self);
- test_suite_append (self, create_natural_size_test (self));
+ test_suite_append (self, create_natural_size_test (self, FALSE));
+ test_suite_append (self, create_natural_size_test (self, TRUE));
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));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]