[gtk+/grid-widget-2: 18/18] Restructure request data



commit 7fde7100ac71ae1f3c3e34a9e61797006e9af012
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Oct 10 23:55:29 2010 -0400

    Restructure request data
    
    Now all per-request data is allocated on the stack, and is kept
    separate from the grid struct itself.

 gtk/gtkgrid.c |  434 ++++++++++++++++++++++++++++-----------------------------
 1 files changed, 214 insertions(+), 220 deletions(-)
---
diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c
index af317a0..62bd967 100644
--- a/gtk/gtkgrid.c
+++ b/gtk/gtkgrid.c
@@ -1,8 +1,3 @@
-/* TODO
- * - magic expand
- * - infinite span
- */
-
 /* GTK - The GIMP Toolkit
  * Copyright (C) 2010 Red Hat, Inc.
  * Author: Matthias Clasen
@@ -37,6 +32,8 @@ typedef struct _GtkGridChild GtkGridChild;
 typedef struct _GtkGridChildAttach GtkGridChildAttach;
 typedef struct _GtkGridLine GtkGridLine;
 typedef struct _GtkGridLines GtkGridLines;
+typedef struct _GtkGridLineData GtkGridLineData;
+typedef struct _GtkGridRequest GtkGridRequest;
 
 struct _GtkGridChildAttach
 {
@@ -58,6 +55,27 @@ struct _GtkGridChild
 #define CHILD_HEIGHT(child)  ((child)->attach[GTK_ORIENTATION_VERTICAL].span)
 #define CHILD_VEXPAND(child) ((child)->attach[GTK_ORIENTATION_VERTICAL].expand)
 
+/* A GtkGridLineData struct contains row/column specific parts
+ * of the grid.
+ */
+struct _GtkGridLineData
+{
+  gint16 spacing;
+  guint homogeneous : 1;
+};
+
+struct _GtkGridPrivate
+{
+  GList *children;
+
+  GtkOrientation orientation;
+
+  GtkGridLineData linedata[2];
+};
+
+#define ROWS(priv)    (&(priv)->linedata[GTK_ORIENTATION_HORIZONTAL])
+#define COLUMNS(priv) (&(priv)->linedata[GTK_ORIENTATION_VERTICAL])
+
 /* A GtkGridLine struct represents a single row or column
  * during size requests
  */
@@ -65,6 +83,7 @@ struct _GtkGridLine
 {
   gint minimum;
   gint natural;
+  gint position;
   gint allocation;
 
   guint need_expand : 1;
@@ -72,30 +91,18 @@ struct _GtkGridLine
   guint empty       : 1;
 };
 
-/* A GtkGridLines struct represents all the rows or columns of
- * a grid, with auxiliary information.
- */
 struct _GtkGridLines
 {
   GtkGridLine *lines;
   gint min, max;
-  gint16 spacing;
-  guint homogeneous : 1;
-  guint need_recalc : 1;
 };
 
-struct _GtkGridPrivate
+struct _GtkGridRequest
 {
-  GList *children;
-
-  GtkOrientation orientation;
-
+  GtkGrid *grid;
   GtkGridLines lines[2];
 };
 
-#define ROWS(priv)    (&(priv)->lines[GTK_ORIENTATION_HORIZONTAL])
-#define COLUMNS(priv) (&(priv)->lines[GTK_ORIENTATION_VERTICAL])
-
 
 enum
 {
@@ -160,18 +167,6 @@ gtk_grid_get_property (GObject    *object,
 }
 
 static void
-lines_need_recalc (GtkGrid        *grid,
-                   GtkOrientation  orientation)
-{
-  GtkGridPrivate *priv = grid->priv;
-  GtkGridLines *lines;
-
-  lines = &priv->lines[orientation];
-
-  lines->need_recalc = TRUE;
-}
-
-static void
 gtk_grid_set_orientation (GtkGrid        *grid,
                           GtkOrientation  orientation)
 {
@@ -211,8 +206,6 @@ gtk_grid_set_orientation (GtkGrid        *grid,
             }
         }
 
-      lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
-      lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
       gtk_widget_queue_resize (GTK_WIDGET (grid));
 
       for (list = priv->children; list; list = list->next)
@@ -266,18 +259,18 @@ gtk_grid_set_property (GObject      *object,
 
 static GtkGridChild *
 find_grid_child (GtkGrid   *grid,
-                 GtkWidget *child)
+                 GtkWidget *widget)
 {
   GtkGridPrivate *priv = grid->priv;
-  GtkGridChild *grid_child;
+  GtkGridChild *child;
   GList *list;
 
   for (list = priv->children; list; list = list->next)
     {
-      grid_child = list->data;
+      child = list->data;
 
-      if (grid_child->widget == child)
-        return grid_child;
+      if (child->widget == widget)
+        return child;
     }
 
   return NULL;
@@ -355,22 +348,18 @@ gtk_grid_set_child_property (GtkContainer *container,
     {
     case CHILD_PROP_LEFT_ATTACH:
       CHILD_LEFT (grid_child) = g_value_get_int (value);
-      lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
       break;
 
     case CHILD_PROP_TOP_ATTACH:
       CHILD_TOP (grid_child) = g_value_get_int (value);
-      lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
       break;
 
    case CHILD_PROP_WIDTH:
       CHILD_WIDTH (grid_child) = g_value_get_int (value);
-      lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
       break;
 
     case CHILD_PROP_HEIGHT:
       CHILD_HEIGHT (grid_child) = g_value_get_int (value);
-      lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
       break;
 
    case CHILD_PROP_HEXPAND:
@@ -380,7 +369,6 @@ gtk_grid_set_child_property (GtkContainer *container,
 
    case CHILD_PROP_VEXPAND:
       CHILD_VEXPAND (grid_child) = g_value_get_boolean (value);
-      gtk_widget_queue_resize (GTK_WIDGET (grid));
       break;
 
     default:
@@ -394,17 +382,6 @@ 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;
-  lines->need_recalc = TRUE;
-}
-
-static void
 gtk_grid_init (GtkGrid *grid)
 {
   GtkGridPrivate *priv;
@@ -418,8 +395,11 @@ gtk_grid_init (GtkGrid *grid)
   priv->children = NULL;
   priv->orientation = GTK_ORIENTATION_HORIZONTAL;
 
-  init_lines (ROWS (priv));
-  init_lines (COLUMNS (priv));
+  priv->linedata[0].spacing = 0;
+  priv->linedata[1].spacing = 0;
+
+  priv->linedata[0].homogeneous = FALSE;
+  priv->linedata[1].homogeneous = FALSE;
 }
 
 static void grid_attach (GtkGrid   *grid,
@@ -480,14 +460,11 @@ gtk_grid_remove (GtkContainer *container,
 
           priv->children = g_list_remove (priv->children, grid_child);
 
-          g_free (grid_child);
+          g_slice_free (GtkGridChild, grid_child);
 
           if (was_visible && gtk_widget_get_visible (GTK_WIDGET (grid)))
             gtk_widget_queue_resize (GTK_WIDGET (grid));
 
-          lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
-          lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
-
           break;
         }
     }
@@ -501,14 +478,14 @@ gtk_grid_forall (GtkContainer *container,
 {
   GtkGrid *grid = GTK_GRID (container);
   GtkGridPrivate *priv = grid->priv;
-  GtkGridChild *grid_child;
+  GtkGridChild *child;
   GList *list;
 
   for (list = priv->children; list; list = list->next)
     {
-      grid_child = list->data;
+      child = list->data;
 
-      (* callback) (grid_child->widget, callback_data);
+      (* callback) (child->widget, callback_data);
     }
 }
 
@@ -529,53 +506,53 @@ gtk_grid_get_request_mode (GtkWidget *widget)
     return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
 }
 
+/* Calculates the min and max numbers for both orientations.
+ */
 static void
-gtk_grid_calculate_line_span (GtkGrid        *grid,
-                              GtkOrientation  orientation)
+gtk_grid_request_count_lines (GtkGridRequest *request)
 {
-  GtkGridPrivate *priv = grid->priv;
-  GtkGridLines *lines;
+  GtkGridPrivate *priv = request->grid->priv;
   GtkGridChild *child;
   GtkGridChildAttach *attach;
   GList *list;
-  gint min, max;
-
-  lines = &priv->lines[orientation];
+  gint min[2];
+  gint max[2];
 
-  if (!lines->need_recalc)
-    return;
+  min[0] = min[1] = G_MAXINT;
+  max[0] = max[1] = G_MININT;
 
-  min = G_MAXINT;
-  max = G_MININT;
   for (list = priv->children; list; list = list->next)
     {
       child = list->data;
-      attach = &child->attach[orientation];
+      attach = child->attach;
 
-      min = MIN (min, attach->pos);
-      max = MAX (max, attach->pos + attach->span);
+      min[0] = MIN (min[0], attach[0].pos);
+      max[0] = MAX (max[0], attach[0].pos + attach[0].span);
+      min[1] = MIN (min[1], attach[1].pos);
+      max[1] = MAX (max[1], attach[1].pos + attach[1].span);
     }
 
-  lines->min = min;
-  lines->max = max;
-  lines->need_recalc = FALSE;
+  request->lines[0].min = min[0];
+  request->lines[0].max = max[0];
+  request->lines[1].min = min[1];
+  request->lines[1].max = max[1];
 }
 
-/* set line sizes to 0, mark lines as expand
- * if they have a non-spanning expanding child
+/* Sets line sizes to 0 and marks lines as expand
+ * if they have a non-spanning expanding child.
  */
 static void
-gtk_grid_request_init (GtkGrid        *grid,
+gtk_grid_request_init (GtkGridRequest *request,
                        GtkOrientation  orientation)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
   GtkGridChild *child;
   GtkGridChildAttach *attach;
   GtkGridLines *lines;
   GList *list;
   gint i;
 
-  lines = &priv->lines[orientation];
+  lines = &request->lines[orientation];
 
   for (i = 0; i < lines->max - lines->min; i++)
     {
@@ -594,25 +571,26 @@ gtk_grid_request_init (GtkGrid        *grid,
     }
 }
 
-/* sums allocations for lines spanned by child and
- * the spacing between those lines
+/* Sums allocations for lines spanned by child and their spacing.
  */
 static gint
-compute_allocation_for_span (GtkGrid        *grid,
-                             GtkOrientation  orientation,
-                             GtkGridChild   *child)
+compute_allocation_for_child (GtkGridRequest *request,
+                              GtkGridChild   *child,
+                              GtkOrientation  orientation)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
+  GtkGridLineData *linedata;
   GtkGridLines *lines;
   GtkGridLine *line;
   GtkGridChildAttach *attach;
   gint size;
   gint i;
 
-  lines = &priv->lines[orientation];
+  linedata = &priv->linedata[orientation];
+  lines = &request->lines[orientation];
   attach = &child->attach[orientation];
 
-  size = (attach->span - 1) * lines->spacing;
+  size = (attach->span - 1) * linedata->spacing;
   for (i = 0; i < attach->span; i++)
     {
       line = &lines->lines[attach->pos - lines->min + i];
@@ -623,9 +601,9 @@ compute_allocation_for_span (GtkGrid        *grid,
 }
 
 static void
-compute_request_for_child (GtkGrid        *grid,
-                           GtkOrientation  orientation,
+compute_request_for_child (GtkGridRequest *request,
                            GtkGridChild   *child,
+                           GtkOrientation  orientation,
                            gboolean        contextual,
                            gint           *minimum,
                            gint           *natural)
@@ -634,7 +612,7 @@ compute_request_for_child (GtkGrid        *grid,
     {
       gint size;
 
-      size = compute_allocation_for_span (grid, 1 - orientation, child);
+      size = compute_allocation_for_child (request, child, 1 - orientation);
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
         gtk_widget_get_preferred_width_for_height (child->widget,
                                                    size,
@@ -653,16 +631,16 @@ compute_request_for_child (GtkGrid        *grid,
     }
 }
 
-/* set requisition to max of non-spanning children.
- * if contextual is TRUE, requires allocations of
+/* Sets requisition to max. of non-spanning children.
+ * If contextual is TRUE, requires allocations of
  * lines in the opposite orientation to be set.
  */
 static void
-gtk_grid_request_non_spanning (GtkGrid        *grid,
+gtk_grid_request_non_spanning (GtkGridRequest *request,
                                GtkOrientation  orientation,
                                gboolean        contextual)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
   GtkGridChild *child;
   GtkGridChildAttach *attach;
   GtkGridLines *lines;
@@ -671,7 +649,7 @@ gtk_grid_request_non_spanning (GtkGrid        *grid,
   gint minimum;
   gint natural;
 
-  lines = &priv->lines[orientation];
+  lines = &request->lines[orientation];
 
   for (list = priv->children; list; list = list->next)
     {
@@ -684,7 +662,7 @@ gtk_grid_request_non_spanning (GtkGrid        *grid,
       if (attach->span != 1)
         continue;
 
-      compute_request_for_child (grid, orientation, child, contextual, &minimum, &natural);
+      compute_request_for_child (request, child, orientation, contextual, &minimum, &natural);
 
       line = &lines->lines[attach->pos - lines->min];
       line->minimum = MAX (line->minimum, minimum);
@@ -692,19 +670,22 @@ gtk_grid_request_non_spanning (GtkGrid        *grid,
     }
 }
 
-/* force homogeneous sizes */
+/* Enforce homogeneous sizes.
+ */
 static void
-gtk_grid_request_homogeneous (GtkGrid        *grid,
+gtk_grid_request_homogeneous (GtkGridRequest *request,
                               GtkOrientation  orientation)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
+  GtkGridLineData *linedata;
   GtkGridLines *lines;
   gint minimum, natural;
   gint i;
 
-  lines = &priv->lines[orientation];
+  linedata = &priv->linedata[orientation];
+  lines = &request->lines[orientation];
 
-  if (!lines->homogeneous)
+  if (!linedata->homogeneous)
     return;
 
   minimum = 0;
@@ -723,19 +704,20 @@ gtk_grid_request_homogeneous (GtkGrid        *grid,
     }
 }
 
-/* deals with spanning children.
- * requires expand fields of lines to be set for
+/* Deals with spanning children.
+ * Requires expand fields of lines to be set for
  * non-spanning children.
  */
 static void
-gtk_grid_request_spanning (GtkGrid        *grid,
+gtk_grid_request_spanning (GtkGridRequest *request,
                            GtkOrientation  orientation,
                            gboolean        contextual)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
   GList *list;
   GtkGridChild *child;
   GtkGridChildAttach *attach;
+  GtkGridLineData *linedata;
   GtkGridLines *lines;
   GtkGridLine *line;
   gint minimum;
@@ -749,7 +731,8 @@ gtk_grid_request_spanning (GtkGrid        *grid,
   gint line_extra;
   gint i;
 
-  lines = &priv->lines[orientation];
+  linedata = &priv->linedata[orientation];
+  lines = &request->lines[orientation];
 
   for (list = priv->children; list; list = list->next)
     {
@@ -762,10 +745,10 @@ gtk_grid_request_spanning (GtkGrid        *grid,
       if (attach->span == 1)
         continue;
 
-      compute_request_for_child (grid, orientation, child, contextual, &minimum, &natural);
+      compute_request_for_child (request, child, orientation, contextual, &minimum, &natural);
 
-      span_minimum = (attach->span - 1) * lines->spacing;
-      span_natural = (attach->span - 1) * lines->spacing;
+      span_minimum = (attach->span - 1) * linedata->spacing;
+      span_natural = (attach->span - 1) * linedata->spacing;
       span_expand = 0;
       force_expand = FALSE;
       for (i = 0; i < attach->span; i++)
@@ -822,14 +805,15 @@ gtk_grid_request_spanning (GtkGrid        *grid,
     }
 }
 
-/* find empty and expanding lines */
+/* Marks empty and expanding lines and counts them.
+ */
 static void
-gtk_grid_compute_expand (GtkGrid        *grid,
-                         GtkOrientation  orientation,
-                         gint           *nonempty_lines,
-                         gint           *expand_lines)
+gtk_grid_request_compute_expand (GtkGridRequest *request,
+                                 GtkOrientation  orientation,
+                                 gint           *nonempty_lines,
+                                 gint           *expand_lines)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
   GtkGridChild *child;
   GtkGridChildAttach *attach;
   GList *list;
@@ -840,7 +824,7 @@ gtk_grid_compute_expand (GtkGrid        *grid,
   gint expand;
   gint empty;
 
-  lines = &priv->lines[orientation];
+  lines = &request->lines[orientation];
 
   for (i = 0; i < lines->max - lines->min; i++)
     {
@@ -919,27 +903,28 @@ gtk_grid_compute_expand (GtkGrid        *grid,
     *expand_lines = expand;
 }
 
-/* sums the minimum and natural fields of lines and
- * the spacing between lines
+/* Sums the minimum and natural fields of lines and their spacing.
  */
 static void
-gtk_grid_request_sum (GtkGrid        *grid,
+gtk_grid_request_sum (GtkGridRequest *request,
                       GtkOrientation  orientation,
                       gint           *minimum,
                       gint           *natural)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
+  GtkGridLineData *linedata;
   GtkGridLines *lines;
   gint i;
   gint min, nat;
   gint nonempty;
 
-  gtk_grid_compute_expand (grid, orientation, &nonempty, NULL);
+  gtk_grid_request_compute_expand (request, orientation, &nonempty, NULL);
 
-  lines = &priv->lines[orientation];
+  linedata = &priv->linedata[orientation];
+  lines = &request->lines[orientation];
 
-  min = (nonempty - 1) * lines->spacing;
-  nat = (nonempty - 1) * lines->spacing;
+  min = (nonempty - 1) * linedata->spacing;
+  nat = (nonempty - 1) * linedata->spacing;
 
   for (i = 0; i < lines->max - lines->min; i++)
     {
@@ -954,20 +939,20 @@ gtk_grid_request_sum (GtkGrid        *grid,
     *natural = nat;
 }
 
-/* computes minimum and natural fields of lines.
- * when contextual is TRUE, requires allocation of
+/* Computes minimum and natural fields of lines.
+ * When contextual is TRUE, requires allocation of
  * lines in the opposite orientation to be set.
  */
 static void
-gtk_grid_request_lines (GtkGrid        *grid,
-                        GtkOrientation  orientation,
-                        gboolean        contextual)
+gtk_grid_request_run (GtkGridRequest *request,
+                      GtkOrientation  orientation,
+                      gboolean        contextual)
 {
-  gtk_grid_request_init (grid, orientation);
-  gtk_grid_request_non_spanning (grid, orientation, contextual);
-  gtk_grid_request_homogeneous (grid, orientation);
-  gtk_grid_request_spanning (grid, orientation, contextual);
-  gtk_grid_request_homogeneous (grid, orientation);
+  gtk_grid_request_init (request, orientation);
+  gtk_grid_request_non_spanning (request, orientation, contextual);
+  gtk_grid_request_homogeneous (request, orientation);
+  gtk_grid_request_spanning (request, orientation, contextual);
+  gtk_grid_request_homogeneous (request, orientation);
 }
 
 /* requires that the minimum and natural fields of lines
@@ -975,11 +960,12 @@ gtk_grid_request_lines (GtkGrid        *grid,
  * by distributing total_size among lines
  */
 static void
-gtk_grid_allocate_lines (GtkGrid        *grid,
-                         GtkOrientation  orientation,
-                         gint            total_size)
+gtk_grid_request_allocate (GtkGridRequest *request,
+                           GtkOrientation  orientation,
+                           gint            total_size)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
+  GtkGridLineData *linedata;
   GtkGridLines *lines;
   GtkGridLine *line;
   gint nonempty;
@@ -990,13 +976,14 @@ gtk_grid_allocate_lines (GtkGrid        *grid,
   gint rest;
   gint size;
 
-  gtk_grid_compute_expand (grid, orientation, &nonempty, &expand);
+  gtk_grid_request_compute_expand (request, orientation, &nonempty, &expand);
 
-  lines = &priv->lines[orientation];
+  linedata = &priv->linedata[orientation];
+  lines = &request->lines[orientation];
 
-  size = total_size - (nonempty - 1) * lines->spacing;
+  size = total_size - (nonempty - 1) * linedata->spacing;
 
-  if (lines->homogeneous)
+  if (linedata->homogeneous)
     {
       extra = size / nonempty;
       rest = size % nonempty;
@@ -1073,52 +1060,73 @@ gtk_grid_allocate_lines (GtkGrid        *grid,
 }
 
 static void
+gtk_grid_request_position (GtkGridRequest *request,
+                           GtkOrientation  orientation)
+{
+  GtkGridPrivate *priv = request->grid->priv;
+  GtkGridLineData *linedata;
+  GtkGridLines *lines;
+  GtkGridLine *line;
+  gint position;
+  gint i;
+
+  linedata = &priv->linedata[orientation];
+  lines = &request->lines[orientation];
+
+  position = 0;
+  for (i = 0; i < lines->max - lines->min; i++)
+    {
+      line = &lines->lines[i];
+      if (!line->empty)
+        {
+          line->position = position;
+          position += line->allocation + linedata->spacing;
+        }
+    }
+}
+
+static void
 gtk_grid_get_size (GtkGrid        *grid,
                    GtkOrientation  orientation,
                    gint           *minimum,
                    gint           *natural)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridRequest request;
   GtkGridLines *lines;
 
-  gtk_grid_calculate_line_span (grid, orientation);
-  lines = &priv->lines[orientation];
+  request.grid = grid;
+  gtk_grid_request_count_lines (&request);
+  lines = &request.lines[orientation];
   lines->lines = g_newa (GtkGridLine, lines->max - lines->min);
 
-  gtk_grid_request_lines (grid, orientation, FALSE);
-  gtk_grid_request_sum (grid, orientation, minimum, natural);
-
-  lines->lines = NULL;
+  gtk_grid_request_run (&request, orientation, FALSE);
+  gtk_grid_request_sum (&request, orientation, minimum, natural);
 }
 
 static void
-gtk_grid_get_size_for_orientation (GtkGrid        *grid,
-                                   GtkOrientation  orientation,
-                                   gint            size,
-                                   gint           *minimum,
-                                   gint           *natural)
+gtk_grid_get_size_for_size (GtkGrid        *grid,
+                            GtkOrientation  orientation,
+                            gint            size,
+                            gint           *minimum,
+                            gint           *natural)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridRequest request;
   GtkGridLines *lines;
   gint min_size;
 
-  gtk_grid_calculate_line_span (grid, orientation);
-  lines = &priv->lines[orientation];
+  request.grid = grid;
+  gtk_grid_request_count_lines (&request);
+  lines = &request.lines[0];
   lines->lines = g_newa (GtkGridLine, lines->max - lines->min);
-
-  gtk_grid_calculate_line_span (grid, 1 - orientation);
-  lines = &priv->lines[1 - orientation];
+  lines = &request.lines[1];
   lines->lines = g_newa (GtkGridLine, lines->max - lines->min);
 
-  gtk_grid_request_lines (grid, 1 - orientation, FALSE);
-  gtk_grid_request_sum (grid, 1 - orientation, &min_size, NULL);
-  gtk_grid_allocate_lines (grid, 1 - orientation, MAX (size, min_size));
-
-  gtk_grid_request_lines (grid, orientation, TRUE);
-  gtk_grid_request_sum (grid, orientation, minimum, natural);
+  gtk_grid_request_run (&request, 1 - orientation, FALSE);
+  gtk_grid_request_sum (&request, 1 - orientation, &min_size, NULL);
+  gtk_grid_request_allocate (&request, 1 - orientation, MAX (size, min_size));
 
-  priv->lines[orientation].lines = NULL;
-  priv->lines[1 - orientation].lines = NULL;
+  gtk_grid_request_run (&request, orientation, TRUE);
+  gtk_grid_request_sum (&request, orientation, minimum, natural);
 }
 
 static void
@@ -1130,7 +1138,7 @@ gtk_grid_get_preferred_width (GtkWidget *widget,
 
   if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
 
-    gtk_grid_get_size_for_orientation (grid, GTK_ORIENTATION_HORIZONTAL, 0, minimum, natural);
+    gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_HORIZONTAL, 0, minimum, natural);
   else
     gtk_grid_get_size (grid, GTK_ORIENTATION_HORIZONTAL, minimum, natural);
 }
@@ -1143,7 +1151,7 @@ gtk_grid_get_preferred_height (GtkWidget *widget,
   GtkGrid *grid = GTK_GRID (widget);
 
   if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
-    gtk_grid_get_size_for_orientation (grid, GTK_ORIENTATION_VERTICAL, 0, minimum, natural);
+    gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_VERTICAL, 0, minimum, natural);
   else
     gtk_grid_get_size (grid, GTK_ORIENTATION_VERTICAL, minimum, natural);
 }
@@ -1157,7 +1165,7 @@ gtk_grid_get_preferred_width_for_height (GtkWidget *widget,
   GtkGrid *grid = GTK_GRID (widget);
 
   if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
-    gtk_grid_get_size_for_orientation (grid, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural);
+    gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural);
   else
     gtk_grid_get_size (grid, GTK_ORIENTATION_HORIZONTAL, minimum, natural);
 }
@@ -1171,36 +1179,32 @@ gtk_grid_get_preferred_height_for_width (GtkWidget *widget,
   GtkGrid *grid = GTK_GRID (widget);
 
   if (gtk_grid_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
-    gtk_grid_get_size_for_orientation (grid, GTK_ORIENTATION_VERTICAL, width, minimum, natural);
+    gtk_grid_get_size_for_size (grid, GTK_ORIENTATION_VERTICAL, width, minimum, natural);
   else
     gtk_grid_get_size (grid, GTK_ORIENTATION_VERTICAL, minimum, natural);
 }
 
 static void
-allocate_child (GtkGrid        *grid,
+allocate_child (GtkGridRequest *request,
                 GtkOrientation  orientation,
                 GtkGridChild   *child,
-                gint           *pos,
+                gint           *position,
                 gint           *size)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
+  GtkGridLineData *linedata;
   GtkGridLines *lines;
   GtkGridLine *line;
   GtkGridChildAttach *attach;
   gint i;
 
-  lines = &priv->lines[orientation];
+  linedata = &priv->linedata[orientation];
+  lines = &request->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;
-    }
+  *position = lines->lines[attach->pos - lines->min].position;
 
-  *size = (attach->span - 1) * lines->spacing;
+  *size = (attach->span - 1) * linedata->spacing;
   for (i = 0; i < attach->span; i++)
     {
       line = &lines->lines[attach->pos - lines->min + i];
@@ -1209,16 +1213,16 @@ allocate_child (GtkGrid        *grid,
 }
 
 static void
-gtk_grid_allocate_children (GtkGrid *grid)
+gtk_grid_request_allocate_children (GtkGridRequest *request)
 {
-  GtkGridPrivate *priv = grid->priv;
+  GtkGridPrivate *priv = request->grid->priv;
   GList *list;
   GtkGridChild *child;
   GtkAllocation allocation;
   GtkAllocation child_allocation;
   gint x, y, width, height;
 
-  gtk_widget_get_allocation (GTK_WIDGET (grid), &allocation);
+  gtk_widget_get_allocation (GTK_WIDGET (request->grid), &allocation);
 
   for (list = priv->children; list; list = list->next)
     {
@@ -1227,8 +1231,8 @@ gtk_grid_allocate_children (GtkGrid *grid)
       if (!gtk_widget_get_visible (child->widget))
         continue;
 
-      allocate_child (grid, GTK_ORIENTATION_HORIZONTAL, child, &x, &width);
-      allocate_child (grid, GTK_ORIENTATION_VERTICAL, child, &y, &height);
+      allocate_child (request, GTK_ORIENTATION_HORIZONTAL, child, &x, &width);
+      allocate_child (request, GTK_ORIENTATION_VERTICAL, child, &y, &height);
 
       child_allocation.x = allocation.x + x;
       child_allocation.y = allocation.y + y;
@@ -1239,43 +1243,35 @@ gtk_grid_allocate_children (GtkGrid *grid)
     }
 }
 
+#define GET_SIZE(allocation, orientation) (orientation == GTK_ORIENTATION_HORIZONTAL ? allocation->width : allocation->height)
+
 static void
 gtk_grid_size_allocate (GtkWidget     *widget,
                         GtkAllocation *allocation)
 {
   GtkGrid *grid = GTK_GRID (widget);
   GtkGridPrivate *priv = grid->priv;
+  GtkGridRequest request;
   GtkGridLines *lines;
 
-  gtk_grid_calculate_line_span (grid, GTK_ORIENTATION_VERTICAL);
-  lines = &priv->lines[GTK_ORIENTATION_VERTICAL];
+  request.grid = grid;
+  gtk_grid_request_count_lines (&request);
+  lines = &request.lines[0];
   lines->lines = g_newa (GtkGridLine, lines->max - lines->min);
-
-  gtk_grid_calculate_line_span (grid, GTK_ORIENTATION_HORIZONTAL);
-  lines = &priv->lines[GTK_ORIENTATION_HORIZONTAL];
+  lines = &request.lines[1];
   lines->lines = g_newa (GtkGridLine, lines->max - lines->min);
 
   gtk_widget_set_allocation (widget, allocation);
 
-  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-    {
-      gtk_grid_request_lines (grid, GTK_ORIENTATION_VERTICAL, FALSE);
-      gtk_grid_allocate_lines (grid, GTK_ORIENTATION_VERTICAL, allocation->height);
-      gtk_grid_request_lines (grid, GTK_ORIENTATION_HORIZONTAL, TRUE);
-      gtk_grid_allocate_lines (grid, GTK_ORIENTATION_HORIZONTAL, allocation->width);
-    }
-  else
-    {
-      gtk_grid_request_lines (grid, GTK_ORIENTATION_HORIZONTAL, FALSE);
-      gtk_grid_allocate_lines (grid, GTK_ORIENTATION_HORIZONTAL, allocation->width);
-      gtk_grid_request_lines (grid, GTK_ORIENTATION_VERTICAL, TRUE);
-      gtk_grid_allocate_lines (grid, GTK_ORIENTATION_VERTICAL, allocation->height);
-    }
+  gtk_grid_request_run (&request, 1 - priv->orientation, FALSE);
+  gtk_grid_request_allocate (&request, 1 - priv->orientation, GET_SIZE (allocation, 1 - priv->orientation));
+  gtk_grid_request_run (&request, priv->orientation, TRUE);
+  gtk_grid_request_allocate (&request, priv->orientation, GET_SIZE (allocation, priv->orientation));
 
-  gtk_grid_allocate_children (grid);
+  gtk_grid_request_position (&request, 0);
+  gtk_grid_request_position (&request, 1);
 
-  priv->lines[GTK_ORIENTATION_HORIZONTAL].lines = NULL;
-  priv->lines[GTK_ORIENTATION_VERTICAL].lines = NULL;
+  gtk_grid_request_allocate_children (&request);
 }
 
 static void
@@ -1395,7 +1391,7 @@ grid_attach (GtkGrid   *grid,
   GtkGridPrivate *priv = grid->priv;
   GtkGridChild *child;
 
-  child = g_new (GtkGridChild, 1);
+  child = g_slice_new (GtkGridChild);
   child->widget = widget;
   CHILD_LEFT (child) = left;
   CHILD_TOP (child) = top;
@@ -1405,8 +1401,6 @@ grid_attach (GtkGrid   *grid,
   CHILD_VEXPAND (child) = FALSE;
 
   priv->children = g_list_prepend (priv->children, child);
-  lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
-  lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
 
   gtk_widget_set_parent (widget, GTK_WIDGET (grid));
 }



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