[gtk+/grid-widget] Reorganize GtkGrid into per-orientation data



commit 72fc03d9c409af668b3de00d483c0cd5b78b4592
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Oct 9 19:33:46 2010 -0400

    Reorganize GtkGrid into per-orientation data
    
    This will allow implement wfh and hfw together, using an
    orientation parameter.

 gtk/gtkgrid.c | 1123 ++++++++++++++++++++++++++-------------------------------
 1 files changed, 502 insertions(+), 621 deletions(-)
---
diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c
index e7c348c..8386a3d 100644
--- a/gtk/gtkgrid.c
+++ b/gtk/gtkgrid.c
@@ -33,20 +33,32 @@
 
 
 typedef struct _GtkGridChild GtkGridChild;
-typedef struct _GtkGridRowCol GtkGridRowCol;
+typedef struct _GtkGridChildAttach GtkGridChildAttach;
+typedef struct _GtkGridLine GtkGridLine;
+typedef struct _GtkGridLines GtkGridLines;
+
+struct _GtkGridChildAttach
+{
+  gint pos;
+  gint span;
+  gboolean expand;
+};
 
 struct _GtkGridChild
 {
   GtkWidget *widget;
-  gint left;
-  gint top;
-  gint width;
-  gint height;
-  gboolean hexpand;
-  gboolean vexpand;
+  GtkGridChildAttach attach[2];
 };
 
-struct _GtkGridRowCol
+#define CHILD_LEFT(child)    ((child)->attach[GTK_ORIENTATION_HORIZONTAL].pos)
+#define CHILD_WIDTH(child)   ((child)->attach[GTK_ORIENTATION_HORIZONTAL].span)
+#define CHILD_HEXPAND(child) ((child)->attach[GTK_ORIENTATION_HORIZONTAL].expand)
+#define CHILD_TOP(child)     ((child)->attach[GTK_ORIENTATION_VERTICAL].pos)
+#define CHILD_HEIGHT(child)  ((child)->attach[GTK_ORIENTATION_VERTICAL].span)
+#define CHILD_VEXPAND(child) ((child)->attach[GTK_ORIENTATION_VERTICAL].expand)
+
+/* A GtkGridLine struct represents a single row or column */
+struct _GtkGridLine
 {
   gint minimum;
   gint natural;
@@ -56,26 +68,31 @@ struct _GtkGridRowCol
   gboolean empty;
 };
 
-struct _GtkGridPrivate
+/* A GtkGridLines struct represents all the rows or columns of
+ * a grid, with auxiliary information. The lines array has length
+ * max - min, and the n-th member represents the line n - min.
+ */
+struct _GtkGridLines
+{
+  GtkGridLine *lines;
+  gint min, max;
+  gint16 spacing;
+  gboolean homogeneous;
+};
 
+struct _GtkGridPrivate
 {
   GList *children;
 
-  GtkGridRowCol *rows;
-  GtkGridRowCol *columns;
-
-  gint min_row, max_row;
-  gint min_column, max_column;
-
-  gint16 row_spacing;
-  gint16 column_spacing;
-
   GtkOrientation orientation;
 
-  guint row_homogeneous    : 1;
-  guint column_homogeneous : 1;
+  GtkGridLines lines[2];
 };
 
+#define ROWS(priv)    (&(priv)->lines[GTK_ORIENTATION_HORIZONTAL])
+#define COLUMNS(priv) (&(priv)->lines[GTK_ORIENTATION_VERTICAL])
+
+
 enum
 {
   PROP_0,
@@ -101,13 +118,22 @@ G_DEFINE_TYPE_WITH_CODE (GtkGrid, gtk_grid, GTK_TYPE_CONTAINER,
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
 
 static void
+gtk_grid_free_lines (GtkGrid        *grid,
+                     GtkOrientation  orientation)
+{
+  GtkGridPrivate *priv = grid->priv;
+
+  g_free (priv->lines[orientation].lines);
+  priv->lines[orientation].lines = NULL;
+}
+
+static void
 gtk_grid_finalize (GObject *object)
 {
   GtkGrid *grid = GTK_GRID (object);
-  GtkGridPrivate *priv = grid->priv;
 
-  g_free (priv->rows);
-  g_free (priv->columns);
+  gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
+  gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
 
   G_OBJECT_CLASS (gtk_grid_parent_class)->finalize (object);
 }
@@ -128,19 +154,19 @@ gtk_grid_get_property (GObject    *object,
       break;
 
     case PROP_ROW_SPACING:
-      g_value_set_int (value, priv->row_spacing);
+      g_value_set_int (value, ROWS(priv)->spacing);
       break;
 
     case PROP_COLUMN_SPACING:
-      g_value_set_int (value, priv->column_spacing);
+      g_value_set_int (value, COLUMNS(priv)->spacing);
       break;
 
     case PROP_ROW_HOMOGENEOUS:
-      g_value_set_boolean (value, priv->row_homogeneous);
+      g_value_set_boolean (value, ROWS(priv)->homogeneous);
       break;
 
     case PROP_COLUMN_HOMOGENEOUS:
-      g_value_set_boolean (value, priv->column_homogeneous);
+      g_value_set_boolean (value, COLUMNS(priv)->homogeneous);
       break;
 
     default:
@@ -150,17 +176,6 @@ 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)
 {
@@ -179,32 +194,34 @@ gtk_grid_set_orientation (GtkGrid        *grid,
         {
           child = list->data;
 
-          left = child->left;
-          top = child->top;
-          width = child->width;
-          height = child->height;
+          left   = CHILD_LEFT(child);
+          top    = CHILD_TOP(child);
+          width  = CHILD_WIDTH(child);
+          height = CHILD_HEIGHT(child);
 
           if (orientation == GTK_ORIENTATION_VERTICAL)
             {
-              child->top = left;
-              child->left = - (top + height);
-              child->width = height;
-              child->height = width;
+              CHILD_LEFT(child)   = - (top + height);
+              CHILD_TOP(child)    = left;
+              CHILD_WIDTH(child)  = height;
+              CHILD_HEIGHT(child) = width;
             }
           else
             {
-              child->left = top;
-              child->top = - (left + width);
-              child->width = height;
-              child->height = width;
+              CHILD_LEFT(child)   = top;
+              CHILD_TOP(child)    = - (left + width);
+              CHILD_WIDTH(child)  = height;
+              CHILD_HEIGHT(child) = width;
             }
-          gtk_widget_child_notify (child->widget, "left");
-          gtk_widget_child_notify (child->widget, "top");
+          gtk_widget_child_notify (child->widget, "left-attach");
+          gtk_widget_child_notify (child->widget, "top-attach");
           gtk_widget_child_notify (child->widget, "width");
           gtk_widget_child_notify (child->widget, "height");
         }
 
-      gtk_grid_resize (grid);
+      gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
+      gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
+
       gtk_widget_queue_resize (GTK_WIDGET (grid));
     }
 }
@@ -285,27 +302,27 @@ gtk_grid_get_child_property (GtkContainer *container,
   switch (property_id)
     {
     case CHILD_PROP_LEFT_ATTACH:
-      g_value_set_int (value, grid_child->left);
+      g_value_set_int (value, CHILD_LEFT(grid_child));
       break;
 
     case CHILD_PROP_TOP_ATTACH:
-      g_value_set_int (value, grid_child->top);
+      g_value_set_int (value, CHILD_TOP(grid_child));
       break;
 
     case CHILD_PROP_WIDTH:
-      g_value_set_int (value, grid_child->width);
+      g_value_set_int (value, CHILD_WIDTH(grid_child));
       break;
 
     case CHILD_PROP_HEIGHT:
-      g_value_set_int (value, grid_child->height);
+      g_value_set_int (value, CHILD_HEIGHT(grid_child));
       break;
 
     case CHILD_PROP_HEXPAND:
-      g_value_set_boolean (value, grid_child->hexpand);
+      g_value_set_boolean (value, CHILD_HEXPAND(grid_child));
       break;
 
     case CHILD_PROP_VEXPAND:
-      g_value_set_boolean (value, grid_child->vexpand);
+      g_value_set_boolean (value, CHILD_VEXPAND(grid_child));
       break;
 
     default:
@@ -335,32 +352,32 @@ gtk_grid_set_child_property (GtkContainer *container,
   switch (property_id)
     {
     case CHILD_PROP_LEFT_ATTACH:
-      grid_child->left = g_value_get_int (value);
-      gtk_grid_resize (grid);
+      CHILD_LEFT(grid_child) = g_value_get_int (value);
+      gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
       break;
 
     case CHILD_PROP_TOP_ATTACH:
-      grid_child->top = g_value_get_int (value);
-      gtk_grid_resize (grid);
+      CHILD_TOP(grid_child) = g_value_get_int (value);
+      gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
       break;
 
    case CHILD_PROP_WIDTH:
-      grid_child->width = g_value_get_int (value);
-      gtk_grid_resize (grid);
+      CHILD_WIDTH(grid_child) = g_value_get_int (value);
+      gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
       break;
 
     case CHILD_PROP_HEIGHT:
-      grid_child->height = g_value_get_int (value);
-      gtk_grid_resize (grid);
+      CHILD_HEIGHT(grid_child) = g_value_get_int (value);
+      gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
       break;
 
    case CHILD_PROP_HEXPAND:
-      grid_child->hexpand = g_value_get_boolean (value);
+      CHILD_HEXPAND(grid_child) = 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);
+      CHILD_VEXPAND(grid_child) = g_value_get_boolean (value);
       gtk_widget_queue_resize (GTK_WIDGET (grid));
       break;
 
@@ -375,6 +392,16 @@ gtk_grid_set_child_property (GtkContainer *container,
 }
 
 static void
+init_lines (GtkGridLines *lines)
+{
+  lines->lines = NULL;
+  lines->min = 0;
+  lines->max = 0;
+  lines->spacing = 0;
+  lines->homogeneous = FALSE;
+}
+
+static void
 gtk_grid_init (GtkGrid *grid)
 {
   GtkGridPrivate *priv;
@@ -386,17 +413,10 @@ gtk_grid_init (GtkGrid *grid)
   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (grid), FALSE);
 
   priv->children = NULL;
-  priv->rows = NULL;
-  priv->columns = NULL;
-  priv->min_row = 0;
-  priv->max_row = 0;
-  priv->min_column = 0;
-  priv->max_column = 0;
-  priv->row_spacing = 0;
-  priv->column_spacing = 0;
-  priv->row_homogeneous = FALSE;
-  priv->column_homogeneous = FALSE;
   priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+
+  init_lines (ROWS(priv));
+  init_lines (COLUMNS(priv));
 }
 
 static void grid_attach (GtkGrid   *grid,
@@ -413,36 +433,27 @@ gtk_grid_add (GtkContainer *container,
   GtkGrid *grid = GTK_GRID (container);
   GtkGridPrivate *priv = grid->priv;
   GtkGridChild *grid_child;
+  GtkGridChildAttach *attach;
+  GtkGridChildAttach *opposite;
   GList *list;
-  gint left, top;
+  gint pos;
 
-  left = 0;
-  top = 0;
-
-  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+  pos = 0;
+  for (list = priv->children; list; list = list->next)
     {
-      /* stack horizontally */
-      for (list = priv->children; list; list = list->next)
-        {
-          grid_child = list->data;
+      grid_child = list->data;
 
-          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;
+      attach = &grid_child->attach[priv->orientation];
+      opposite = &grid_child->attach[1 - priv->orientation];
 
-          if (grid_child->left <= 0 && grid_child->left + grid_child->width > 0)
-            top = MAX (top, grid_child->top + grid_child->height);
-        }
-    }
+      if (opposite->pos <= 0 && opposite->pos + opposite->span > 0)
+        pos = MAX (pos, attach->pos + attach->span);
+     }
 
-  grid_attach (grid, child, left, top, 1, 1);
+  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+    grid_attach (grid, child, pos, 0, 1, 1);
+  else
+    grid_attach (grid, child, 0, pos, 1, 1);
 }
 
 static void
@@ -501,92 +512,105 @@ gtk_grid_child_type (GtkContainer *container)
 }
 
 static void
-gtk_grid_allocate_rowcols (GtkGrid *grid)
+gtk_grid_allocate_lines (GtkGrid        *grid,
+                         GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
+  GtkGridLines *lines;
   GtkGridChild *grid_child;
   GList *list;
-  gint minrow, maxrow, mincol, maxcol;
+  gint min, max;
 
-  if (priv->rows && priv->columns)
+  lines = &priv->lines[orientation];
+
+  if (lines->lines != NULL)
     return;
 
-  minrow = mincol = G_MAXINT;
-  maxrow = maxcol = G_MININT;
+  min = G_MAXINT;
+  max = G_MININT;
   for (list = priv->children; list; list = list->next)
     {
       grid_child = list->data;
 
-      if (grid_child->top < minrow)
-        minrow = grid_child->top;
-
-      if (grid_child->top + grid_child->height > maxrow)
-        maxrow = grid_child->top + grid_child->height;
-
-      if (grid_child->left < mincol)
-        mincol = grid_child->left;
-
-      if (grid_child->left + grid_child->width > maxcol)
-        maxcol = grid_child->left + grid_child->width;
+      min = MIN (min, grid_child->attach[orientation].pos);
+      max = MAX (max, grid_child->attach[orientation].pos + grid_child->attach[orientation].span);
     }
 
-  priv->min_row = minrow;
-  priv->max_row = maxrow;
-  priv->min_column = mincol;
-  priv->max_column = maxcol;
-
-  priv->rows = g_new (GtkGridRowCol, maxrow - minrow);
-  priv->columns = g_new (GtkGridRowCol, maxcol - mincol);
+  lines->min = min;
+  lines->max = max;
+  lines->lines = g_new (GtkGridLine, max - min);
 }
 
 /* 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)
+gtk_grid_size_request_init (GtkGrid        *grid,
+                            GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
-  GtkGridChild *grid_child;
+  GtkGridChild *child;
+  GtkGridChildAttach *attach;
+  GtkGridLines *lines;
   GList *list;
   gint i;
 
-  for (i = 0; i < priv->max_row - priv->min_row; i++)
-    {
-      priv->rows[i].minimum = 0;
-      priv->rows[i].natural = 0;
-      priv->rows[i].expand = FALSE;
-    }
+  lines = &priv->lines[orientation];
 
-  for (i = 0; i < priv->max_column - priv->min_column; i++)
+  for (i = 0; i < lines->max - lines->min; i++)
     {
-      priv->columns[i].minimum = 0;
-      priv->columns[i].natural = 0;
-      priv->columns[i].expand = FALSE;
+      lines->lines[i].minimum = 0;
+      lines->lines[i].natural = 0;
+      lines->lines[i].expand = FALSE;
     }
 
   for (list = priv->children; list; list = list->next)
     {
-      grid_child = list->data;
+      child = list->data;
+
+      attach = &child->attach[orientation];
+      if (attach->span == 1 && attach->expand)
+        lines->lines[attach->pos - lines->min].expand = TRUE;
+    }
+}
 
-      if (gtk_widget_get_visible (grid_child->widget))
-        gtk_widget_get_preferred_size (grid_child->widget, NULL, NULL);
+static void
+get_preferred_size (GtkWidget      *widget,
+                    GtkOrientation  orientation,
+                    gint           *minimum,
+                    gint           *natural)
+{
+  GtkRequisition minimum_req;
+  GtkRequisition natural_req;
 
-      if (grid_child->width == 1 && grid_child->hexpand)
-        priv->columns[grid_child->left - priv->min_column].expand = TRUE;
+  gtk_widget_get_preferred_size (widget, &minimum_req, &natural_req);
 
-      if (grid_child->height == 1 && grid_child->vexpand)
-        priv->rows[grid_child->top - priv->min_row].expand = TRUE;
-    }
+  if (minimum)
+    *minimum = orientation == GTK_ORIENTATION_HORIZONTAL
+               ? minimum_req.width
+               : minimum_req.height;
+
+  if (natural)
+    *natural = orientation == GTK_ORIENTATION_HORIZONTAL
+               ? natural_req.width
+               : natural_req.height;
 }
 
 /* set requisition to max of non-spanning children */
 static void
-gtk_grid_size_request_pass1 (GtkGrid *grid)
+gtk_grid_size_request_pass1 (GtkGrid        *grid,
+                             GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
   GtkGridChild *child;
+  GtkGridChildAttach *attach;
+  GtkGridLines *lines;
+  GtkGridLine *line;
   GList *list;
-  GtkRequisition minimum, natural;
+  gint minimum;
+  gint natural;
+
+  lines = &priv->lines[orientation];
 
   for (list = priv->children; list; list = list->next)
     {
@@ -595,83 +619,73 @@ gtk_grid_size_request_pass1 (GtkGrid *grid)
       if (!gtk_widget_get_visible (child->widget))
         continue;
 
-      gtk_widget_get_preferred_size (child->widget, &minimum, &natural);
+      attach = &child->attach[orientation];
+      if (attach->span != 1)
+        continue;
 
-      /* Child spans a single column. */
-      if (child->width == 1)
-        {
-          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);
-        }
+      get_preferred_size (child->widget, orientation, &minimum, &natural);
 
-      /* Child spans a single row. */
-      if (child->height == 1)
-        {
-          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);
-        }
+      line = &lines->lines[attach->pos - lines->min];
+      line->minimum = MAX (line->minimum, minimum);
+      line->natural = MAX (line->natural, natural);
     }
 }
 
 /* force homogeneous sizes */
 static void
-gtk_grid_size_request_pass2 (GtkGrid *grid)
+gtk_grid_size_request_pass2 (GtkGrid        *grid,
+                             GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
+  GtkGridLines *lines;
   gint minimum, natural;
   gint i;
 
-  if (priv->row_homogeneous)
-    {
-      minimum = 0;
-      natural = 0;
+  lines = &priv->lines[orientation];
 
-      for (i = 0; i < priv->max_row - priv->min_row; i++)
-        {
-          minimum = MAX (minimum, priv->rows[i].minimum);
-          natural = MAX (natural, priv->rows[i].natural);
-        }
+  if (!lines->homogeneous)
+    return;
 
-      for (i = 0; i < priv->max_row - priv->min_row; i++)
-        {
-          priv->rows[i].minimum = minimum;
-          priv->rows[i].natural = natural;
-        }
-    }
+  minimum = 0;
+  natural = 0;
 
-  if (priv->column_homogeneous)
+  for (i = 0; i < lines->max - lines->min; i++)
     {
-      minimum = 0;
-      natural = 0;
-
-      for (i = 0; i < priv->max_column - priv->min_column; i++)
-        {
-          minimum = MAX (minimum, priv->columns[i].minimum);
-          natural = MAX (natural, priv->columns[i].natural);
-        }
+      minimum = MAX (minimum, lines->lines[i].minimum);
+      natural = MAX (natural, lines->lines[i].natural);
+    }
 
-      for (i = 0; i < priv->max_column - priv->min_column; i++)
-        {
-          priv->columns[i].minimum = minimum;
-          priv->columns[i].natural = natural;
-        }
+  for (i = 0; i < lines->max - lines->min; i++)
+    {
+      lines->lines[i].minimum = minimum;
+      lines->lines[i].natural = natural;
     }
 }
 
 /* deal with spanning children */
 static void
-gtk_grid_size_request_pass3 (GtkGrid *grid)
+gtk_grid_size_request_pass3 (GtkGrid        *grid,
+                             GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
   GList *list;
   GtkGridChild *child;
-  GtkRequisition child_minimum, child_natural;
+  GtkGridChildAttach *attach;
+  GtkGridLines *lines;
+  GtkGridLine *line;
+  gint child_minimum;
+  gint child_natural;
+  gint span_minimum;
+  gint span_natural;
+  gint span_expand;
+  gint minimum;
+  gint natural;
   gint expand;
   gboolean force;
   gint i;
-  gint row, col;
   gint extra;
-  gint minimum, natural;
+
+  lines = &priv->lines[orientation];
 
   for (list = priv->children; list; list = list->next)
     {
@@ -680,143 +694,70 @@ 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);
+      attach = &child->attach[orientation];
+      if (attach->span == 1)
+        continue;
 
-      if (child->width > 1)
+      span_minimum = (attach->span - 1) * lines->spacing;
+      span_natural = (attach->span - 1) * lines->spacing;
+      span_expand = 0;
+      for (i = 0; i < attach->span; i++)
         {
-          minimum = 0;
-          natural = 0;
-          expand = 0;
-          for (i = 0; i < child->width; i++)
-            {
-              col = child->left - priv->min_column + i;
-              minimum += priv->columns[col].minimum;
-              natural += priv->columns[col].natural;
-              if (i > 0)
-                {
-                  minimum += priv->column_spacing;
-                  natural += priv->column_spacing;
-                }
-              if (priv->columns[col].expand)
-                expand += 1;
-            }
+          line = &lines->lines[attach->pos - lines->min + i];
+          span_minimum += line->minimum;
+          span_natural += line->natural;
+          if (line->expand)
+            span_expand += 1;
+        }
+
+      get_preferred_size (child->widget, orientation, &child_minimum, &child_natural);
 
-          /* 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 (minimum < child_minimum.width)
+      /* 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 (span_minimum < child_minimum)
+        {
+          force = FALSE;
+          minimum = child_minimum - span_minimum;
+          expand = span_expand;
+          if (expand == 0)
             {
-              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;
-                    }
-                }
+              expand = attach->span;
+              force = TRUE;
             }
-
-          if (natural < child_natural.width)
+          for (i = 0; i < attach->span; i++)
             {
-              force = FALSE;
-              natural = child_natural.width - natural;
-              if (expand == 0)
-                {
-                  expand = child->width;
-                  force = TRUE;
-                }
-              for (i = 0; i < child->width; i++)
+              line = &lines->lines[attach->pos - lines->min + i];
+              if (force || line->expand)
                 {
-                  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;
-                    }
+                  extra = minimum / expand;
+                  line->minimum += extra;
+                  minimum -= extra;
+                  expand -= 1;
                 }
             }
         }
 
-      if (child->height > 1)
+      if (span_natural < child_natural)
         {
-          minimum = 0;
-          natural = 0;
-          expand = 0;
-          for (i = 0; i < child->height; i++)
-            {
-              row = child->top - priv->min_row + i;
-              minimum += priv->rows[row].minimum;
-              natural += priv->rows[row].natural;
-              if (i > 0)
-                {
-                  minimum += priv->row_spacing;
-                  natural += 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 (minimum < child_minimum.height)
+          force = FALSE;
+          natural = child_natural - span_natural;
+          expand = span_expand;
+          if (expand == 0)
             {
-              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;
-                    }
-                }
+              expand = attach->span;
+              force = TRUE;
             }
-
-          if (natural < child_natural.height)
+          for (i = 0; i < attach->span; i++)
             {
-              force = FALSE;
-              natural = child_natural.height - natural;
-              if (expand == 0)
-                {
-                  expand = child->height;
-                  force = TRUE;
-                }
-              for (i = 0; i < child->height; i++)
+              line = &lines->lines[attach->pos - lines->min + i];
+              if (force || line->expand)
                 {
-                  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;
-                    }
+                  extra = natural / expand;
+                  line->natural += extra;
+                  natural -= extra;
+                  expand -= 1;
                 }
             }
         }
@@ -824,101 +765,110 @@ gtk_grid_size_request_pass3 (GtkGrid *grid)
 }
 
 static void
-gtk_grid_get_preferred_width (GtkWidget *widget,
-                              gint      *minimum_width,
-                              gint      *natural_width)
+gtk_grid_get_size (GtkGrid        *grid,
+                   GtkOrientation  orientation,
+                   gint           *minimum_size,
+                   gint           *natural_size)
 {
-  GtkGrid *grid = GTK_GRID (widget);
   GtkGridPrivate *priv = grid->priv;
-  gint col;
+  GtkGridLines *lines;
+  gint i;
   gint minimum, natural;
 
-  gtk_grid_allocate_rowcols (grid);
+  gtk_grid_allocate_lines (grid, orientation);
+
+  gtk_grid_size_request_init (grid, orientation);
+  gtk_grid_size_request_pass1 (grid, orientation);
+  gtk_grid_size_request_pass2 (grid, orientation);
+  gtk_grid_size_request_pass3 (grid, orientation);
+  gtk_grid_size_request_pass2 (grid, orientation);
 
-  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);
+  lines = &priv->lines[orientation];
 
-  minimum = priv->columns[0].minimum;
-  natural = priv->columns[0].natural;
+  minimum = (lines->max - lines->min - 1) * lines->spacing;
+  natural = (lines->max - lines->min - 1) * lines->spacing;
 
-  for (col = 1; col < priv->max_column - priv->min_column; col++)
+  for (i = 0; i < lines->max - lines->min; i++)
     {
-      minimum += priv->column_spacing;
-      minimum += priv->columns[col].minimum;
-      natural += priv->column_spacing;
-      natural += priv->columns[col].natural;
+      minimum += lines->lines[i].minimum;
+      natural += lines->lines[i].natural;
     }
 
-  if (minimum_width)
-    *minimum_width = minimum;
+  if (minimum_size)
+    *minimum_size = minimum;
 
-  if (natural_width)
-    *natural_width = natural;
+  if (natural_size)
+    *natural_size = natural;
+}
+
+static void
+gtk_grid_get_preferred_width (GtkWidget *widget,
+                              gint      *minimum,
+                              gint      *natural)
+{
+  gtk_grid_get_size (GTK_GRID (widget),
+                     GTK_ORIENTATION_HORIZONTAL,
+                     minimum,
+                     natural);
 }
 
 static void
 gtk_grid_get_preferred_height (GtkWidget *widget,
-                               gint      *minimum_height,
-                               gint      *natural_height)
+                               gint      *minimum,
+                               gint      *natural)
+{
+  gtk_grid_get_size (GTK_GRID (widget),
+                     GTK_ORIENTATION_VERTICAL,
+                     minimum,
+                     natural);
+}
+
+#if 0
+static void
+gtk_grid_get_preferred_width_for_height (GtkWidget *widget,
+                                         gint       height,
+                                         gint      *minimum,
+                                         gint      *natural)
 {
   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++)
-    {
-      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_get_preferred_height_for_width (GtkWidget *widget,
+                                         gint       width,
+                                         gint      *minimum,
+                                         gint      *natural)
+{
+  GtkGrid *grid = GTK_GRID (widget);
+  GtkGridPrivate *priv = grid->priv;
 }
+#endif
+
+/* find empty and expanding lines */
 static void
-gtk_grid_size_allocate_init (GtkGrid *grid)
+gtk_grid_size_allocate_init (GtkGrid        *grid,
+                             GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
   GtkGridChild *child;
+  GtkGridChildAttach *attach;
   GList *list;
-  gint row, col;
   gint i;
+  GtkGridLines *lines;
+  GtkGridLine *line;
+  gboolean has_expand;
 
-  gtk_grid_allocate_rowcols (grid);
+  gtk_grid_allocate_lines (grid, orientation);
 
-  for (col = 0; col < priv->max_column - priv->min_column; col++)
-    {
-      priv->columns[col].allocation = priv->columns[col].minimum;
-      priv->columns[col].need_expand = FALSE;
-      priv->columns[col].expand = FALSE;
-      priv->columns[col].empty = TRUE;
-    }
+  lines = &priv->lines[orientation];
 
-  for (row = 0; row < priv->max_row - priv->min_row; row++)
+  for (i = 0; i < lines->max - lines->min; i++)
     {
-      priv->rows[row].allocation = priv->rows[row].minimum;
-      priv->rows[row].need_expand = FALSE;
-      priv->rows[row].expand = FALSE;
-      priv->rows[row].empty = TRUE;
+      lines->lines[i].allocation = lines->lines[i].minimum;
+      lines->lines[i].need_expand = FALSE;
+      lines->lines[i].expand = FALSE;
+      lines->lines[i].empty = TRUE;
     }
 
   for (list = priv->children; list; list = list->next)
@@ -928,21 +878,14 @@ gtk_grid_size_allocate_init (GtkGrid *grid)
       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;
-        }
+      attach = &child->attach[orientation];
+      if (attach->span != 1)
+        continue;
 
-      if (child->height == 1)
-        {
-          row = child->top - priv->min_row;
-          priv->rows[row].empty = FALSE;
-          if (child->vexpand)
-            priv->rows[row].expand = TRUE;
-        }
+      line = &lines->lines[attach->pos - lines->min];
+      line->empty = FALSE;
+      if (attach->expand)
+        line->expand = TRUE;
     }
 
   for (list = priv->children; list; list = list->next)
@@ -952,195 +895,109 @@ gtk_grid_size_allocate_init (GtkGrid *grid)
       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;
+      attach = &child->attach[orientation];
+      if (attach->span == 1)
+        continue;
 
-              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;
-                  }
-            }
+      has_expand = FALSE;
+      for (i = 0; i < attach->span; i++)
+        {
+          line = &lines->lines[attach->pos - lines->min + i];
+          line->empty = FALSE;
+          if (line->expand)
+            has_expand = TRUE;
         }
 
-      if (child->height > 1)
+      if (attach->expand && !has_expand)
         {
-          for (i = 0; i < child->height; i++)
+          for (i = 0; i < attach->span; 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;
-                  }
+              line = &lines->lines[attach->pos - lines->min + i];
+              line->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++)
+  for (i = 0; i < lines->max - lines->min; i++)
     {
-      if (priv->rows[row].empty)
-        priv->rows[row].expand = FALSE;
-      else if (priv->rows[row].need_expand)
-        priv->rows[row].expand = TRUE;
+      if (lines->lines[i].need_expand)
+        lines->lines[i].expand = TRUE;
     }
 }
 
+/* distribute space over lines */
 static void
-gtk_grid_size_allocate_pass1 (GtkGrid *grid)
+gtk_grid_size_allocate_pass1 (GtkGrid        *grid,
+                              GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
   GtkAllocation allocation;
-  gint width, height;
   gint extra;
-  gint row, col;
+  gint i;
   gint nonempty, expand;
-
-  gtk_widget_get_allocation (GTK_WIDGET (grid), &allocation);
+  GtkGridLines *lines;
+  gint size;
+  gint alloc_size;
 
   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;
-          }
-    }
+  gtk_widget_get_allocation (GTK_WIDGET (grid), &allocation);
+
+  lines = &priv->lines[orientation];
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    alloc_size = allocation.width;
   else
+    alloc_size = allocation.height;
+
+  if (lines->homogeneous)
     {
-      width = 0;
-      expand = 0;
       nonempty = 0;
-      for (col = 0; col < priv->max_column - priv->min_column; col++)
+      expand = 0;
+      for (i = 0; i < lines->max - lines->min; i++)
         {
-          width += priv->columns[col].minimum;
-          if (!priv->columns[col].empty)
+          if (!lines->lines[i].empty)
             nonempty += 1;
-          if (priv->columns[col].expand)
+          if (lines->lines[i].expand)
             expand += 1;
         }
-      width += (nonempty - 1) * priv->column_spacing;
 
-      if (width < allocation.width && expand > 0)
+      size = alloc_size - (nonempty - 1) * lines->spacing;
+      if (expand > 0)
         {
-          width = allocation.width - width;
-          for (col = 0; col < priv->max_column - priv->min_column; col++)
+          for (i = 0; i < lines->max - lines->min; i++)
             {
-              if (priv->columns[col].expand)
-                {
-                  extra = width / expand;
-                  priv->columns[col].allocation += extra;
-                  width -= extra;
-                  expand -= 1;
-                }
+              extra = size / (lines->max - lines->min - i);
+              lines->lines[i].allocation = MAX (1, extra);
+              size -= extra;
             }
         }
     }
-
-  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;
+      size = 0;
       expand = 0;
       nonempty = 0;
-      for (row = 0; row < priv->max_row - priv->min_row; row++)
+      for (i = 0; i < lines->max - lines->min; i++)
         {
-          height += priv->rows[row].minimum;
-          if (!priv->rows[row].empty)
+          size += lines->lines[i].minimum;
+          if (!lines->lines[i].empty)
             nonempty += 1;
-          if (priv->rows[row].expand)
+          if (lines->lines[i].expand)
             expand += 1;
         }
-      height += (nonempty - 1) * priv->row_spacing;
+      size += (nonempty - 1) * lines->spacing;
 
-      if (height < allocation.height && expand > 0)
+      if (size < alloc_size && expand > 0)
         {
-          height = allocation.height - height;
-          for (row = 0; row < priv->max_row - priv->min_row; row++)
+          size = alloc_size - size;
+          for (i = 0; i < lines->max - lines->min; i++)
             {
-              if (priv->rows[row].expand)
+              if (lines->lines[i].expand)
                 {
-                  extra = height / expand;
-                  priv->rows[row].allocation += extra;
-                  height -= extra;
+                  extra = size / expand;
+                  lines->lines[i].allocation += extra;
+                  size -= extra;
                   expand -= 1;
                 }
             }
@@ -1149,18 +1006,47 @@ gtk_grid_size_allocate_pass1 (GtkGrid *grid)
 }
 
 static void
+allocate_child (GtkGrid        *grid,
+                GtkOrientation  orientation,
+                GtkGridChild   *child,
+                gint           *pos,
+                gint           *size)
+{
+  GtkGridPrivate *priv = grid->priv;
+  GtkGridLines *lines;
+  GtkGridLine *line;
+  GtkGridChildAttach *attach;
+  gint i;
+
+  lines = &priv->lines[orientation];
+  attach = &child->attach[orientation];
+
+  *pos = 0;
+  for (i = 0; i < attach->pos - lines->min; i++)
+    {
+      line = &lines->lines[i];
+      if (!line->empty)
+        *pos += line->allocation + lines->spacing;
+    }
+
+  *size = (attach->span - 1) * lines->spacing;
+  for (i = 0; i < attach->span; i++)
+    {
+      line = &lines->lines[attach->pos - lines->min + i];
+      *size += line->allocation;
+    }
+}
+
+/* allocate children */
+static void
 gtk_grid_size_allocate_pass2 (GtkGrid *grid)
 {
   GtkGridPrivate *priv = grid->priv;
-  GtkGridChild *child;
   GList *list;
-  GtkRequisition child_requisition;
-  GtkAllocation child_allocation;
+  GtkGridChild *child;
   GtkAllocation allocation;
-  gint x, y;
-  gint width, height;
-  gint row, col;
-  gint i;
+  GtkAllocation child_allocation;
+  gint x, y, width, height;
 
   gtk_widget_get_allocation (GTK_WIDGET (grid), &allocation);
 
@@ -1171,48 +1057,11 @@ gtk_grid_size_allocate_pass2 (GtkGrid *grid)
       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;
-        }
+      allocate_child (grid, GTK_ORIENTATION_HORIZONTAL, child, &x, &width);
+      allocate_child (grid, GTK_ORIENTATION_VERTICAL, child, &y, &height);
 
-      child_allocation.x = x;
-      child_allocation.y = y;
+      child_allocation.x = allocation.x + x;
+      child_allocation.y = allocation.y + y;
       child_allocation.width = MAX (1, width);
       child_allocation.height = MAX (1, height);
 
@@ -1228,11 +1077,24 @@ gtk_grid_size_allocate (GtkWidget     *widget,
 
   gtk_widget_set_allocation (widget, allocation);
 
-  gtk_grid_size_allocate_init (grid);
-  gtk_grid_size_allocate_pass1 (grid);
+  gtk_grid_size_allocate_init (grid, GTK_ORIENTATION_HORIZONTAL);
+  gtk_grid_size_allocate_init (grid, GTK_ORIENTATION_VERTICAL);
+  gtk_grid_size_allocate_pass1 (grid, GTK_ORIENTATION_HORIZONTAL);
+  gtk_grid_size_allocate_pass1 (grid, GTK_ORIENTATION_VERTICAL);
   gtk_grid_size_allocate_pass2 (grid);
 }
 
+static GtkSizeRequestMode
+gtk_grid_get_request_mode (GtkWidget *widget)
+{
+  GtkGridPrivate *priv = GTK_GRID (widget)->priv;
+
+  if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+    return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+  else
+    return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
 static void
 gtk_grid_class_init (GtkGridClass *class)
 {
@@ -1244,9 +1106,14 @@ 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_allocate = gtk_grid_size_allocate;
   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;
+  widget_class->get_request_mode = gtk_grid_get_request_mode;
+#if 0
+  widget_class->get_preferred_width_for_height = gtk_grid_get_preferred_width_for_height;
+  widget_class->get_preferred_height_for_width = gtk_grid_get_preferred_height_for_width;
+#endif
 
   container_class->add = gtk_grid_add;
   container_class->remove = gtk_grid_remove;
@@ -1334,34 +1201,35 @@ gtk_grid_class_init (GtkGridClass *class)
 GtkWidget *
 gtk_grid_new (void)
 {
-  return (GtkWidget *)g_object_new (GTK_TYPE_GRID, NULL);
+  return g_object_new (GTK_TYPE_GRID, NULL);
 }
 
 static void
 grid_attach (GtkGrid   *grid,
-             GtkWidget *child,
+             GtkWidget *widget,
              gint       left,
              gint       top,
              gint       width,
              gint       height)
 {
   GtkGridPrivate *priv = grid->priv;
-  GtkGridChild *grid_child;
+  GtkGridChild *child;
 
-  grid_child = g_new (GtkGridChild, 1);
-  grid_child->widget = child;
-  grid_child->left = left;
-  grid_child->top = top;
-  grid_child->width = width;
-  grid_child->height = height;
-  grid_child->hexpand = FALSE;
-  grid_child->vexpand = FALSE;
+  child = g_new (GtkGridChild, 1);
+  child->widget = widget;
+  CHILD_LEFT(child) = left;
+  CHILD_TOP(child) = top;
+  CHILD_WIDTH(child) = width;
+  CHILD_HEIGHT(child) = height;
+  CHILD_HEXPAND(child) = FALSE;
+  CHILD_VEXPAND(child) = FALSE;
 
-  priv->children = g_list_prepend (priv->children, grid_child);
+  priv->children = g_list_prepend (priv->children, child);
 
-  gtk_widget_set_parent (child, GTK_WIDGET (grid));
+  gtk_widget_set_parent (widget, GTK_WIDGET (grid));
 
-  gtk_grid_resize (grid);
+  gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
+  gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
 }
 
 void
@@ -1404,20 +1272,20 @@ gtk_grid_attach_next_to (GtkGrid         *grid,
   switch (side)
     {
     case GTK_POS_LEFT:
-      left = grid_sibling->left - width;
-      top = grid_sibling->top;
+      left = CHILD_LEFT(grid_sibling) - width;
+      top = CHILD_TOP(grid_sibling);
       break;
     case GTK_POS_RIGHT:
-      left = grid_sibling->left + grid_sibling->width;
-      top = grid_sibling->top;
+      left = CHILD_LEFT(grid_sibling) + CHILD_WIDTH(grid_sibling);
+      top = CHILD_TOP(grid_sibling);
       break;
     case GTK_POS_TOP:
-      left = grid_sibling->left;
-      top = grid_sibling->top - height;
+      left = CHILD_LEFT(grid_sibling);
+      top = CHILD_TOP(grid_sibling) - height;
       break;
     case GTK_POS_BOTTOM:
-      left = grid_sibling->left;
-      top = grid_sibling->top + grid_sibling->height;
+      left = CHILD_LEFT(grid_sibling);
+      top = CHILD_TOP(grid_sibling) + CHILD_HEIGHT(grid_sibling);
       break;
     default:
       g_assert_not_reached ();
@@ -1435,9 +1303,9 @@ gtk_grid_set_row_homogeneous (GtkGrid  *grid,
 
   priv = grid->priv;
 
-  if (priv->row_homogeneous != homogeneous)
+  if (ROWS(priv)->homogeneous != homogeneous)
     {
-      priv->row_homogeneous = homogeneous;
+      ROWS(priv)->homogeneous = homogeneous;
 
       if (gtk_widget_get_visible (GTK_WIDGET (grid)))
         gtk_widget_queue_resize (GTK_WIDGET (grid));
@@ -1449,9 +1317,12 @@ gtk_grid_set_row_homogeneous (GtkGrid  *grid,
 gboolean
 gtk_grid_get_row_homogeneous (GtkGrid *grid)
 {
+  GtkGridPrivate *priv;
   g_return_val_if_fail (GTK_IS_GRID (grid), FALSE);
 
-  return grid->priv->row_homogeneous;
+  priv = grid->priv;
+
+  return ROWS(priv)->homogeneous;
 }
 
 void
@@ -1463,9 +1334,9 @@ gtk_grid_set_column_homogeneous (GtkGrid  *grid,
 
   priv = grid->priv;
 
-  if (priv->column_homogeneous != homogeneous)
+  if (COLUMNS(priv)->homogeneous != homogeneous)
     {
-      priv->column_homogeneous = homogeneous;
+      COLUMNS(priv)->homogeneous = homogeneous;
 
       if (gtk_widget_get_visible (GTK_WIDGET (grid)))
         gtk_widget_queue_resize (GTK_WIDGET (grid));
@@ -1477,9 +1348,12 @@ gtk_grid_set_column_homogeneous (GtkGrid  *grid,
 gboolean
 gtk_grid_get_column_homogeneous (GtkGrid *grid)
 {
+  GtkGridPrivate *priv;
   g_return_val_if_fail (GTK_IS_GRID (grid), FALSE);
 
-  return grid->priv->column_homogeneous;
+  priv = grid->priv;
+
+  return COLUMNS(priv)->homogeneous;
 }
 
 void
@@ -1492,9 +1366,9 @@ gtk_grid_set_row_spacing (GtkGrid *grid,
 
   priv = grid->priv;
 
-  if (priv->row_spacing != spacing)
+  if (ROWS(priv)->spacing != spacing)
     {
-      priv->row_spacing = spacing;
+      ROWS(priv)->spacing = spacing;
 
       if (gtk_widget_get_visible (GTK_WIDGET (grid)))
         gtk_widget_queue_resize (GTK_WIDGET (grid));
@@ -1506,9 +1380,12 @@ gtk_grid_set_row_spacing (GtkGrid *grid,
 guint
 gtk_grid_get_row_spacing (GtkGrid *grid)
 {
+  GtkGridPrivate *priv;
   g_return_val_if_fail (GTK_IS_GRID (grid), 0);
 
-  return grid->priv->row_spacing;
+  priv = grid->priv;
+
+  return ROWS(priv)->spacing;
 }
 
 void
@@ -1521,9 +1398,9 @@ gtk_grid_set_column_spacing (GtkGrid *grid,
 
   priv = grid->priv;
 
-  if (priv->column_spacing != spacing)
+  if (COLUMNS(priv)->spacing != spacing)
     {
-      priv->column_spacing = spacing;
+      COLUMNS(priv)->spacing = spacing;
 
       if (gtk_widget_get_visible (GTK_WIDGET (grid)))
         gtk_widget_queue_resize (GTK_WIDGET (grid));
@@ -1535,7 +1412,11 @@ gtk_grid_set_column_spacing (GtkGrid *grid,
 guint
 gtk_grid_get_column_spacing (GtkGrid *grid)
 {
+  GtkGridPrivate *priv;
+
   g_return_val_if_fail (GTK_IS_GRID (grid), 0);
 
-  return grid->priv->column_spacing;
+  priv = grid->priv;
+
+  return COLUMNS(priv)->spacing;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]