[gtk+/grid-widget: 7/20] Implement get_preferred_width/height
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/grid-widget: 7/20] Implement get_preferred_width/height
- Date: Fri, 15 Oct 2010 00:05:20 +0000 (UTC)
commit f55b95150fc603c28b40e4da78a07d8e71cd2cc5
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Oct 6 11:38:23 2010 -0400
Implement get_preferred_width/height
gtk/gtkgrid.c | 284 +++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 197 insertions(+), 87 deletions(-)
---
diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c
index 1828746..e7c348c 100644
--- a/gtk/gtkgrid.c
+++ b/gtk/gtkgrid.c
@@ -48,8 +48,9 @@ struct _GtkGridChild
struct _GtkGridRowCol
{
- guint requisition;
- guint allocation;
+ gint minimum;
+ gint natural;
+ gint allocation;
gboolean need_expand;
gboolean expand;
gboolean empty;
@@ -551,13 +552,15 @@ gtk_grid_size_request_init (GtkGrid *grid)
for (i = 0; i < priv->max_row - priv->min_row; i++)
{
- priv->rows[i].requisition = 0;
+ priv->rows[i].minimum = 0;
+ priv->rows[i].natural = 0;
priv->rows[i].expand = FALSE;
}
for (i = 0; i < priv->max_column - priv->min_column; i++)
{
- priv->columns[i].requisition = 0;
+ priv->columns[i].minimum = 0;
+ priv->columns[i].natural = 0;
priv->columns[i].expand = FALSE;
}
@@ -583,8 +586,7 @@ gtk_grid_size_request_pass1 (GtkGrid *grid)
GtkGridPrivate *priv = grid->priv;
GtkGridChild *child;
GList *list;
- gint width;
- gint height;
+ GtkRequisition minimum, natural;
for (list = priv->children; list; list = list->next)
{
@@ -593,22 +595,20 @@ gtk_grid_size_request_pass1 (GtkGrid *grid)
if (!gtk_widget_get_visible (child->widget))
continue;
- GtkRequisition child_requisition;
-
- gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
+ gtk_widget_get_preferred_size (child->widget, &minimum, &natural);
/* Child spans a single column. */
if (child->width == 1)
{
- width = child_requisition.width;
- priv->columns[child->left - priv->min_column].requisition = MAX (priv->columns[child->left - priv->min_column].requisition, width);
+ priv->columns[child->left - priv->min_column].minimum = MAX (priv->columns[child->left - priv->min_column].minimum, minimum.width);
+ priv->columns[child->left - priv->min_column].natural = MAX (priv->columns[child->left - priv->min_column].natural, natural.width);
}
/* Child spans a single row. */
if (child->height == 1)
{
- height = child_requisition.height;
- priv->rows[child->top - priv->min_row].requisition = MAX (priv->rows[child->top - priv->min_row].requisition, height);
+ priv->rows[child->top - priv->min_row].minimum = MAX (priv->rows[child->top - priv->min_row].minimum, minimum.height);
+ priv->rows[child->top - priv->min_row].natural = MAX (priv->rows[child->top - priv->min_row].natural, natural.height);
}
}
}
@@ -618,29 +618,43 @@ static void
gtk_grid_size_request_pass2 (GtkGrid *grid)
{
GtkGridPrivate *priv = grid->priv;
- gint size;
+ gint minimum, natural;
gint i;
if (priv->row_homogeneous)
{
- size = 0;
+ minimum = 0;
+ natural = 0;
for (i = 0; i < priv->max_row - priv->min_row; i++)
- size = MAX (size, priv->rows[i].requisition);
+ {
+ minimum = MAX (minimum, priv->rows[i].minimum);
+ natural = MAX (natural, priv->rows[i].natural);
+ }
for (i = 0; i < priv->max_row - priv->min_row; i++)
- priv->rows[i].requisition = size;
+ {
+ priv->rows[i].minimum = minimum;
+ priv->rows[i].natural = natural;
+ }
}
if (priv->column_homogeneous)
{
- size = 0;
+ minimum = 0;
+ natural = 0;
for (i = 0; i < priv->max_column - priv->min_column; i++)
- size = MAX (size, priv->columns[i].requisition);
+ {
+ minimum = MAX (minimum, priv->columns[i].minimum);
+ natural = MAX (natural, priv->columns[i].natural);
+ }
for (i = 0; i < priv->max_column - priv->min_column; i++)
- priv->columns[i].requisition = size;
+ {
+ priv->columns[i].minimum = minimum;
+ priv->columns[i].natural = natural;
+ }
}
}
@@ -651,13 +665,13 @@ gtk_grid_size_request_pass3 (GtkGrid *grid)
GtkGridPrivate *priv = grid->priv;
GList *list;
GtkGridChild *child;
- GtkRequisition child_requisition;
+ GtkRequisition child_minimum, child_natural;
gint expand;
gboolean force;
gint i;
gint row, col;
gint extra;
- gint width, height;
+ gint minimum, natural;
for (list = priv->children; list; list = list->next)
{
@@ -666,17 +680,26 @@ gtk_grid_size_request_pass3 (GtkGrid *grid)
if (!gtk_widget_get_visible (child->widget))
continue;
+ if (child->width > 1 || child->height > 1)
+ gtk_widget_get_preferred_size (child->widget,
+ &child_minimum,
+ &child_natural);
+
if (child->width > 1)
{
- gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
- width = 0;
+ minimum = 0;
+ natural = 0;
expand = 0;
for (i = 0; i < child->width; i++)
{
col = child->left - priv->min_column + i;
- width += priv->columns[col].requisition;
+ minimum += priv->columns[col].minimum;
+ natural += priv->columns[col].natural;
if (i > 0)
- width += priv->column_spacing;
+ {
+ minimum += priv->column_spacing;
+ natural += priv->column_spacing;
+ }
if (priv->columns[col].expand)
expand += 1;
}
@@ -685,40 +708,66 @@ gtk_grid_size_request_pass3 (GtkGrid *grid)
* its requisition, then divide up the needed space amongst the
* columns it spans, favoring expandable columns if any.
*/
- if (width < child_requisition.width)
- {
- force = FALSE;
- width = child_requisition.width - width;
- if (expand == 0)
- {
- expand = child->width;
- force = TRUE;
- }
- for (i = 0; i < child->width; i++)
- {
- col = child->left - priv->min_column + i;
- if (force || priv->columns[col].expand)
- {
- extra = width / expand;
- priv->columns[col].requisition += extra;
- width -= extra;
- expand -= 1;
- }
- }
- }
+ if (minimum < child_minimum.width)
+ {
+ force = FALSE;
+ minimum = child_minimum.width - minimum;
+ if (expand == 0)
+ {
+ expand = child->width;
+ force = TRUE;
+ }
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ if (force || priv->columns[col].expand)
+ {
+ extra = minimum / expand;
+ priv->columns[col].minimum += extra;
+ minimum -= extra;
+ expand -= 1;
+ }
+ }
+ }
+
+ if (natural < child_natural.width)
+ {
+ force = FALSE;
+ natural = child_natural.width - natural;
+ if (expand == 0)
+ {
+ expand = child->width;
+ force = TRUE;
+ }
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ if (force || priv->columns[col].expand)
+ {
+ extra = natural / expand;
+ priv->columns[col].natural += extra;
+ natural -= extra;
+ expand -= 1;
+ }
+ }
+ }
}
if (child->height > 1)
{
- gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
- height = 0;
+ minimum = 0;
+ natural = 0;
expand = 0;
for (i = 0; i < child->height; i++)
{
row = child->top - priv->min_row + i;
- height += priv->rows[row].requisition;
+ minimum += priv->rows[row].minimum;
+ natural += priv->rows[row].natural;
if (i > 0)
- height += priv->row_spacing;
+ {
+ minimum += priv->row_spacing;
+ natural += priv->row_spacing;
+ }
if (priv->rows[row].expand)
expand += 1;
}
@@ -727,38 +776,62 @@ gtk_grid_size_request_pass3 (GtkGrid *grid)
* its requisition, then divide up the needed space amongst the
* columns it spans, favoring expandable columns if any.
*/
- if (height < child_requisition.height)
- {
- force = FALSE;
- height = child_requisition.height - height;
- if (expand == 0)
- {
- expand = child->height;
- force = TRUE;
- }
- for (i = 0; i < child->height; i++)
- {
- row = child->top - priv->min_row + i;
- if (force || priv->rows[row].expand)
- {
- extra = height / expand;
- priv->rows[row].requisition += extra;
- height -= extra;
- expand -= 1;
- }
- }
- }
+ if (minimum < child_minimum.height)
+ {
+ force = FALSE;
+ minimum = child_minimum.height - minimum;
+ if (expand == 0)
+ {
+ expand = child->height;
+ force = TRUE;
+ }
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ if (force || priv->rows[row].expand)
+ {
+ extra = minimum / expand;
+ priv->rows[row].minimum += extra;
+ minimum -= extra;
+ expand -= 1;
+ }
+ }
+ }
+
+ if (natural < child_natural.height)
+ {
+ force = FALSE;
+ natural = child_natural.height - natural;
+ if (expand == 0)
+ {
+ expand = child->height;
+ force = TRUE;
+ }
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ if (force || priv->rows[row].expand)
+ {
+ extra = natural / expand;
+ priv->rows[row].natural += extra;
+ natural -= extra;
+ expand -= 1;
+ }
+ }
+ }
}
}
}
static void
-gtk_grid_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
+gtk_grid_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
{
GtkGrid *grid = GTK_GRID (widget);
GtkGridPrivate *priv = grid->priv;
- gint row, col;
+ gint col;
+ gint minimum, natural;
gtk_grid_allocate_rowcols (grid);
@@ -768,23 +841,59 @@ gtk_grid_size_request (GtkWidget *widget,
gtk_grid_size_request_pass3 (grid);
gtk_grid_size_request_pass2 (grid);
- requisition->width = priv->columns[0].requisition;
+ minimum = priv->columns[0].minimum;
+ natural = priv->columns[0].natural;
for (col = 1; col < priv->max_column - priv->min_column; col++)
{
- requisition->width += priv->column_spacing;
- requisition->width += priv->columns[col].requisition;
+ minimum += priv->column_spacing;
+ minimum += priv->columns[col].minimum;
+ natural += priv->column_spacing;
+ natural += priv->columns[col].natural;
}
- requisition->height = priv->rows[0].requisition;
+ if (minimum_width)
+ *minimum_width = minimum;
+
+ if (natural_width)
+ *natural_width = natural;
+}
+
+static void
+gtk_grid_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkGrid *grid = GTK_GRID (widget);
+ GtkGridPrivate *priv = grid->priv;
+ gint row;
+ gint minimum, natural;
+
+ gtk_grid_allocate_rowcols (grid);
+
+ gtk_grid_size_request_init (grid);
+ gtk_grid_size_request_pass1 (grid);
+ gtk_grid_size_request_pass2 (grid);
+ gtk_grid_size_request_pass3 (grid);
+ gtk_grid_size_request_pass2 (grid);
+
+ minimum = priv->rows[0].minimum;
+ natural = priv->rows[0].natural;
for (row = 1; row < priv->max_row - priv->min_row; row++)
{
- requisition->height += priv->row_spacing;
- requisition->height += priv->rows[row].requisition;
+ minimum += priv->row_spacing;
+ minimum += priv->rows[row].minimum;
+ natural += priv->row_spacing;
+ natural += priv->rows[row].natural;
}
-}
+ if (minimum_height)
+ *minimum_height = minimum;
+
+ if (natural_height)
+ *natural_height = natural;
+}
static void
gtk_grid_size_allocate_init (GtkGrid *grid)
{
@@ -798,7 +907,7 @@ gtk_grid_size_allocate_init (GtkGrid *grid)
for (col = 0; col < priv->max_column - priv->min_column; col++)
{
- priv->columns[col].allocation = priv->columns[col].requisition;
+ priv->columns[col].allocation = priv->columns[col].minimum;
priv->columns[col].need_expand = FALSE;
priv->columns[col].expand = FALSE;
priv->columns[col].empty = TRUE;
@@ -806,7 +915,7 @@ gtk_grid_size_allocate_init (GtkGrid *grid)
for (row = 0; row < priv->max_row - priv->min_row; row++)
{
- priv->rows[row].allocation = priv->rows[row].requisition;
+ priv->rows[row].allocation = priv->rows[row].minimum;
priv->rows[row].need_expand = FALSE;
priv->rows[row].expand = FALSE;
priv->rows[row].empty = TRUE;
@@ -963,7 +1072,7 @@ gtk_grid_size_allocate_pass1 (GtkGrid *grid)
nonempty = 0;
for (col = 0; col < priv->max_column - priv->min_column; col++)
{
- width += priv->columns[col].requisition;
+ width += priv->columns[col].minimum;
if (!priv->columns[col].empty)
nonempty += 1;
if (priv->columns[col].expand)
@@ -1014,7 +1123,7 @@ gtk_grid_size_allocate_pass1 (GtkGrid *grid)
nonempty = 0;
for (row = 0; row < priv->max_row - priv->min_row; row++)
{
- height += priv->rows[row].requisition;
+ height += priv->rows[row].minimum;
if (!priv->rows[row].empty)
nonempty += 1;
if (priv->rows[row].expand)
@@ -1135,7 +1244,8 @@ gtk_grid_class_init (GtkGridClass *class)
object_class->get_property = gtk_grid_get_property;
object_class->set_property = gtk_grid_set_property;
- widget_class->size_request = gtk_grid_size_request;
+ widget_class->get_preferred_width = gtk_grid_get_preferred_width;
+ widget_class->get_preferred_height = gtk_grid_get_preferred_height;
widget_class->size_allocate = gtk_grid_size_allocate;
container_class->add = gtk_grid_add;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]