[gtk+/grid-widget: 5/20] More work
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/grid-widget: 5/20] More work
- Date: Fri, 15 Oct 2010 00:05:10 +0000 (UTC)
commit 32cb9951c5295ab14fc1c9e9c82310bd3efb8351
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Oct 6 01:53:39 2010 -0400
More work
Make it actually build.
Implement GtkOrientable.
gtk/gtkgrid.c | 729 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 641 insertions(+), 88 deletions(-)
---
diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c
index ba8af15..1828746 100644
--- a/gtk/gtkgrid.c
+++ b/gtk/gtkgrid.c
@@ -1,7 +1,6 @@
/* TODO
- * - size allocation
* - wfh
- * - orientable
+ * - magic expand
*/
/* GTK - The GIMP Toolkit
@@ -27,6 +26,8 @@
#include "config.h"
#include "gtkgrid.h"
+
+#include "gtkorientable.h"
#include "gtkprivate.h"
#include "gtkintl.h"
@@ -49,7 +50,9 @@ struct _GtkGridRowCol
{
guint requisition;
guint allocation;
+ gboolean need_expand;
gboolean expand;
+ gboolean empty;
};
struct _GtkGridPrivate
@@ -66,6 +69,8 @@ struct _GtkGridPrivate
gint16 row_spacing;
gint16 column_spacing;
+ GtkOrientation orientation;
+
guint row_homogeneous : 1;
guint column_homogeneous : 1;
};
@@ -73,6 +78,7 @@ struct _GtkGridPrivate
enum
{
PROP_0,
+ PROP_ORIENTATION,
PROP_ROW_SPACING,
PROP_COLUMN_SPACING,
PROP_ROW_HOMOGENEOUS,
@@ -85,10 +91,13 @@ enum
CHILD_PROP_LEFT_ATTACH,
CHILD_PROP_TOP_ATTACH,
CHILD_PROP_WIDTH,
- CHILD_PROP_HEIGHT
+ CHILD_PROP_HEIGHT,
+ CHILD_PROP_HEXPAND,
+ CHILD_PROP_VEXPAND
};
-G_DEFINE_TYPE (GtkGrid, gtk_grid, GTK_TYPE_CONTAINER);
+G_DEFINE_TYPE_WITH_CODE (GtkGrid, gtk_grid, GTK_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
static void
gtk_grid_finalize (GObject *object)
@@ -97,7 +106,7 @@ gtk_grid_finalize (GObject *object)
GtkGridPrivate *priv = grid->priv;
g_free (priv->rows);
- g_free (priv->cols);
+ g_free (priv->columns);
G_OBJECT_CLASS (gtk_grid_parent_class)->finalize (object);
}
@@ -113,6 +122,10 @@ gtk_grid_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, priv->orientation);
+ break;
+
case PROP_ROW_SPACING:
g_value_set_int (value, priv->row_spacing);
break;
@@ -136,6 +149,66 @@ gtk_grid_get_property (GObject *object,
}
static void
+gtk_grid_resize (GtkGrid *grid)
+{
+ GtkGridPrivate *priv = grid->priv;
+
+ g_free (priv->rows);
+ g_free (priv->columns);
+ priv->rows = NULL;
+ priv->columns = NULL;
+}
+
+static void
+gtk_grid_set_orientation (GtkGrid *grid,
+ GtkOrientation orientation)
+{
+ GtkGridPrivate *priv = grid->priv;
+ GList *list;
+ GtkGridChild *child;
+ gint left, top, width, height;
+
+ if (priv->orientation != orientation)
+ {
+ priv->orientation = orientation;
+
+ g_object_notify (G_OBJECT (grid), "orientation");
+
+ for (list = priv->children; list; list = list->next)
+ {
+ child = list->data;
+
+ left = child->left;
+ top = child->top;
+ width = child->width;
+ height = child->height;
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ child->top = left;
+ child->left = - (top + height);
+ child->width = height;
+ child->height = width;
+ }
+ else
+ {
+ child->left = top;
+ child->top = - (left + width);
+ child->width = height;
+ child->height = width;
+ }
+ gtk_widget_child_notify (child->widget, "left");
+ gtk_widget_child_notify (child->widget, "top");
+ gtk_widget_child_notify (child->widget, "width");
+ gtk_widget_child_notify (child->widget, "height");
+ }
+
+ gtk_grid_resize (grid);
+ gtk_widget_queue_resize (GTK_WIDGET (grid));
+ }
+}
+
+static void
gtk_grid_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -145,6 +218,10 @@ gtk_grid_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_ORIENTATION:
+ gtk_grid_set_orientation (grid, g_value_get_enum (value));
+ break;
+
case PROP_ROW_SPACING:
gtk_grid_set_row_spacing (grid, g_value_get_int (value));
break;
@@ -222,6 +299,14 @@ gtk_grid_get_child_property (GtkContainer *container,
g_value_set_int (value, grid_child->height);
break;
+ case CHILD_PROP_HEXPAND:
+ g_value_set_boolean (value, grid_child->hexpand);
+ break;
+
+ case CHILD_PROP_VEXPAND:
+ g_value_set_boolean (value, grid_child->vexpand);
+ break;
+
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
@@ -229,17 +314,6 @@ gtk_grid_get_child_property (GtkContainer *container,
}
static void
-gtk_grid_resize (GtkGrid *grid)
-{
- GtkGridPrivate *priv = grid->priv;
-
- g_free (priv->rows);
- g_free (priv->cols);
- priv->rows = NULL;
- priv->cols = NULL;
-}
-
-static void
gtk_grid_set_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
@@ -247,9 +321,7 @@ gtk_grid_set_child_property (GtkContainer *container,
GParamSpec *pspec)
{
GtkGrid *grid = GTK_GRID (container);
- GtkGridPrivate *priv = grid->priv;
GtkGridChild *grid_child;
- gint right, bottom;
grid_child = find_grid_child (grid, child);
@@ -281,6 +353,16 @@ gtk_grid_set_child_property (GtkContainer *container,
gtk_grid_resize (grid);
break;
+ case CHILD_PROP_HEXPAND:
+ grid_child->hexpand = g_value_get_boolean (value);
+ gtk_widget_queue_resize (GTK_WIDGET (grid));
+ break;
+
+ case CHILD_PROP_VEXPAND:
+ grid_child->vexpand = g_value_get_boolean (value);
+ gtk_widget_queue_resize (GTK_WIDGET (grid));
+ break;
+
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
@@ -313,6 +395,7 @@ gtk_grid_init (GtkGrid *grid)
priv->column_spacing = 0;
priv->row_homogeneous = FALSE;
priv->column_homogeneous = FALSE;
+ priv->orientation = GTK_ORIENTATION_HORIZONTAL;
}
static void grid_attach (GtkGrid *grid,
@@ -330,19 +413,35 @@ gtk_grid_add (GtkContainer *container,
GtkGridPrivate *priv = grid->priv;
GtkGridChild *grid_child;
GList *list;
- gint right;
+ gint left, top;
- /* stack horizontally */
- right = 0;
- for (list = priv->children; list; list = list->next)
+ left = 0;
+ top = 0;
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- grid_child = list->data;
+ /* stack horizontally */
+ for (list = priv->children; list; list = list->next)
+ {
+ grid_child = list->data;
- if (grid_child->top <= 0 && grid_child->top + grid_child->height > 0)
- right = MAX (right, grid_child->left + grid_child->width);
+ if (grid_child->top <= 0 && grid_child->top + grid_child->height > 0)
+ left = MAX (left, grid_child->left + grid_child->width);
+ }
}
+ else
+ {
+ /* stack vertically */
+ for (list = priv->children; list; list = list->next)
+ {
+ grid_child = list->data;
- grid_attach (grid, child, right, 0, 1, 1);
+ if (grid_child->left <= 0 && grid_child->left + grid_child->width > 0)
+ top = MAX (top, grid_child->top + grid_child->height);
+ }
+ }
+
+ grid_attach (grid, child, left, top, 1, 1);
}
static void
@@ -408,7 +507,7 @@ gtk_grid_allocate_rowcols (GtkGrid *grid)
GList *list;
gint minrow, maxrow, mincol, maxcol;
- if (priv->rows && priv->cols)
+ if (priv->rows && priv->columns)
return;
minrow = mincol = G_MAXINT;
@@ -439,12 +538,15 @@ gtk_grid_allocate_rowcols (GtkGrid *grid)
priv->columns = g_new (GtkGridRowCol, maxcol - mincol);
}
+/* set requisitions to 0, mark rows/cols as expand
+ * if they have a non-spanning exanding child
+ */
static void
gtk_grid_size_request_init (GtkGrid *grid)
{
GtkGridPrivate *priv = grid->priv;
GtkGridChild *grid_child;
- GtkList *list;
+ GList *list;
gint i;
for (i = 0; i < priv->max_row - priv->min_row; i++)
@@ -455,28 +557,28 @@ gtk_grid_size_request_init (GtkGrid *grid)
for (i = 0; i < priv->max_column - priv->min_column; i++)
{
- priv->cols[i].requisition = 0;
- priv->cols[i].expand = FALSE;
+ priv->columns[i].requisition = 0;
+ priv->columns[i].expand = FALSE;
}
for (list = priv->children; list; list = list->next)
{
- grid_child = children->data;
+ grid_child = list->data;
if (gtk_widget_get_visible (grid_child->widget))
- gtk_size_request_get_size (GTK_SIZE_REQUEST (grid_child->widget),
- NULL, NULL);
+ gtk_widget_get_preferred_size (grid_child->widget, NULL, NULL);
if (grid_child->width == 1 && grid_child->hexpand)
- priv->cols[grid_child->left - priv->min_column].expand = TRUE;
+ priv->columns[grid_child->left - priv->min_column].expand = TRUE;
- if (grid_child->height && child->vexpand)
+ if (grid_child->height == 1 && grid_child->vexpand)
priv->rows[grid_child->top - priv->min_row].expand = TRUE;
}
}
+/* set requisition to max of non-spanning children */
static void
-gtk_table_size_request_pass1 (GtkGrid *grid)
+gtk_grid_size_request_pass1 (GtkGrid *grid)
{
GtkGridPrivate *priv = grid->priv;
GtkGridChild *child;
@@ -488,30 +590,30 @@ gtk_table_size_request_pass1 (GtkGrid *grid)
{
child = list->data;
- if (gtk_widget_get_visible (child->widget))
- {
- GtkRequisition child_requisition;
+ if (!gtk_widget_get_visible (child->widget))
+ continue;
- gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
- &child_requisition, NULL);
+ GtkRequisition child_requisition;
- /* Child spans a single column. */
- if (child->width == 1)
- {
- width = child_requisition.width;
- priv->cols[child->left - priv->min_column].requisition = MAX (priv->cols[child->left - priv->min_column].requisition, width);
- }
+ gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
- /* 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);
- }
+ /* 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);
+ }
+
+ /* 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);
}
}
}
+/* force homogeneous sizes */
static void
gtk_grid_size_request_pass2 (GtkGrid *grid)
{
@@ -542,6 +644,113 @@ gtk_grid_size_request_pass2 (GtkGrid *grid)
}
}
+/* deal with spanning children */
+static void
+gtk_grid_size_request_pass3 (GtkGrid *grid)
+{
+ GtkGridPrivate *priv = grid->priv;
+ GList *list;
+ GtkGridChild *child;
+ GtkRequisition child_requisition;
+ gint expand;
+ gboolean force;
+ gint i;
+ gint row, col;
+ gint extra;
+ gint width, height;
+
+ for (list = priv->children; list; list = list->next)
+ {
+ child = list->data;
+
+ if (!gtk_widget_get_visible (child->widget))
+ continue;
+
+ if (child->width > 1)
+ {
+ gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
+ width = 0;
+ expand = 0;
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ width += priv->columns[col].requisition;
+ if (i > 0)
+ width += priv->column_spacing;
+ if (priv->columns[col].expand)
+ expand += 1;
+ }
+
+ /* If we need to request more space for this child to fill
+ * 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 (child->height > 1)
+ {
+ gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
+ height = 0;
+ expand = 0;
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ height += priv->rows[row].requisition;
+ if (i > 0)
+ height += priv->row_spacing;
+ if (priv->rows[row].expand)
+ expand += 1;
+ }
+
+ /* If we need to request more space for this child to fill
+ * 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;
+ }
+ }
+ }
+ }
+ }
+}
static void
gtk_grid_size_request (GtkWidget *widget,
@@ -550,10 +759,6 @@ gtk_grid_size_request (GtkWidget *widget,
GtkGrid *grid = GTK_GRID (widget);
GtkGridPrivate *priv = grid->priv;
gint row, col;
- guint border_width;
-
- requisition->width = 0;
- requisition->height = 0;
gtk_grid_allocate_rowcols (grid);
@@ -563,18 +768,346 @@ gtk_grid_size_request (GtkWidget *widget,
gtk_grid_size_request_pass3 (grid);
gtk_grid_size_request_pass2 (grid);
- for (col = 0; col < priv->max_column - priv->min_column; col++)
+ requisition->width = priv->columns[0].requisition;
+
+ for (col = 1; col < priv->max_column - priv->min_column; col++)
{
+ requisition->width += priv->column_spacing;
requisition->width += priv->columns[col].requisition;
- if (col > 0)
- requisition->width += priv->column_spacing;
}
- for (row = 0; row < priv->max_row - priv->min_row; row++)
+ requisition->height = priv->rows[0].requisition;
+
+ for (row = 1; row < priv->max_row - priv->min_row; row++)
{
+ requisition->height += priv->row_spacing;
requisition->height += priv->rows[row].requisition;
- if (row > 0)
- requisition->width += priv->row_spacing;
+ }
+}
+
+static void
+gtk_grid_size_allocate_init (GtkGrid *grid)
+{
+ GtkGridPrivate *priv = grid->priv;
+ GtkGridChild *child;
+ GList *list;
+ gint row, col;
+ gint i;
+
+ gtk_grid_allocate_rowcols (grid);
+
+ for (col = 0; col < priv->max_column - priv->min_column; col++)
+ {
+ priv->columns[col].allocation = priv->columns[col].requisition;
+ priv->columns[col].need_expand = FALSE;
+ priv->columns[col].expand = FALSE;
+ priv->columns[col].empty = TRUE;
+ }
+
+ for (row = 0; row < priv->max_row - priv->min_row; row++)
+ {
+ priv->rows[row].allocation = priv->rows[row].requisition;
+ priv->rows[row].need_expand = FALSE;
+ priv->rows[row].expand = FALSE;
+ priv->rows[row].empty = TRUE;
+ }
+
+ for (list = priv->children; list; list = list->next)
+ {
+ child = list->data;
+
+ if (!gtk_widget_get_visible (child->widget))
+ continue;
+
+ if (child->width == 1)
+ {
+ col = child->left - priv->min_column;
+ priv->columns[col].empty = FALSE;
+ if (child->hexpand)
+ priv->columns[col].expand = TRUE;
+ }
+
+ if (child->height == 1)
+ {
+ row = child->top - priv->min_row;
+ priv->rows[row].empty = FALSE;
+ if (child->vexpand)
+ priv->rows[row].expand = TRUE;
+ }
+ }
+
+ for (list = priv->children; list; list = list->next)
+ {
+ child = list->data;
+
+ if (!gtk_widget_get_visible (child->widget))
+ continue;
+
+ if (child->width > 1)
+ {
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ priv->columns[col].empty = FALSE;
+ }
+ if (child->hexpand)
+ {
+ gboolean has_expand;
+
+ has_expand = FALSE;
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ if (priv->columns[col].expand)
+ {
+ has_expand = TRUE;
+ break;
+ }
+ }
+ if (!has_expand)
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ priv->columns[col].need_expand = TRUE;
+ }
+ }
+ }
+
+ if (child->height > 1)
+ {
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ priv->rows[row].empty = FALSE;
+ }
+ if (child->vexpand)
+ {
+ gboolean has_expand;
+
+ has_expand = FALSE;
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ if (priv->rows[row].expand)
+ {
+ has_expand = TRUE;
+ break;
+ }
+ }
+ if (!has_expand)
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ priv->rows[row].need_expand = TRUE;
+ }
+ }
+ }
+ }
+
+ for (col = 0; col < priv->max_column - priv->min_column; col++)
+ {
+ if (priv->columns[col].empty)
+ priv->columns[col].expand = FALSE;
+ else if (priv->columns[col].need_expand)
+ priv->columns[col].expand = TRUE;
+ }
+
+ for (row = 0; row < priv->max_row - priv->min_row; row++)
+ {
+ if (priv->rows[row].empty)
+ priv->rows[row].expand = FALSE;
+ else if (priv->rows[row].need_expand)
+ priv->rows[row].expand = TRUE;
+ }
+}
+
+static void
+gtk_grid_size_allocate_pass1 (GtkGrid *grid)
+{
+ GtkGridPrivate *priv = grid->priv;
+ GtkAllocation allocation;
+ gint width, height;
+ gint extra;
+ gint row, col;
+ gint nonempty, expand;
+
+ gtk_widget_get_allocation (GTK_WIDGET (grid), &allocation);
+
+ if (priv->children == NULL)
+ return;
+
+ if (priv->column_homogeneous)
+ {
+ nonempty = 0;
+ expand = 0;
+ for (col = 0; col < priv->max_column - priv->min_column; col++)
+ {
+ if (!priv->columns[col].empty)
+ nonempty += 1;
+ if (priv->columns[col].expand)
+ expand += 1;
+ }
+ width = allocation.width - (nonempty - 1) * priv->column_spacing;
+ if (expand)
+ for (col = 0; col < priv->max_column - priv->min_column; col++)
+ {
+ extra = width / (priv->max_column - priv->min_column - col);
+ priv->columns[col].allocation = MAX (1, extra);
+ width -= extra;
+ }
+ }
+ else
+ {
+ width = 0;
+ expand = 0;
+ nonempty = 0;
+ for (col = 0; col < priv->max_column - priv->min_column; col++)
+ {
+ width += priv->columns[col].requisition;
+ if (!priv->columns[col].empty)
+ nonempty += 1;
+ if (priv->columns[col].expand)
+ expand += 1;
+ }
+ width += (nonempty - 1) * priv->column_spacing;
+
+ if (width < allocation.width && expand > 0)
+ {
+ width = allocation.width - width;
+ for (col = 0; col < priv->max_column - priv->min_column; col++)
+ {
+ if (priv->columns[col].expand)
+ {
+ extra = width / expand;
+ priv->columns[col].allocation += extra;
+ width -= extra;
+ expand -= 1;
+ }
+ }
+ }
+ }
+
+ if (priv->row_homogeneous)
+ {
+ nonempty = 0;
+ expand = 0;
+ for (row = 0; row < priv->max_row - priv->min_row; row++)
+ {
+ if (!priv->rows[row].empty)
+ nonempty += 1;
+ if (priv->rows[row].expand)
+ expand += 1;
+ }
+ height = allocation.height - (nonempty - 1) * priv->row_spacing;
+ if (expand)
+ for (row = 0; row < priv->max_row - priv->min_row; row++)
+ {
+ extra = height / (priv->max_row - priv->min_row - row);
+ priv->rows[row].allocation = MAX (1, extra);
+ height -= extra;
+ }
+ }
+ else
+ {
+ height = 0;
+ expand = 0;
+ nonempty = 0;
+ for (row = 0; row < priv->max_row - priv->min_row; row++)
+ {
+ height += priv->rows[row].requisition;
+ if (!priv->rows[row].empty)
+ nonempty += 1;
+ if (priv->rows[row].expand)
+ expand += 1;
+ }
+ height += (nonempty - 1) * priv->row_spacing;
+
+ if (height < allocation.height && expand > 0)
+ {
+ height = allocation.height - height;
+ for (row = 0; row < priv->max_row - priv->min_row; row++)
+ {
+ if (priv->rows[row].expand)
+ {
+ extra = height / expand;
+ priv->rows[row].allocation += extra;
+ height -= extra;
+ expand -= 1;
+ }
+ }
+ }
+ }
+}
+
+static void
+gtk_grid_size_allocate_pass2 (GtkGrid *grid)
+{
+ GtkGridPrivate *priv = grid->priv;
+ GtkGridChild *child;
+ GList *list;
+ GtkRequisition child_requisition;
+ GtkAllocation child_allocation;
+ GtkAllocation allocation;
+ gint x, y;
+ gint width, height;
+ gint row, col;
+ gint i;
+
+ gtk_widget_get_allocation (GTK_WIDGET (grid), &allocation);
+
+ for (list = priv->children; list; list = list->next)
+ {
+ child = list->data;
+
+ if (!gtk_widget_get_visible (child->widget))
+ continue;
+
+ gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
+
+ x = allocation.x;
+ for (col = 0; col < child->left - priv->min_column; col++)
+ {
+ if (!priv->columns[col].empty)
+ {
+ x += priv->columns[col].allocation;
+ x += priv->column_spacing;
+ }
+ }
+
+ width = 0;
+ for (i = 0; i < child->width; i++)
+ {
+ col = child->left - priv->min_column + i;
+ width += priv->columns[col].allocation;
+ if (i > 0)
+ width += priv->column_spacing;
+ }
+
+ y = allocation.y;
+ for (row = 0; row < child->top - priv->min_row; row++)
+ {
+ if (!priv->rows[row].empty)
+ {
+ y += priv->rows[row].allocation;
+ y += priv->row_spacing;
+ }
+ }
+
+ height = 0;
+ for (i = 0; i < child->height; i++)
+ {
+ row = child->top - priv->min_row + i;
+ height += priv->rows[row].allocation;
+ if (i > 0)
+ height += priv->row_spacing;
+ }
+
+ child_allocation.x = x;
+ child_allocation.y = y;
+ child_allocation.width = MAX (1, width);
+ child_allocation.height = MAX (1, height);
+
+ gtk_widget_size_allocate (child->widget, &child_allocation);
}
}
@@ -582,19 +1115,25 @@ static void
gtk_grid_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GtkGrid *grid = GTK_GRID (widget);
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ gtk_grid_size_allocate_init (grid);
+ gtk_grid_size_allocate_pass1 (grid);
+ gtk_grid_size_allocate_pass2 (grid);
}
static void
gtk_grid_class_init (GtkGridClass *class)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
- gobject_class->finalize = gtk_grid_finalize;
-
- gobject_class->get_property = gtk_grid_get_property;
- gobject_class->set_property = gtk_grid_set_property;
+ object_class->finalize = gtk_grid_finalize;
+ 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->size_allocate = gtk_grid_size_allocate;
@@ -607,28 +1146,30 @@ gtk_grid_class_init (GtkGridClass *class)
container_class->get_child_property = gtk_grid_get_child_property;
gtk_container_class_handle_border_width (container_class);
- g_object_class_install_property (gobject_class, PROP_ROW_SPACING,
+ g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation");
+
+ g_object_class_install_property (object_class, PROP_ROW_SPACING,
g_param_spec_int ("row-spacing",
P_("Row spacing"),
P_("The amount of space between two consecutive rows"),
0, G_MAXINT16, 0,
GTK_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_COLUMN_SPACING,
+ g_object_class_install_property (object_class, PROP_COLUMN_SPACING,
g_param_spec_int ("column-spacing",
P_("Column spacing"),
P_("The amount of space between two consecutive columns"),
0, G_MAXINT16, 0,
GTK_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_ROW_HOMOGENEOUS,
+ g_object_class_install_property (object_class, PROP_ROW_HOMOGENEOUS,
g_param_spec_boolean ("row-homogeneous",
P_("Row Homogeneous"),
P_("If TRUE, the rows are all the same height"),
FALSE,
GTK_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_COLUMN_HOMOGENEOUS,
+ g_object_class_install_property (object_class, PROP_COLUMN_HOMOGENEOUS,
g_param_spec_boolean ("column-homogeneous",
P_("Column Homogeneous"),
P_("If TRUE, the columns are all the same width"),
@@ -663,6 +1204,20 @@ gtk_grid_class_init (GtkGridClass *class)
1, G_MAXINT, 1,
GTK_PARAM_READWRITE));
+ gtk_container_class_install_child_property (container_class, CHILD_PROP_HEXPAND,
+ g_param_spec_boolean ("hexpand",
+ P_("Horizontal expand"),
+ P_("Horizontal expand"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+ gtk_container_class_install_child_property (container_class, CHILD_PROP_VEXPAND,
+ g_param_spec_boolean ("vexpand",
+ P_("Vertical expand"),
+ P_("Vertical expand"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
g_type_class_add_private (class, sizeof (GtkGridPrivate));
}
@@ -672,7 +1227,7 @@ gtk_grid_new (void)
return (GtkWidget *)g_object_new (GTK_TYPE_GRID, NULL);
}
-staic void
+static void
grid_attach (GtkGrid *grid,
GtkWidget *child,
gint left,
@@ -689,6 +1244,8 @@ grid_attach (GtkGrid *grid,
grid_child->top = top;
grid_child->width = width;
grid_child->height = height;
+ grid_child->hexpand = FALSE;
+ grid_child->vexpand = FALSE;
priv->children = g_list_prepend (priv->children, grid_child);
@@ -705,9 +1262,6 @@ gtk_grid_attach (GtkGrid *grid,
gint width,
gint height)
{
- GtkGridPrivate *priv;
- GtkGridChild *grid_child;
-
g_return_if_fail (GTK_IS_GRID (grid));
g_return_if_fail (GTK_IS_WIDGET (child));
g_return_if_fail (gtk_widget_get_parent (child) == NULL);
@@ -725,14 +1279,13 @@ gtk_grid_attach_next_to (GtkGrid *grid,
gint width,
gint height)
{
- GtkGridPrivate *priv;
GtkGridChild *grid_sibling;
gint left, top;
g_return_if_fail (GTK_IS_GRID (grid));
g_return_if_fail (GTK_IS_WIDGET (child));
g_return_if_fail (gtk_widget_get_parent (child) == NULL);
- g_return_if_fail (gtk_widget_get_parent (sibling) == grid);
+ g_return_if_fail (gtk_widget_get_parent (sibling) == (GtkWidget*)grid);
g_return_if_fail (width > 0);
g_return_if_fail (height > 0);
@@ -741,20 +1294,20 @@ gtk_grid_attach_next_to (GtkGrid *grid,
switch (side)
{
case GTK_POS_LEFT:
- left = grid_sibling->left_attach - width;
+ left = grid_sibling->left - width;
top = grid_sibling->top;
break;
case GTK_POS_RIGHT:
- left = grid_sibling->left_attach + grid_sibling->width;
- top - grid_sibling->top;
+ left = grid_sibling->left + grid_sibling->width;
+ top = grid_sibling->top;
break;
case GTK_POS_TOP:
- left = grid_sibling->left_attach;
- top = grid_sibling->top_attach - height;
+ left = grid_sibling->left;
+ top = grid_sibling->top - height;
break;
case GTK_POS_BOTTOM:
- left = grid_sibling->left_attach;
- top = grid_sibling->top_attach + grid_sibling->height;
+ left = grid_sibling->left;
+ top = grid_sibling->top + grid_sibling->height;
break;
default:
g_assert_not_reached ();
@@ -800,9 +1353,9 @@ gtk_grid_set_column_homogeneous (GtkGrid *grid,
priv = grid->priv;
- if (priv->col_homogeneous != homogeneous)
+ if (priv->column_homogeneous != homogeneous)
{
- priv->col_homogeneous = homogeneous;
+ priv->column_homogeneous = homogeneous;
if (gtk_widget_get_visible (GTK_WIDGET (grid)))
gtk_widget_queue_resize (GTK_WIDGET (grid));
@@ -860,7 +1413,7 @@ gtk_grid_set_column_spacing (GtkGrid *grid,
if (priv->column_spacing != spacing)
{
- priv->col_spacing = spacing;
+ priv->column_spacing = spacing;
if (gtk_widget_get_visible (GTK_WIDGET (grid)))
gtk_widget_queue_resize (GTK_WIDGET (grid));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]