[gtk+/grid-widget: 17/20] Allocate request-related data on the stack



commit dc256a788da341e1d5bbc074ac5a1bd6a4fac7d7
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Oct 10 19:24:03 2010 -0400

    Allocate request-related data on the stack

 gtk/gtkgrid.c |  121 ++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 78 insertions(+), 43 deletions(-)
---
diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c
index 3c5b473..af317a0 100644
--- a/gtk/gtkgrid.c
+++ b/gtk/gtkgrid.c
@@ -58,7 +58,9 @@ struct _GtkGridChild
 #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 */
+/* A GtkGridLine struct represents a single row or column
+ * during size requests
+ */
 struct _GtkGridLine
 {
   gint minimum;
@@ -71,8 +73,7 @@ struct _GtkGridLine
 };
 
 /* 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.
+ * a grid, with auxiliary information.
  */
 struct _GtkGridLines
 {
@@ -80,6 +81,7 @@ struct _GtkGridLines
   gint min, max;
   gint16 spacing;
   guint homogeneous : 1;
+  guint need_recalc : 1;
 };
 
 struct _GtkGridPrivate
@@ -119,26 +121,6 @@ enum
 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);
-
-  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);
-}
 
 static void
 gtk_grid_get_property (GObject    *object,
@@ -178,6 +160,18 @@ 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)
 {
@@ -215,16 +209,22 @@ gtk_grid_set_orientation (GtkGrid        *grid,
               CHILD_WIDTH (child)  = height;
               CHILD_HEIGHT (child) = width;
             }
+        }
+
+      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)
+        {
+          child = list->data;
+
           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_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
-      gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
 
-      gtk_widget_queue_resize (GTK_WIDGET (grid));
+        }
     }
 }
 
@@ -355,22 +355,22 @@ gtk_grid_set_child_property (GtkContainer *container,
     {
     case CHILD_PROP_LEFT_ATTACH:
       CHILD_LEFT (grid_child) = g_value_get_int (value);
-      gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
+      lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
       break;
 
     case CHILD_PROP_TOP_ATTACH:
       CHILD_TOP (grid_child) = g_value_get_int (value);
-      gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
+      lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
       break;
 
    case CHILD_PROP_WIDTH:
       CHILD_WIDTH (grid_child) = g_value_get_int (value);
-      gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
+      lines_need_recalc (grid, GTK_ORIENTATION_HORIZONTAL);
       break;
 
     case CHILD_PROP_HEIGHT:
       CHILD_HEIGHT (grid_child) = g_value_get_int (value);
-      gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
+      lines_need_recalc (grid, GTK_ORIENTATION_VERTICAL);
       break;
 
    case CHILD_PROP_HEXPAND:
@@ -401,6 +401,7 @@ init_lines (GtkGridLines *lines)
   lines->max = 0;
   lines->spacing = 0;
   lines->homogeneous = FALSE;
+  lines->need_recalc = TRUE;
 }
 
 static void
@@ -483,6 +484,10 @@ gtk_grid_remove (GtkContainer *container,
 
           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;
         }
     }
@@ -525,8 +530,8 @@ gtk_grid_get_request_mode (GtkWidget *widget)
 }
 
 static void
-gtk_grid_ensure_lines (GtkGrid        *grid,
-                       GtkOrientation  orientation)
+gtk_grid_calculate_line_span (GtkGrid        *grid,
+                              GtkOrientation  orientation)
 {
   GtkGridPrivate *priv = grid->priv;
   GtkGridLines *lines;
@@ -537,7 +542,7 @@ gtk_grid_ensure_lines (GtkGrid        *grid,
 
   lines = &priv->lines[orientation];
 
-  if (lines->lines != NULL)
+  if (!lines->need_recalc)
     return;
 
   min = G_MAXINT;
@@ -553,7 +558,7 @@ gtk_grid_ensure_lines (GtkGrid        *grid,
 
   lines->min = min;
   lines->max = max;
-  lines->lines = g_new (GtkGridLine, max - min);
+  lines->need_recalc = FALSE;
 }
 
 /* set line sizes to 0, mark lines as expand
@@ -665,7 +670,6 @@ gtk_grid_request_non_spanning (GtkGrid        *grid,
   GList *list;
   gint minimum;
   gint natural;
-  gint size;
 
   lines = &priv->lines[orientation];
 
@@ -959,8 +963,6 @@ gtk_grid_request_lines (GtkGrid        *grid,
                         GtkOrientation  orientation,
                         gboolean        contextual)
 {
-  gtk_grid_ensure_lines (grid, orientation);
-
   gtk_grid_request_init (grid, orientation);
   gtk_grid_request_non_spanning (grid, orientation, contextual);
   gtk_grid_request_homogeneous (grid, orientation);
@@ -1076,8 +1078,17 @@ gtk_grid_get_size (GtkGrid        *grid,
                    gint           *minimum,
                    gint           *natural)
 {
+  GtkGridPrivate *priv = grid->priv;
+  GtkGridLines *lines;
+
+  gtk_grid_calculate_line_span (grid, orientation);
+  lines = &priv->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;
 }
 
 static void
@@ -1087,13 +1098,27 @@ gtk_grid_get_size_for_orientation (GtkGrid        *grid,
                                    gint           *minimum,
                                    gint           *natural)
 {
+  GtkGridPrivate *priv = grid->priv;
+  GtkGridLines *lines;
   gint min_size;
 
+  gtk_grid_calculate_line_span (grid, orientation);
+  lines = &priv->lines[orientation];
+  lines->lines = g_newa (GtkGridLine, lines->max - lines->min);
+
+  gtk_grid_calculate_line_span (grid, 1 - orientation);
+  lines = &priv->lines[1 - orientation];
+  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);
+
+  priv->lines[orientation].lines = NULL;
+  priv->lines[1 - orientation].lines = NULL;
 }
 
 static void
@@ -1220,6 +1245,15 @@ gtk_grid_size_allocate (GtkWidget     *widget,
 {
   GtkGrid *grid = GTK_GRID (widget);
   GtkGridPrivate *priv = grid->priv;
+  GtkGridLines *lines;
+
+  gtk_grid_calculate_line_span (grid, GTK_ORIENTATION_VERTICAL);
+  lines = &priv->lines[GTK_ORIENTATION_VERTICAL];
+  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->lines = g_newa (GtkGridLine, lines->max - lines->min);
 
   gtk_widget_set_allocation (widget, allocation);
 
@@ -1239,6 +1273,9 @@ gtk_grid_size_allocate (GtkWidget     *widget,
     }
 
   gtk_grid_allocate_children (grid);
+
+  priv->lines[GTK_ORIENTATION_HORIZONTAL].lines = NULL;
+  priv->lines[GTK_ORIENTATION_VERTICAL].lines = NULL;
 }
 
 static void
@@ -1248,7 +1285,6 @@ gtk_grid_class_init (GtkGridClass *class)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
 
-  object_class->finalize = gtk_grid_finalize;
   object_class->get_property = gtk_grid_get_property;
   object_class->set_property = gtk_grid_set_property;
 
@@ -1369,11 +1405,10 @@ 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));
-
-  gtk_grid_free_lines (grid, GTK_ORIENTATION_HORIZONTAL);
-  gtk_grid_free_lines (grid, GTK_ORIENTATION_VERTICAL);
 }
 
 void



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