[gtk+/grid-widget-2: 7/18] Implement get_preferred_width/height



commit 5ed82a499c6e01111ae3abaacd86bd55eaadb092
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Oct 6 11:38:23 2010 -0400

    Implement get_preferred_width/height

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



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