Consider natural size to allocate widgets spanning a single, rename

2007-07-24  Mathias Hasselmann  <mathias.hasselmann@gmx.de>

	* gtk/gtktable.c, gtk/gtktable.h: Consider natural size to allocate
	widgets spanning a single, rename GtkTableRowCol::natural_size.
	Remove some lost g_print statements.
	* tests/testextendedlayout.c: Test natural size allocation in
	GtkTable for simple cases.

svn path=/branches/extended-layout/; revision=18532
This commit is contained in:
Mathias Hasselmann
2007-07-23 22:28:44 +00:00
committed by Mathias Hasselmann
parent ea485139bf
commit d601bce003
4 changed files with 148 additions and 71 deletions

View File

@@ -1,3 +1,11 @@
2007-07-24 Mathias Hasselmann <mathias.hasselmann@gmx.de>
* gtk/gtktable.c, gtk/gtktable.h: Consider natural size to allocate
widgets spanning a single, rename GtkTableRowCol::natural_size.
Remove some lost g_print statements.
* tests/testextendedlayout.c: Test natural size allocation in
GtkTable for simple cases.
2007-07-23 Mathias Hasselmann <mathias.hasselmann@gmx.de>
* gtk/gtktable.c, gtk/gtktable.h: Provide natural size information.

View File

@@ -947,13 +947,13 @@ gtk_table_size_request_init (GtkTable *table)
for (row = 0; row < table->nrows; row++)
{
table->rows[row].requisition = 0;
table->rows[row].natural_size = 0;
table->rows[row].natural = 0;
table->rows[row].expand = FALSE;
}
for (col = 0; col < table->ncols; col++)
{
table->cols[col].requisition = 0;
table->cols[col].natural_size = 0;
table->cols[col].natural = 0;
table->cols[col].expand = FALSE;
}
@@ -1007,8 +1007,7 @@ gtk_table_size_request_pass1 (GtkTable *table)
table->cols[child->left_attach].requisition = MAX (table->cols[child->left_attach].requisition, width);
width = child_natural_size.width + child->xpadding * 2;
if (GTK_IS_LABEL (child->widget))
table->cols[child->left_attach].natural_size = MAX (table->cols[child->left_attach].natural_size, width);
table->cols[child->left_attach].natural = MAX (table->cols[child->left_attach].natural, width);
}
/* Child spans a single row.
@@ -1019,7 +1018,7 @@ if (GTK_IS_LABEL (child->widget))
table->rows[child->top_attach].requisition = MAX (table->rows[child->top_attach].requisition, height);
height = child_natural_size.height + child->ypadding * 2;
table->rows[child->top_attach].natural_size = MAX (table->rows[child->top_attach].natural_size, height);
table->rows[child->top_attach].natural = MAX (table->rows[child->top_attach].natural, height);
}
}
}
@@ -1066,14 +1065,25 @@ gtk_table_size_request_pass3 (GtkTable *table)
if (GTK_WIDGET_VISIBLE (child->widget))
{
GtkRequisition child_natural_size;
GtkRequisition child_requisition;
if (child->left_attach != (child->right_attach - 1) ||
child->top_attach != (child->bottom_attach - 1))
{
gtk_widget_get_child_requisition (child->widget, &child_requisition);
if (GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (child->widget),
&child_natural_size);
else
child_natural_size = child_requisition;
}
/* Child spans multiple columns.
*/
if (child->left_attach != (child->right_attach - 1))
{
GtkRequisition child_requisition;
gtk_widget_get_child_requisition (child->widget, &child_requisition);
/* Check and see if there is already enough space
* for the child.
*/
@@ -1115,16 +1125,14 @@ gtk_table_size_request_pass3 (GtkTable *table)
n_expand--;
}
}
g_debug ("%s: TODO: consider natural size", G_STRFUNC);
}
/* Child spans multiple rows.
*/
if (child->top_attach != (child->bottom_attach - 1))
{
GtkRequisition child_requisition;
gtk_widget_get_child_requisition (child->widget, &child_requisition);
/* Check and see if there is already enough space
* for the child.
*/
@@ -1168,6 +1176,8 @@ gtk_table_size_request_pass3 (GtkTable *table)
n_expand--;
}
}
g_debug ("%s: TODO: consider natural size", G_STRFUNC);
}
}
}
@@ -1373,10 +1383,13 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
gint real_width;
gint real_height;
gint width, height;
gint natural_delta;
gint natural_size;
gint row, col;
gint nexpand;
gint nshrink;
gint extra;
gint delta;
/* If we were allocated more space than we requested
* then we have to expand any expandable rows and columns
@@ -1419,14 +1432,20 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
width = 0;
nexpand = 0;
nshrink = 0;
natural_delta = 0;
for (col = 0; col < table->ncols; col++)
{
width += table->cols[col].requisition;
delta = table->cols[col].natural - table->cols[col].requisition;
if (table->cols[col].expand)
nexpand += 1;
if (table->cols[col].shrink)
nshrink += 1;
if (delta > 0)
natural_delta += delta;
}
for (col = 0; col + 1 < table->ncols; col++)
width += table->cols[col].spacing;
@@ -1436,16 +1455,27 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
if ((width < real_width) && (nexpand >= 1))
{
width = real_width - width;
natural_size = MIN (natural_delta, width);
width = MAX (0, width - natural_size);
for (col = 0; col < table->ncols; col++)
if (table->cols[col].expand)
{
extra = width / nexpand;
table->cols[col].allocation += extra;
width -= extra;
nexpand -= 1;
}
{
if (natural_size)
{
delta = table->cols[col].natural - table->cols[col].requisition;
delta = natural_size * delta / natural_delta;
table->cols[col].allocation += delta;
}
if (table->cols[col].expand)
{
extra = width / nexpand;
table->cols[col].allocation += extra;
width -= extra;
nexpand -= 1;
}
}
}
/* Check to see if we were allocated less width than we requested,
@@ -1516,10 +1546,14 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
for (row = 0; row < table->nrows; row++)
{
height += table->rows[row].requisition;
delta = table->rows[row].natural - table->rows[row].requisition;
if (table->rows[row].expand)
nexpand += 1;
if (table->rows[row].shrink)
nshrink += 1;
if (table->rows[row].natural > table->rows[row].requisition)
natural_delta += delta;
}
for (row = 0; row + 1 < table->nrows; row++)
height += table->rows[row].spacing;
@@ -1529,16 +1563,27 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
if ((height < real_height) && (nexpand >= 1))
{
height = real_height - height;
natural_size = MIN (natural_delta, height);
height = MAX (0, height - natural_size);
for (row = 0; row < table->nrows; row++)
if (table->rows[row].expand)
{
extra = height / nexpand;
table->rows[row].allocation += extra;
height -= extra;
nexpand -= 1;
}
{
if (natural_size)
{
delta = table->rows[row].natural - table->rows[row].requisition;
delta = natural_size * delta / natural_delta;
table->rows[row].allocation += delta;
}
if (table->rows[row].expand)
{
extra = height / nexpand;
table->rows[row].allocation += extra;
height -= extra;
nexpand -= 1;
}
}
}
/* Check to see if we were allocated less height than we requested.
@@ -1678,15 +1723,9 @@ gtk_table_extended_layout_get_natural_size (GtkExtendedLayout *layout,
height = 0;
for (i = 0; i < table->ncols; i++)
{
width += table->cols[i].natural_size;
g_print ("%s: cols[%d].natural_size: %d\n", G_STRFUNC, i, table->cols[i].natural_size);
}
width += table->cols[i].natural;
for (i = 0; i < table->nrows; i++)
{
height += table->rows[i].natural_size;
g_print ("%s: rows[%d].natural_size: %d\n", G_STRFUNC, i, table->rows[i].natural_size);
}
height += table->rows[i].natural;
requisition->width = width;
requisition->height = height;

View File

@@ -93,7 +93,7 @@ struct _GtkTableRowCol
guint expand : 1;
guint shrink : 1;
guint empty : 1;
guint16 natural_size;
guint16 natural;
};

View File

@@ -216,16 +216,24 @@ static void
append_natural_size_box (TestCase *test,
GtkWidget *parent,
gboolean vertical,
gboolean table,
const gchar *caption,
PangoEllipsizeMode ellipsize)
{
GtkWidget *box;
GtkWidget *container;
GtkWidget *button;
GtkWidget *label;
box = vertical ?
gtk_vbox_new (FALSE, 12):
gtk_hbox_new (FALSE, 12);
if (table)
{
container = gtk_table_new (vertical ? 2 : 1, vertical ? 1 : 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (container), 12);
gtk_table_set_row_spacings (GTK_TABLE (container), 12);
}
else if (vertical)
container = gtk_vbox_new (FALSE, 12);
else
container = gtk_hbox_new (FALSE, 12);
label = gtk_label_new ("The small Button");
gtk_label_set_angle (GTK_LABEL (label), vertical ? 90 : 0);
@@ -233,7 +241,12 @@ append_natural_size_box (TestCase *test,
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), label);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
if (table)
gtk_table_attach (GTK_TABLE (container), button, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
else
gtk_box_pack_start (GTK_BOX (container), button, FALSE, TRUE, 0);
test_case_append_guide (test, button, GUIDE_EXTERIOUR_VERTICAL, 0);
test_case_append_guide (test, label, GUIDE_EXTERIOUR_VERTICAL, -1);
@@ -242,7 +255,17 @@ append_natural_size_box (TestCase *test,
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), label);
gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
if (table)
gtk_table_attach (GTK_TABLE (container), button,
vertical ? 0 : 1, vertical ? 1 : 2,
vertical ? 1 : 0, vertical ? 2 : 1,
vertical ? GTK_FILL : GTK_FILL | GTK_EXPAND,
vertical ? GTK_FILL | GTK_EXPAND : GTK_FILL,
0, 0);
else
gtk_box_pack_start (GTK_BOX (container), button, TRUE, TRUE, 0);
test_case_append_guide (test, button, GUIDE_EXTERIOUR_VERTICAL, 1);
label = gtk_label_new (NULL);
@@ -260,7 +283,7 @@ append_natural_size_box (TestCase *test,
}
gtk_box_pack_start (GTK_BOX (parent), label, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (parent), box, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (parent), container, FALSE, TRUE, 0);
}
static gboolean
@@ -318,47 +341,52 @@ shrink_paned (GtkWidget *button,
static TestCase*
create_natural_size_test (TestSuite *suite,
gboolean vertical)
gboolean vertical,
gboolean table)
{
GtkWidget *box, *hint, *button;
GtkWidget *box, *paned, *hint, *button;
const gchar *detail;
TestCase *test;
TestCase *test = test_case_new (suite, "Natural Size",
vertical ? "GtkVBox" : "GtkHBox",
vertical ? gtk_vpaned_new () : gtk_hpaned_new ());
if (vertical)
{
detail = table ? "GtkTable, vertical" : "GtkVBox";
hint = gtk_alignment_new (0.5, 1.0, 1.0, 0.0);
box = gtk_hbox_new (FALSE, 12);
paned = gtk_vpaned_new ();
}
else
{
detail = table ? "GtkTable, horizontal" : "GtkHBox";
hint = gtk_alignment_new (1.0, 0.5, 0.0, 1.0);
box = gtk_vbox_new (FALSE, 12);
paned = gtk_hpaned_new ();
}
test = test_case_new (suite, "Natural Size", detail, paned);
gtk_container_set_border_width (GTK_CONTAINER (test->widget), 6);
box = vertical ?
gtk_hbox_new (FALSE, 12):
gtk_vbox_new (FALSE, 12);
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,
append_natural_size_box (test, box, vertical, table,
"<b>No ellipsizing</b>",
PANGO_ELLIPSIZE_NONE);
append_natural_size_box (test, box, vertical,
append_natural_size_box (test, box, vertical, table,
"<b>Ellipsizing at start</b>",
PANGO_ELLIPSIZE_START);
append_natural_size_box (test, box, vertical,
append_natural_size_box (test, box, vertical, table,
"<b>Ellipsizing in the middle</b>",
PANGO_ELLIPSIZE_MIDDLE);
append_natural_size_box (test, box, vertical,
append_natural_size_box (test, box, vertical, table,
"<b>Ellipsizing at end</b>",
PANGO_ELLIPSIZE_END);
button = gtk_button_new_with_label ("Shrink to check ellipsing");
g_signal_connect (button, "clicked", G_CALLBACK (shrink_paned), test->widget);
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);
}
if (!vertical)
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);
@@ -1728,8 +1756,10 @@ test_suite_new ()
TestSuite* self = g_new0 (TestSuite, 1);
test_suite_setup_ui (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_natural_size_test (self, FALSE, FALSE));
test_suite_append (self, create_natural_size_test (self, TRUE, FALSE));
test_suite_append (self, create_natural_size_test (self, FALSE, TRUE));
test_suite_append (self, create_natural_size_test (self, TRUE, 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));