[gtk+/treeview-refactor] Finally really support rendering of cells in an unallocated context.



commit 487223d480578457f924470c1a1d73eb261eefd7
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Fri Nov 26 21:26:24 2010 +0900

    Finally really support rendering of cells in an unallocated context.
    
    What this means is basically that a vertically oriented GtkCellAreaBox
    will render cells properly even if the height is not constant for every
    for of data in the said GtkCellAreaContext (i.e. the height was not allocated
    by gtk_cell_area_context_allocate).
    
    This is done completely on the fly and so is much more heavy duty
    at render time (considerably slower but not visibly noticable in
    lightweight views like GtkTreeMenu). Note that cell alignments
    are not possible in an unallocated orientation, each row of data
    individually receives only enough space to render the independant
    row and no space is reserved for alignments if the size is not
    a constant size across rows in the same context.

 gtk/gtkcellareabox.c        |  139 ++++++++++++--
 gtk/gtkcellareaboxcontext.c |  437 ++++++++++++++++---------------------------
 gtk/gtkcellareaboxcontext.h |    5 -
 gtk/gtkcellareacontext.c    |  415 ++---------------------------------------
 gtk/gtkcellareacontext.h    |   34 +---
 5 files changed, 300 insertions(+), 730 deletions(-)
---
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index 02ec53f..522c397 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -167,7 +167,8 @@ static void           init_context_group     (GtkCellAreaBox        *box,
 static GSList        *get_allocated_cells    (GtkCellAreaBox        *box,
 					      GtkCellAreaBoxContext *context,
 					      GtkWidget             *widget,
-					      gint                   orientation_size);
+					      gint                   width,
+					      gint                   height);
 
 
 struct _GtkCellAreaBoxPrivate
@@ -564,6 +565,121 @@ flush_contexts (GtkCellAreaBox *box)
     }
 }
 
+/* Fall back on a completely unaligned dynamic allocation of cells
+ * when not allocated for the said orientation, alignment of cells
+ * is not done when each area gets a different size in the orientation
+ * of the box.
+ */
+static GSList *
+allocate_cells_manually (GtkCellAreaBox        *box,
+			 GtkWidget             *widget,
+			 gint                   width,
+			 gint                   height)
+{
+  GtkCellAreaBoxPrivate    *priv = box->priv;
+  GList                    *cells, *l;
+  GSList                   *allocated_cells = NULL;
+  GtkRequestedSize         *sizes;
+  gint                      i;
+  gint                      nvisible = 0, nexpand = 0, group_expand;
+  gint                      avail_size, extra_size, extra_extra;
+  gint                      position = 0;
+
+  if (!priv->cells)
+    return NULL;
+
+  cells = list_consecutive_cells (box);
+
+  /* Count the visible and expand cells */
+  for (i = 0; i < priv->groups->len; i++)
+    {
+      CellGroup *group = &g_array_index (priv->groups, CellGroup, i);
+
+      nvisible += count_visible_cells (group, &group_expand);
+      nexpand  += group_expand;
+    }
+
+  if (nvisible <= 0)
+    {
+      g_list_free (cells);
+      return NULL;
+    }
+
+  if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+    avail_size = width;
+  else
+    avail_size = height;
+
+  /* Go ahead and collect the requests on the fly */
+  sizes = g_new0 (GtkRequestedSize, nvisible);
+  for (l = cells, i = 0; l; l = l->next)
+    {
+      CellInfo *info = l->data;
+
+      if (!gtk_cell_renderer_get_visible (info->renderer))
+	continue;
+
+      if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+	gtk_cell_renderer_get_preferred_width_for_height (info->renderer, widget, height, 
+							  &sizes[i].minimum_size,
+							  &sizes[i].natural_size);
+      else
+	gtk_cell_renderer_get_preferred_height_for_width (info->renderer, widget, width, 
+							  &sizes[i].minimum_size,
+							  &sizes[i].natural_size);
+
+      avail_size -= sizes[i].minimum_size;
+
+      sizes[i].data = info;
+
+      i++;
+    }
+
+  /* Naturally distribute the allocation */
+  avail_size -= (nvisible - 1) * priv->spacing;
+  avail_size = gtk_distribute_natural_allocation (avail_size, nvisible, sizes);
+
+  /* Calculate/distribute expand for cells */
+  if (nexpand > 0)
+    {
+      extra_size  = avail_size / nexpand;
+      extra_extra = avail_size % nexpand;
+    }
+  else
+    extra_size = extra_extra = 0;
+
+  /* Create the allocated cells */
+  for (i = 0; i < nvisible; i++)
+    {
+      CellInfo      *info = sizes[i].data;
+      AllocatedCell *cell;
+
+      if (info->expand)
+	{
+	  sizes[i].minimum_size += extra_size;
+	  if (extra_extra)
+	    {
+	      sizes[i].minimum_size++;
+	      extra_extra--;
+	    }
+	}
+      
+      cell = allocated_cell_new (info->renderer, position, sizes[i].minimum_size);
+
+      allocated_cells = g_slist_prepend (allocated_cells, cell);
+	      
+      position += sizes[i].minimum_size;
+      position += priv->spacing;
+    }
+
+  g_free (sizes);
+  g_list_free (cells);
+
+  /* Note it might not be important to reverse the list here at all,
+   * we have the correct positions, no need to allocate from left to right */
+  return g_slist_reverse (allocated_cells);
+}
+
 /* Returns an allocation for each cell in the orientation of the box,
  * used in ->render()/->event() implementations to get a straight-forward
  * list of allocated cells to operate on.
@@ -572,7 +688,8 @@ static GSList *
 get_allocated_cells (GtkCellAreaBox        *box,
 		     GtkCellAreaBoxContext *context,
 		     GtkWidget             *widget,
-		     gint                   orientation_size)
+		     gint                   width,
+		     gint                   height)
 {
   GtkCellAreaBoxAllocation *group_allocs;
   GtkCellArea              *area = GTK_CELL_AREA (box);
@@ -580,14 +697,10 @@ get_allocated_cells (GtkCellAreaBox        *box,
   GList                    *cell_list;
   GSList                   *allocated_cells = NULL;
   gint                      i, j, n_allocs;
-  gboolean                  free_allocs = FALSE;
 
   group_allocs = gtk_cell_area_box_context_get_orientation_allocs (context, &n_allocs);
   if (!group_allocs)
-    {
-      group_allocs = gtk_cell_area_box_context_allocate (context, orientation_size, &n_allocs);
-      free_allocs  = TRUE;
-    }
+    return allocate_cells_manually (box, widget, width, height);
 
   for (i = 0; i < n_allocs; i++)
     {
@@ -686,9 +799,6 @@ get_allocated_cells (GtkCellAreaBox        *box,
 	}
     }
 
-  if (free_allocs)
-    g_free (group_allocs);
-
   /* Note it might not be important to reverse the list here at all,
    * we have the correct positions, no need to allocate from left to right */
   return g_slist_reverse (allocated_cells);
@@ -843,8 +953,7 @@ gtk_cell_area_box_get_cell_allocation (GtkCellArea          *area,
   /* Get a list of cells with allocation sizes decided regardless
    * of alignments and pack order etc. */
   allocated_cells = get_allocated_cells (box, box_context, widget, 
-					 priv->orientation == GTK_ORIENTATION_HORIZONTAL ?
-					 cell_area->width : cell_area->height);
+					 cell_area->width, cell_area->height);
 
   for (l = allocated_cells; l; l = l->next)
     {
@@ -921,8 +1030,7 @@ gtk_cell_area_box_event (GtkCellArea          *area,
 	  /* Get a list of cells with allocation sizes decided regardless
 	   * of alignments and pack order etc. */
 	  allocated_cells = get_allocated_cells (box, box_context, widget, 
-						 priv->orientation == GTK_ORIENTATION_HORIZONTAL ?
-						 cell_area->width : cell_area->height);
+						 cell_area->width, cell_area->height);
 
 	  for (l = allocated_cells; l; l = l->next)
 	    {
@@ -1025,8 +1133,7 @@ gtk_cell_area_box_render (GtkCellArea          *area,
   /* Get a list of cells with allocation sizes decided regardless
    * of alignments and pack order etc. */
   allocated_cells = get_allocated_cells (box, box_context, widget, 
-					 priv->orientation == GTK_ORIENTATION_HORIZONTAL ?
-					 cell_area->width : cell_area->height);
+					 cell_area->width, cell_area->height);
 
   for (l = allocated_cells; l; l = l->next)
     {
diff --git a/gtk/gtkcellareaboxcontext.c b/gtk/gtkcellareaboxcontext.c
index caf23df..c1e27cb 100644
--- a/gtk/gtkcellareaboxcontext.c
+++ b/gtk/gtkcellareaboxcontext.c
@@ -32,24 +32,23 @@ static void      gtk_cell_area_box_context_finalize                         (GOb
 
 /* GtkCellAreaContextClass */
 static void      gtk_cell_area_box_context_flush_preferred_width            (GtkCellAreaContext *context);
-static void      gtk_cell_area_box_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
-									     gint                width);
 static void      gtk_cell_area_box_context_flush_preferred_height           (GtkCellAreaContext *context);
-static void      gtk_cell_area_box_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
-									     gint                height);
 static void      gtk_cell_area_box_context_flush_allocation                 (GtkCellAreaContext *context);
 static void      gtk_cell_area_box_context_sum_preferred_width              (GtkCellAreaContext *context);
-static void      gtk_cell_area_box_context_sum_preferred_height_for_width   (GtkCellAreaContext *context,
-									     gint                width);
 static void      gtk_cell_area_box_context_sum_preferred_height             (GtkCellAreaContext *context);
-static void      gtk_cell_area_box_context_sum_preferred_width_for_height   (GtkCellAreaContext *context,
-									     gint                height);
-static void      gtk_cell_area_box_context_allocate_width                   (GtkCellAreaContext *context,
-									     gint                width);
-static void      gtk_cell_area_box_context_allocate_height                  (GtkCellAreaContext *context,
+static void      gtk_cell_area_box_context_allocate                         (GtkCellAreaContext *context,
+									     gint                width,
 									     gint                height);
 
-static void      free_cache_array                                           (GArray          *array);
+static void      free_cache_array    (GArray                *array);
+static GArray   *group_array_new     (GtkCellAreaBoxContext *context);
+static GArray   *get_array           (GtkCellAreaBoxContext *context,
+				      GtkOrientation         orientation,
+				      gint                   for_size);
+static gboolean  group_expands       (GtkCellAreaBoxContext *context,
+				      gint                   group_idx);
+static gint      count_expand_groups (GtkCellAreaBoxContext *context);
+
 
 /* CachedSize management */
 typedef struct {
@@ -57,12 +56,6 @@ typedef struct {
   gint     nat_size;
 } CachedSize;
 
-typedef struct {
-  gint     min_size;
-  gint     nat_size;
-  gboolean expand;
-} BaseSize;
-
 struct _GtkCellAreaBoxContextPrivate
 {
   /* Table of per renderer CachedSizes */
@@ -73,6 +66,9 @@ struct _GtkCellAreaBoxContextPrivate
   GHashTable *widths;
   GHashTable *heights;
 
+  /* Whether each group expands */
+  gboolean  *expand;
+
   /* Allocation info for this context if any */
   gint                      alloc_width;
   gint                      alloc_height;
@@ -88,6 +84,80 @@ free_cache_array (GArray *array)
   g_array_free (array, TRUE);
 }
 
+static GArray *
+group_array_new (GtkCellAreaBoxContext *context)
+{
+  GtkCellAreaBoxContextPrivate *priv = context->priv;
+  GArray *group_array;
+
+  group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
+  g_array_set_size (group_array, priv->base_widths->len);
+
+  return group_array;
+}
+
+static GArray *
+get_array (GtkCellAreaBoxContext *context,
+	   GtkOrientation         orientation,
+	   gint                   for_size)
+{
+  GtkCellAreaBoxContextPrivate *priv = context->priv;
+  GArray                       *array;
+
+  if (for_size < 0)
+    {
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+	array = priv->base_widths;
+      else
+	array = priv->base_heights;
+    }
+  else
+    {
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+	{
+	  array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_size));
+
+	  if (!array)
+	    array = priv->base_widths;
+	}
+      else
+	{
+	  array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_size));
+
+	  if (!array)
+	    array = priv->base_heights;
+	}
+    }
+
+  return array;
+}
+
+static gboolean 
+group_expands (GtkCellAreaBoxContext *context,
+	       gint                   group_idx)
+{
+  GtkCellAreaBoxContextPrivate *priv = context->priv;
+
+  g_assert (group_idx >= 0 && group_idx < priv->base_widths->len);
+
+  return priv->expand[group_idx];
+}
+
+static gint
+count_expand_groups (GtkCellAreaBoxContext *context)
+{
+  GtkCellAreaBoxContextPrivate *priv = context->priv;
+  gint i, expand = 0;
+
+  for (i = 0; i < priv->base_widths->len; i++)
+    {
+      if (priv->expand[i])
+	expand++;
+    }
+  
+  return expand;
+}
+
 static void
 gtk_cell_area_box_context_init (GtkCellAreaBoxContext *box_context)
 {
@@ -98,8 +168,8 @@ gtk_cell_area_box_context_init (GtkCellAreaBoxContext *box_context)
 						   GtkCellAreaBoxContextPrivate);
   priv = box_context->priv;
 
-  priv->base_widths  = g_array_new (FALSE, TRUE, sizeof (BaseSize));
-  priv->base_heights = g_array_new (FALSE, TRUE, sizeof (BaseSize));
+  priv->base_widths  = g_array_new (FALSE, TRUE, sizeof (CachedSize));
+  priv->base_heights = g_array_new (FALSE, TRUE, sizeof (CachedSize));
 
   priv->widths       = g_hash_table_new_full (g_direct_hash, g_direct_equal,
 					      NULL, (GDestroyNotify)free_cache_array);
@@ -121,19 +191,13 @@ gtk_cell_area_box_context_class_init (GtkCellAreaBoxContextClass *class)
   /* GObjectClass */
   object_class->finalize = gtk_cell_area_box_context_finalize;
 
-  context_class->flush_preferred_width            = gtk_cell_area_box_context_flush_preferred_width;
-  context_class->flush_preferred_height_for_width = gtk_cell_area_box_context_flush_preferred_height_for_width;
-  context_class->flush_preferred_height           = gtk_cell_area_box_context_flush_preferred_height;
-  context_class->flush_preferred_width_for_height = gtk_cell_area_box_context_flush_preferred_width_for_height;
-  context_class->flush_allocation                 = gtk_cell_area_box_context_flush_allocation;
-
-  context_class->sum_preferred_width            = gtk_cell_area_box_context_sum_preferred_width;
-  context_class->sum_preferred_height_for_width = gtk_cell_area_box_context_sum_preferred_height_for_width;
-  context_class->sum_preferred_height           = gtk_cell_area_box_context_sum_preferred_height;
-  context_class->sum_preferred_width_for_height = gtk_cell_area_box_context_sum_preferred_width_for_height;
+  context_class->flush_preferred_width   = gtk_cell_area_box_context_flush_preferred_width;
+  context_class->flush_preferred_height  = gtk_cell_area_box_context_flush_preferred_height;
+  context_class->flush_allocation        = gtk_cell_area_box_context_flush_allocation;
+  context_class->sum_preferred_width     = gtk_cell_area_box_context_sum_preferred_width;
+  context_class->sum_preferred_height    = gtk_cell_area_box_context_sum_preferred_height;
 
-  context_class->allocate_width  = gtk_cell_area_box_context_allocate_width;
-  context_class->allocate_height = gtk_cell_area_box_context_allocate_height;
+  context_class->allocate  = gtk_cell_area_box_context_allocate;
 
   g_type_class_add_private (object_class, sizeof (GtkCellAreaBoxContextPrivate));
 }
@@ -153,6 +217,7 @@ gtk_cell_area_box_context_finalize (GObject *object)
   g_hash_table_destroy (priv->heights);
 
   g_free (priv->orientation_allocs);
+  g_free (priv->expand);
 
   G_OBJECT_CLASS (gtk_cell_area_box_context_parent_class)->finalize (object);
 }
@@ -169,31 +234,17 @@ gtk_cell_area_box_context_flush_preferred_width (GtkCellAreaContext *context)
 
   for (i = 0; i < priv->base_widths->len; i++)
     {
-      BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
+      CachedSize *size = &g_array_index (priv->base_widths, CachedSize, i);
 
       size->min_size = 0;
       size->nat_size = 0;
     }
 
-  GTK_CELL_AREA_CONTEXT_CLASS
-    (gtk_cell_area_box_context_parent_class)->flush_preferred_width (context);
-}
-
-static void
-gtk_cell_area_box_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
-							    gint                width)
-{
-  GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
-  GtkCellAreaBoxContextPrivate *priv        = box_context->priv;
-
-  /* Flush all sizes for special -1 value */
-  if (width < 0)
-    g_hash_table_remove_all (priv->heights);
-  else
-    g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
+  /* Flush context widths as well */
+  g_hash_table_remove_all (priv->widths);
 
   GTK_CELL_AREA_CONTEXT_CLASS
-    (gtk_cell_area_box_context_parent_class)->flush_preferred_height_for_width (context, width);
+    (gtk_cell_area_box_context_parent_class)->flush_preferred_width (context);
 }
 
 static void
@@ -205,31 +256,17 @@ gtk_cell_area_box_context_flush_preferred_height (GtkCellAreaContext *context)
 
   for (i = 0; i < priv->base_heights->len; i++)
     {
-      BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i);
+      CachedSize *size = &g_array_index (priv->base_heights, CachedSize, i);
 
       size->min_size = 0;
       size->nat_size = 0;
     }
 
-  GTK_CELL_AREA_CONTEXT_CLASS
-    (gtk_cell_area_box_context_parent_class)->flush_preferred_height (context);
-}
-
-static void
-gtk_cell_area_box_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
-							    gint                height)
-{
-  GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
-  GtkCellAreaBoxContextPrivate *priv        = box_context->priv;
-
-  /* Flush all sizes for special -1 value */
-  if (height < 0)
-    g_hash_table_remove_all (priv->widths);
-  else
-    g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
+  /* Flush context heights as well */
+  g_hash_table_remove_all (priv->heights);
 
   GTK_CELL_AREA_CONTEXT_CLASS
-    (gtk_cell_area_box_context_parent_class)->flush_preferred_width_for_height (context, height);
+    (gtk_cell_area_box_context_parent_class)->flush_preferred_height (context);
 }
 
 static void
@@ -259,7 +296,7 @@ gtk_cell_area_box_context_sum_preferred_width (GtkCellAreaContext *context)
 
   for (i = 0; i < priv->base_widths->len; i++)
     {
-      BaseSize *size = &g_array_index (priv->base_widths, BaseSize, i);
+      CachedSize *size = &g_array_index (priv->base_widths, CachedSize, i);
 
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
 	{
@@ -286,55 +323,6 @@ gtk_cell_area_box_context_sum_preferred_width (GtkCellAreaContext *context)
 }
 
 static void
-gtk_cell_area_box_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
-							  gint                width)
-{
-  GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
-  GtkCellAreaBoxContextPrivate *priv        = box_context->priv;
-  GArray                    *group_array;
-  GtkCellArea               *area;
-  GtkOrientation             orientation;
-  gint                       spacing, i;
-  gint                       min_size = 0, nat_size = 0;
-
-  group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (width));
-
-  if (group_array)
-    {
-      area        = gtk_cell_area_context_get_area (context);
-      spacing     = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-      orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-      
-      for (i = 0; i < group_array->len; i++)
-	{
-	  CachedSize *size = &g_array_index (group_array, CachedSize, i);
-	  
-	  if (orientation == GTK_ORIENTATION_VERTICAL)
-	    {
-	      /* Dont add spacing for 0 size groups, they can be 0 size because
-	       * they contain only invisible cells for this round of requests 
-	       */
-	      if (min_size > 0 && size->nat_size > 0)
-		{
-		  min_size += spacing;
-		  nat_size += spacing;
-		}
-	      
-	      min_size += size->min_size;
-	      nat_size += size->nat_size;
-	    }
-	  else
-	    {
-	      min_size = MAX (min_size, size->min_size);
-	      nat_size = MAX (nat_size, size->nat_size);
-	    }
-	}
-
-      gtk_cell_area_context_push_preferred_height_for_width (context, width, min_size, nat_size);
-    }
-}
-
-static void
 gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context)
 {
   GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
@@ -350,7 +338,7 @@ gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context)
 
   for (i = 0; i < priv->base_heights->len; i++)
     {
-      BaseSize *size = &g_array_index (priv->base_heights, BaseSize, i);
+      CachedSize *size = &g_array_index (priv->base_heights, CachedSize, i);
 
       if (orientation == GTK_ORIENTATION_VERTICAL)
 	{
@@ -376,79 +364,27 @@ gtk_cell_area_box_context_sum_preferred_height (GtkCellAreaContext *context)
   gtk_cell_area_context_push_preferred_height (context, min_size, nat_size);
 }
 
-static void
-gtk_cell_area_box_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
-							  gint                height)
-{
-  GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
-  GtkCellAreaBoxContextPrivate *priv        = box_context->priv;
-  GArray                    *group_array;
-  GtkCellArea               *area;
-  GtkOrientation             orientation;
-  gint                       spacing, i;
-  gint                       min_size = 0, nat_size = 0;
-
-  group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (height));
-
-  if (group_array)
-    {
-      area        = gtk_cell_area_context_get_area (context);
-      spacing     = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-      orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-      
-      for (i = 0; i < group_array->len; i++)
-	{
-	  CachedSize *size = &g_array_index (group_array, CachedSize, i);
-	  
-	  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-	    {
-	      /* Dont add spacing for 0 size groups, they can be 0 size because
-	       * they contain only invisible cells for this round of requests 
-	       */
-	      if (min_size > 0 && size->nat_size > 0)
-		{
-		  min_size += spacing;
-		  nat_size += spacing;
-		}
-	      
-	      min_size += size->min_size;
-	      nat_size += size->nat_size;
-	    }
-	  else
-	    {
-	      min_size = MAX (min_size, size->min_size);
-	      nat_size = MAX (nat_size, size->nat_size);
-	    }
-	}
-
-      gtk_cell_area_context_push_preferred_width_for_height (context, height, min_size, nat_size);
-    }
-}
-
 static GtkRequestedSize *
 gtk_cell_area_box_context_get_requests (GtkCellAreaBoxContext *box_context,
 					GtkOrientation         orientation,
+					gint                   for_size,
 					gint                  *n_requests)
 {
   GtkCellAreaBoxContextPrivate *priv;
   GtkRequestedSize             *requests;
-  GArray                       *base_array;
-  BaseSize                     *size;
+  GArray                       *array;
+  CachedSize                   *size;
   gint                          visible_groups = 0;
   gint                          i, j;
 
   g_return_val_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context), NULL);
 
-  priv = box_context->priv;
+  priv  = box_context->priv;
+  array = get_array (box_context, orientation, for_size);
 
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    base_array = priv->base_widths;
-  else
-    base_array = priv->base_heights;
-
-  for (i = 0; i < base_array->len; i++)
+  for (i = 0; i < array->len; i++)
     {
-      size = &g_array_index (base_array, BaseSize, i);
+      size = &g_array_index (array, CachedSize, i);
 
       if (size->nat_size > 0)
 	visible_groups++;
@@ -456,9 +392,9 @@ gtk_cell_area_box_context_get_requests (GtkCellAreaBoxContext *box_context,
 
   requests = g_new (GtkRequestedSize, visible_groups);
 
-  for (j = 0, i = 0; i < base_array->len; i++)
+  for (j = 0, i = 0; i < array->len; i++)
     {
-      size = &g_array_index (base_array, BaseSize, i);
+      size = &g_array_index (array, CachedSize, i);
 
       if (size->nat_size > 0)
 	{
@@ -480,40 +416,27 @@ allocate_for_orientation (GtkCellAreaBoxContext *context,
 			  GtkOrientation         orientation,
 			  gint                   spacing,
 			  gint                   size,
+			  gint                   for_size,
 			  gint                  *n_allocs)
 {
-  GtkCellAreaBoxContextPrivate *priv = context->priv;
-  GtkRequestedSize             *orientation_sizes;
   GtkCellAreaBoxAllocation     *allocs;
+  GtkRequestedSize             *sizes;
+  GArray                       *array;
   gint                          n_expand_groups = 0;
   gint                          i, n_groups, position;
   gint                          extra_size, extra_extra;
   gint                          avail_size = size;
 
-  orientation_sizes =
-    gtk_cell_area_box_context_get_requests (context, orientation, &n_groups);
-
-  /* Count groups that expand */
-  for (i = 0; i < n_groups; i++)
-    {
-      BaseSize *size;
-      gint      group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
-
-      if (orientation == GTK_ORIENTATION_HORIZONTAL)
-	size = &g_array_index (priv->base_widths, BaseSize, group_idx);
-      else
-	size = &g_array_index (priv->base_heights, BaseSize, group_idx);
-
-      if (size->expand)
-	n_expand_groups++;
-    }
+  sizes           = gtk_cell_area_box_context_get_requests (context, orientation, for_size, &n_groups);
+  array           = get_array (context, orientation, for_size);
+  n_expand_groups = count_expand_groups (context);
 
   /* First start by naturally allocating space among groups */
   avail_size -= (n_groups - 1) * spacing;
   for (i = 0; i < n_groups; i++)
-    avail_size -= orientation_sizes[i].minimum_size;
+    avail_size -= sizes[i].minimum_size;
 
-  avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, orientation_sizes);
+  avail_size = gtk_distribute_natural_allocation (avail_size, n_groups, sizes);
 
   /* Calculate/distribute expand for groups */
   if (n_expand_groups > 0)
@@ -528,13 +451,11 @@ allocate_for_orientation (GtkCellAreaBoxContext *context,
 
   for (position = 0, i = 0; i < n_groups; i++)
     {
-      BaseSize *base_size = &g_array_index (priv->base_widths, BaseSize, i);
-
-      allocs[i].group_idx = GPOINTER_TO_INT (orientation_sizes[i].data);
+      allocs[i].group_idx = GPOINTER_TO_INT (sizes[i].data);
       allocs[i].position  = position;
-      allocs[i].size      = orientation_sizes[i].minimum_size;
+      allocs[i].size      = sizes[i].minimum_size;
 
-      if (base_size->expand)
+      if (group_expands (context, allocs[i].group_idx))
 	{
 	  allocs[i].size += extra_size;
 	  if (extra_extra)
@@ -551,57 +472,42 @@ allocate_for_orientation (GtkCellAreaBoxContext *context,
   if (n_allocs)
     *n_allocs = n_groups;
 
-  g_free (orientation_sizes);
+  g_free (sizes);
 
   return allocs;
 }
 
 static void
-gtk_cell_area_box_context_allocate_width (GtkCellAreaContext *context,
-					  gint                width)
+gtk_cell_area_box_context_allocate (GtkCellAreaContext *context,
+				    gint                width,
+				    gint                height)
 {
   GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
   GtkCellAreaBoxContextPrivate *priv        = box_context->priv;
   GtkCellArea                  *area;
   GtkOrientation                orientation;
+  gint                          spacing;
 
   area        = gtk_cell_area_context_get_area (context);
   orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
+  spacing     = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
 
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+  if (orientation == GTK_ORIENTATION_HORIZONTAL && width > 0)
     {
-      gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-
       g_free (priv->orientation_allocs);
-      priv->orientation_allocs = allocate_for_orientation (box_context, orientation, spacing, width,
+      priv->orientation_allocs = allocate_for_orientation (box_context, orientation, 
+							   spacing, width, height,
 							   &priv->n_orientation_allocs);
     }
-
-  GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate_width (context, width);
-}
-
-static void
-gtk_cell_area_box_context_allocate_height (GtkCellAreaContext *context,
-					   gint                height)
-{
-  GtkCellAreaBoxContext        *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
-  GtkCellAreaBoxContextPrivate *priv     = box_context->priv;
-  GtkCellArea                  *area;
-  GtkOrientation                orientation;
-
-  area        = gtk_cell_area_context_get_area (context);
-  orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-
-  if (orientation == GTK_ORIENTATION_VERTICAL)
+  else if (orientation == GTK_ORIENTATION_VERTICAL && height > 0)
     {
-      gint spacing = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-
       g_free (priv->orientation_allocs);
-      priv->orientation_allocs = allocate_for_orientation (box_context, orientation, spacing, height,
+      priv->orientation_allocs = allocate_for_orientation (box_context, orientation, 
+							   spacing, height, width,
 							   &priv->n_orientation_allocs);
     }
 
-  GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate_height (context, height);
+  GTK_CELL_AREA_CONTEXT_CLASS (gtk_cell_area_box_context_parent_class)->allocate (context, width, height);
 }
 
 
@@ -614,13 +520,12 @@ gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
 			       gboolean              *expand_groups)
 {
   GtkCellAreaBoxContextPrivate *priv;
-  gint                          i;
 
   g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
   g_return_if_fail (n_groups == 0 || expand_groups != NULL);
 
   /* When the group dimensions change, all info must be flushed 
-   * Note this already clears the min/nat values on the BaseSizes
+   * Note this already clears the min/nat values on the CachedSizes
    */
   gtk_cell_area_context_flush (GTK_CELL_AREA_CONTEXT (box_context));
 
@@ -628,15 +533,8 @@ gtk_cell_area_box_init_groups (GtkCellAreaBoxContext *box_context,
   g_array_set_size (priv->base_widths,  n_groups);
   g_array_set_size (priv->base_heights, n_groups);
 
-  /* Now set the expand info */
-  for (i = 0; i < n_groups; i++)
-    {
-      BaseSize *base_width  = &g_array_index (priv->base_widths,  BaseSize, i);
-      BaseSize *base_height = &g_array_index (priv->base_heights, BaseSize, i);
-
-      base_width->expand  = expand_groups[i];
-      base_height->expand = expand_groups[i];
-    }
+  g_free (priv->expand);
+  priv->expand = g_memdup (expand_groups, n_groups * sizeof (gboolean));
 }
 
 void
@@ -646,14 +544,14 @@ gtk_cell_area_box_context_push_group_width (GtkCellAreaBoxContext *box_context,
 					    gint                   natural_width)
 {
   GtkCellAreaBoxContextPrivate *priv;
-  BaseSize                     *size;
+  CachedSize                   *size;
 
   g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
 
   priv = box_context->priv;
   g_return_if_fail (group_idx < priv->base_widths->len);
 
-  size = &g_array_index (priv->base_widths, BaseSize, group_idx);
+  size = &g_array_index (priv->base_widths, CachedSize, group_idx);
   size->min_size = MAX (size->min_size, minimum_width);
   size->nat_size = MAX (size->nat_size, natural_width);
 }
@@ -677,9 +575,7 @@ gtk_cell_area_box_context_push_group_height_for_width  (GtkCellAreaBoxContext *b
   group_array = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
   if (!group_array)
     {
-      group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
-      g_array_set_size (group_array, priv->base_heights->len);
-
+      group_array = group_array_new (box_context);
       g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), group_array);
     }
 
@@ -695,14 +591,14 @@ gtk_cell_area_box_context_push_group_height (GtkCellAreaBoxContext *box_context,
 					     gint                   natural_height)
 {
   GtkCellAreaBoxContextPrivate *priv;
-  BaseSize                     *size;
+  CachedSize                   *size;
 
   g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
 
   priv = box_context->priv;
   g_return_if_fail (group_idx < priv->base_heights->len);
 
-  size = &g_array_index (priv->base_heights, BaseSize, group_idx);
+  size = &g_array_index (priv->base_heights, CachedSize, group_idx);
   size->min_size = MAX (size->min_size, minimum_height);
   size->nat_size = MAX (size->nat_size, natural_height);
 }
@@ -715,8 +611,8 @@ gtk_cell_area_box_context_push_group_width_for_height (GtkCellAreaBoxContext *bo
 						       gint                   natural_width)
 {
   GtkCellAreaBoxContextPrivate *priv;
-  GArray                    *group_array;
-  CachedSize                *size;
+  GArray                       *group_array;
+  CachedSize                   *size;
 
   g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
 
@@ -726,9 +622,7 @@ gtk_cell_area_box_context_push_group_width_for_height (GtkCellAreaBoxContext *bo
   group_array = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
   if (!group_array)
     {
-      group_array = g_array_new (FALSE, TRUE, sizeof (CachedSize));
-      g_array_set_size (group_array, priv->base_heights->len);
-
+      group_array = group_array_new (box_context);
       g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), group_array);
     }
 
@@ -744,14 +638,14 @@ gtk_cell_area_box_context_get_group_width (GtkCellAreaBoxContext *box_context,
 					   gint                  *natural_width)
 {
   GtkCellAreaBoxContextPrivate *priv;
-  BaseSize                     *size;
+  CachedSize                   *size;
 
   g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
 
   priv = box_context->priv;
   g_return_if_fail (group_idx < priv->base_widths->len);
 
-  size = &g_array_index (priv->base_widths, BaseSize, group_idx);
+  size = &g_array_index (priv->base_widths, CachedSize, group_idx);
 
   if (minimum_width)
     *minimum_width = size->min_size;
@@ -804,14 +698,14 @@ gtk_cell_area_box_context_get_group_height (GtkCellAreaBoxContext *box_context,
 					    gint                  *natural_height)
 {
   GtkCellAreaBoxContextPrivate *priv;
-  BaseSize                     *size;
+  CachedSize                   *size;
 
   g_return_if_fail (GTK_IS_CELL_AREA_BOX_CONTEXT (box_context));
 
   priv = box_context->priv;
   g_return_if_fail (group_idx < priv->base_heights->len);
 
-  size = &g_array_index (priv->base_heights, BaseSize, group_idx);
+  size = &g_array_index (priv->base_heights, CachedSize, group_idx);
 
   if (minimum_height)
     *minimum_height = size->min_size;
@@ -861,14 +755,14 @@ GtkRequestedSize *
 gtk_cell_area_box_context_get_widths (GtkCellAreaBoxContext *box_context,
 				      gint                  *n_widths)
 {
-  return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_HORIZONTAL, n_widths);
+  return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_HORIZONTAL, -1, n_widths);
 }
 
 GtkRequestedSize *
 gtk_cell_area_box_context_get_heights (GtkCellAreaBoxContext *box_context,
 				       gint                  *n_heights)
 {
-  return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_VERTICAL, n_heights);
+  return gtk_cell_area_box_context_get_requests (box_context, GTK_ORIENTATION_VERTICAL, -1, n_heights);
 }
 
 GtkCellAreaBoxAllocation *
@@ -884,21 +778,4 @@ gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context
   *n_allocs = priv->n_orientation_allocs;
 
   return priv->orientation_allocs;
-
-}
-
-GtkCellAreaBoxAllocation *
-gtk_cell_area_box_context_allocate (GtkCellAreaBoxContext *context,
-				    gint                   orientation_size,
-				    gint                  *n_allocs)
-{
-  GtkCellArea    *area;
-  GtkOrientation  orientation;
-  gint            spacing;
-
-  area        = gtk_cell_area_context_get_area (GTK_CELL_AREA_CONTEXT (context));
-  orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (area));
-  spacing     = gtk_cell_area_box_get_spacing (GTK_CELL_AREA_BOX (area));
-
-  return allocate_for_orientation (context, orientation, spacing, orientation_size, n_allocs);
 }
diff --git a/gtk/gtkcellareaboxcontext.h b/gtk/gtkcellareaboxcontext.h
index 01f7dc6..7800b0f 100644
--- a/gtk/gtkcellareaboxcontext.h
+++ b/gtk/gtkcellareaboxcontext.h
@@ -129,11 +129,6 @@ GtkCellAreaBoxAllocation *
 gtk_cell_area_box_context_get_orientation_allocs (GtkCellAreaBoxContext *context,
 						  gint                  *n_allocs);
 
-GtkCellAreaBoxAllocation *
-gtk_cell_area_box_context_allocate (GtkCellAreaBoxContext *context,
-				    gint                   orientation_size,
-				    gint                  *n_allocs);
-
 G_END_DECLS
 
 #endif /* __GTK_CELL_AREA_BOX_CONTEXT_H__ */
diff --git a/gtk/gtkcellareacontext.c b/gtk/gtkcellareacontext.c
index 6164670..5a3ee8b 100644
--- a/gtk/gtkcellareacontext.c
+++ b/gtk/gtkcellareacontext.c
@@ -28,7 +28,6 @@
 #include "gtkprivate.h"
 
 /* GObjectClass */
-static void      gtk_cell_area_context_finalize                       (GObject            *object);
 static void      gtk_cell_area_context_dispose                        (GObject            *object);
 static void      gtk_cell_area_context_get_property                   (GObject            *object,
 								       guint               prop_id,
@@ -41,26 +40,12 @@ static void      gtk_cell_area_context_set_property                   (GObject
 
 /* GtkCellAreaContextClass */
 static void      gtk_cell_area_context_real_flush_preferred_width            (GtkCellAreaContext *context);
-static void      gtk_cell_area_context_real_flush_preferred_height_for_width (GtkCellAreaContext *context,
-									      gint                width);
 static void      gtk_cell_area_context_real_flush_preferred_height           (GtkCellAreaContext *context);
-static void      gtk_cell_area_context_real_flush_preferred_width_for_height (GtkCellAreaContext *context,
-									      gint                height);
 static void      gtk_cell_area_context_real_flush_allocation                 (GtkCellAreaContext *context);
-static void      gtk_cell_area_context_real_allocate_width                   (GtkCellAreaContext *context,
-									      gint                width);
-static void      gtk_cell_area_context_real_allocate_height                  (GtkCellAreaContext *context,
+static void      gtk_cell_area_context_real_allocate                         (GtkCellAreaContext *context,
+							 		      gint                width,
 									      gint                height);
 
-/* CachedSize management */
-typedef struct {
-  gint min_size;
-  gint nat_size;
-} CachedSize;
-
-static CachedSize *cached_size_new  (gint min_size, gint nat_size);
-static void        cached_size_free (CachedSize *size);
-
 struct _GtkCellAreaContextPrivate
 {
   GtkCellArea *cell_area;
@@ -71,9 +56,6 @@ struct _GtkCellAreaContextPrivate
   gint         nat_height;
   gint         alloc_width;
   gint         alloc_height;
-
-  GHashTable  *widths;
-  GHashTable  *heights;
 };
 
 enum {
@@ -85,14 +67,6 @@ enum {
   PROP_NAT_HEIGHT
 };
 
-enum {
-  SIGNAL_WIDTH_CHANGED,
-  SIGNAL_HEIGHT_CHANGED,
-  LAST_SIGNAL
-};
-
-static guint cell_area_context_signals[LAST_SIGNAL] = { 0 };
-
 G_DEFINE_TYPE (GtkCellAreaContext, gtk_cell_area_context, G_TYPE_OBJECT);
 
 static void
@@ -109,10 +83,6 @@ gtk_cell_area_context_init (GtkCellAreaContext *context)
   priv->nat_width  = -1;
   priv->min_height = -1;
   priv->nat_height = -1;
-  priv->widths     = g_hash_table_new_full (g_direct_hash, g_direct_equal,
-					    NULL, (GDestroyNotify)cached_size_free);
-  priv->heights    = g_hash_table_new_full (g_direct_hash, g_direct_equal,
-					    NULL, (GDestroyNotify)cached_size_free);
 }
 
 static void 
@@ -121,45 +91,17 @@ gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
   GObjectClass     *object_class = G_OBJECT_CLASS (class);
 
   /* GObjectClass */
-  object_class->finalize     = gtk_cell_area_context_finalize;
   object_class->dispose      = gtk_cell_area_context_dispose;
   object_class->get_property = gtk_cell_area_context_get_property;
   object_class->set_property = gtk_cell_area_context_set_property;
 
   /* GtkCellAreaContextClass */
-  class->flush_preferred_width            = gtk_cell_area_context_real_flush_preferred_width;
-  class->flush_preferred_height_for_width = gtk_cell_area_context_real_flush_preferred_height_for_width;
-  class->flush_preferred_height           = gtk_cell_area_context_real_flush_preferred_height;
-  class->flush_preferred_width_for_height = gtk_cell_area_context_real_flush_preferred_width_for_height;
-  class->flush_allocation                 = gtk_cell_area_context_real_flush_allocation;
-
-  class->sum_preferred_width            = NULL;
-  class->sum_preferred_height_for_width = NULL;
-  class->sum_preferred_height           = NULL;
-  class->sum_preferred_width_for_height = NULL;
-
-  class->allocate_width  = gtk_cell_area_context_real_allocate_width;
-  class->allocate_height = gtk_cell_area_context_real_allocate_height;
-
-  cell_area_context_signals[SIGNAL_HEIGHT_CHANGED] =
-    g_signal_new (I_("height-changed"),
-		  G_TYPE_FROM_CLASS (object_class),
-		  G_SIGNAL_RUN_LAST,
-		  0, /* Class offset (just a notification, no class handler) */
-		  NULL, NULL,
-		  _gtk_marshal_VOID__INT_INT_INT,
-		  G_TYPE_NONE, 3,
-		  G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
-
-  cell_area_context_signals[SIGNAL_WIDTH_CHANGED] =
-    g_signal_new (I_("width-changed"),
-		  G_TYPE_FROM_CLASS (object_class),
-		  G_SIGNAL_RUN_LAST,
-		  0, /* Class offset (just a notification, no class handler) */
-		  NULL, NULL,
-		  _gtk_marshal_VOID__INT_INT_INT,
-		  G_TYPE_NONE, 3,
-		  G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+  class->flush_preferred_width   = gtk_cell_area_context_real_flush_preferred_width;
+  class->flush_preferred_height  = gtk_cell_area_context_real_flush_preferred_height;
+  class->flush_allocation        = gtk_cell_area_context_real_flush_allocation;
+  class->sum_preferred_width     = NULL;
+  class->sum_preferred_height    = NULL;
+  class->allocate                = gtk_cell_area_context_real_allocate;
 
   g_object_class_install_property (object_class,
                                    PROP_CELL_AREA,
@@ -212,45 +154,10 @@ gtk_cell_area_context_class_init (GtkCellAreaContextClass *class)
   g_type_class_add_private (object_class, sizeof (GtkCellAreaContextPrivate));
 }
 
-
-
-/*************************************************************
- *                      Cached Sizes                         *
- *************************************************************/
-static CachedSize *
-cached_size_new (gint min_size, 
-		 gint nat_size)
-{
-  CachedSize *size = g_slice_new (CachedSize);
-
-  size->min_size = min_size;
-  size->nat_size = nat_size;
-
-  return size;
-}
-
-static void
-cached_size_free (CachedSize *size)
-{
-  g_slice_free (CachedSize, size);
-}
-
 /*************************************************************
  *                      GObjectClass                         *
  *************************************************************/
 static void
-gtk_cell_area_context_finalize (GObject *object)
-{
-  GtkCellAreaContext        *context = GTK_CELL_AREA_CONTEXT (object);
-  GtkCellAreaContextPrivate *priv = context->priv;
-
-  g_hash_table_destroy (priv->widths);
-  g_hash_table_destroy (priv->heights);
-
-  G_OBJECT_CLASS (gtk_cell_area_context_parent_class)->finalize (object);
-}
-
-static void
 gtk_cell_area_context_dispose (GObject *object)
 {
   GtkCellAreaContext        *context = GTK_CELL_AREA_CONTEXT (object);
@@ -336,40 +243,6 @@ gtk_cell_area_context_real_flush_preferred_width (GtkCellAreaContext *context)
 }
 
 static void
-notify_invalid_height (gpointer            width_ptr,
-		       CachedSize         *size,
-		       GtkCellAreaContext *context)
-{
-  gint width = GPOINTER_TO_INT (width_ptr);
-
-  /* Notify size invalidated */
-  g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED], 
-		 0, width, -1, -1);
-}
-
-static void
-gtk_cell_area_context_real_flush_preferred_height_for_width (GtkCellAreaContext *context,
-							     gint                width)
-{
-  GtkCellAreaContextPrivate *priv = context->priv;
-
-  /* Flush all sizes for special -1 value */
-  if (width < 0)
-    {
-      g_hash_table_foreach (priv->heights, (GHFunc)notify_invalid_height, context);
-      g_hash_table_remove_all (priv->heights);
-    }
-  else
-    {
-      g_hash_table_remove (priv->heights, GINT_TO_POINTER (width));
-
-      /* Notify size invalidated */
-      g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED], 
-		     0, width, -1, -1);
-    }
-}
-
-static void
 gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context)
 {
   GtkCellAreaContextPrivate *priv = context->priv;
@@ -384,40 +257,6 @@ gtk_cell_area_context_real_flush_preferred_height (GtkCellAreaContext *context)
 }
 
 static void
-notify_invalid_width (gpointer            height_ptr,
-		      CachedSize         *size,
-		      GtkCellAreaContext *context)
-{
-  gint height = GPOINTER_TO_INT (height_ptr);
-
-  /* Notify size invalidated */
-  g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED], 
-		 0, height, -1, -1);
-}
-
-static void
-gtk_cell_area_context_real_flush_preferred_width_for_height (GtkCellAreaContext *context,
-							     gint                height)
-{
-  GtkCellAreaContextPrivate *priv = context->priv;
-
-  /* Flush all sizes for special -1 value */
-  if (height < 0)
-    {
-      g_hash_table_foreach (priv->widths, (GHFunc)notify_invalid_width, context);
-      g_hash_table_remove_all (priv->widths);
-    }
-  else
-    {
-      g_hash_table_remove (priv->widths, GINT_TO_POINTER (height));
-
-      /* Notify size invalidated */
-      g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED], 
-		     0, height, -1, -1);
-    }
-}
-
-static void
 gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context)
 {
   GtkCellAreaContextPrivate *priv = context->priv;
@@ -427,24 +266,16 @@ gtk_cell_area_context_real_flush_allocation (GtkCellAreaContext *context)
 }
 
 static void
-gtk_cell_area_context_real_allocate_width (GtkCellAreaContext *context,
-					   gint                width)
-{
-  GtkCellAreaContextPrivate *priv = context->priv;
-
-  priv->alloc_width = width;
-}
-
-static void
-gtk_cell_area_context_real_allocate_height (GtkCellAreaContext *context,
-					    gint                height)
+gtk_cell_area_context_real_allocate (GtkCellAreaContext *context,
+				     gint                width,
+				     gint                height)
 {
   GtkCellAreaContextPrivate *priv = context->priv;
 
+  priv->alloc_width  = width;
   priv->alloc_height = height;
 }
 
-
 /*************************************************************
  *                            API                            *
  *************************************************************/
@@ -466,9 +297,7 @@ gtk_cell_area_context_flush (GtkCellAreaContext *context)
   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
 
   gtk_cell_area_context_flush_preferred_width (context);
-  gtk_cell_area_context_flush_preferred_height_for_width (context, -1);
   gtk_cell_area_context_flush_preferred_height (context);
-  gtk_cell_area_context_flush_preferred_width_for_height (context, -1);
   gtk_cell_area_context_flush_allocation (context);
 }
 
@@ -481,15 +310,6 @@ gtk_cell_area_context_flush_preferred_width (GtkCellAreaContext *context)
 }
 
 void
-gtk_cell_area_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
-							gint                for_width)
-{
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_height_for_width (context, for_width);
-}
-
-void
 gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context)
 {
   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
@@ -498,15 +318,6 @@ gtk_cell_area_context_flush_preferred_height (GtkCellAreaContext *context)
 }
 
 void
-gtk_cell_area_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
-							gint                for_height)
-{
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  GTK_CELL_AREA_CONTEXT_GET_CLASS (context)->flush_preferred_width_for_height (context, for_height);
-}
-
-void
 gtk_cell_area_context_flush_allocation (GtkCellAreaContext *context)
 {
   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
@@ -528,20 +339,6 @@ gtk_cell_area_context_sum_preferred_width (GtkCellAreaContext *context)
 }
 
 void
-gtk_cell_area_context_sum_preferred_height_for_width (GtkCellAreaContext *context,
-						      gint                for_width)
-{
-  GtkCellAreaContextClass *class;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
-
-  if (class->sum_preferred_height_for_width)
-    class->sum_preferred_height_for_width (context, for_width);
-}
-
-void
 gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
 {
   GtkCellAreaContextClass *class;
@@ -555,8 +352,9 @@ gtk_cell_area_context_sum_preferred_height (GtkCellAreaContext *context)
 }
 
 void
-gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *context,
-						      gint                for_height)
+gtk_cell_area_context_allocate (GtkCellAreaContext *context,
+				gint                width,
+				gint                height)
 {
   GtkCellAreaContextClass *class;
 
@@ -564,34 +362,7 @@ gtk_cell_area_context_sum_preferred_width_for_height (GtkCellAreaContext *contex
 
   class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
 
-  if (class->sum_preferred_width_for_height)
-    class->sum_preferred_width_for_height (context, for_height);
-}
-
-void
-gtk_cell_area_context_allocate_width (GtkCellAreaContext *context,
-				      gint                width)
-{
-  GtkCellAreaContextClass *class;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
-
-  class->allocate_width (context, width);
-}
-
-void
-gtk_cell_area_context_allocate_height (GtkCellAreaContext *context,
-				       gint                height)
-{
-  GtkCellAreaContextClass *class;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  class = GTK_CELL_AREA_CONTEXT_GET_CLASS (context);
-
-  class->allocate_height (context, height);
+  class->allocate (context, width, height);
 }
 
 void
@@ -613,39 +384,6 @@ gtk_cell_area_context_get_preferred_width (GtkCellAreaContext *context,
 }
 
 void
-gtk_cell_area_context_get_preferred_height_for_width (GtkCellAreaContext *context,
-						      gint                for_width,
-						      gint               *minimum_height,
-						      gint               *natural_height)
-{
-  GtkCellAreaContextPrivate *priv;
-  CachedSize                *size;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  priv = context->priv;
-
-  size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
-
-  if (size)
-    {
-      if (minimum_height)
-	*minimum_height = size->min_size;
-
-      if (natural_height)
-	*natural_height = size->nat_size;
-    }
-  else
-    {
-      if (minimum_height)
-	*minimum_height = -1;
-
-      if (natural_height)
-	*natural_height = -1;
-    }
-}
-
-void
 gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
 					    gint               *minimum_height,
 					    gint               *natural_height)
@@ -664,39 +402,6 @@ gtk_cell_area_context_get_preferred_height (GtkCellAreaContext *context,
 }
 
 void
-gtk_cell_area_context_get_preferred_width_for_height (GtkCellAreaContext *context,
-						      gint                for_height,
-						      gint               *minimum_width,
-						      gint               *natural_width)
-{
-  GtkCellAreaContextPrivate *priv;
-  CachedSize                *size;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  priv = context->priv;
-
-  size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
-
-  if (size)
-    {
-      if (minimum_width)
-	*minimum_width = size->min_size;
-
-      if (natural_width)
-	*natural_width = size->nat_size;
-    }
-  else
-    {
-      if (minimum_width)
-	*minimum_width = -1;
-
-      if (natural_width)
-	*natural_width = -1;
-    }
-}
-
-void
 gtk_cell_area_context_get_allocation (GtkCellAreaContext *context,
 				      gint               *width,
 				      gint               *height)
@@ -745,50 +450,6 @@ gtk_cell_area_context_push_preferred_width (GtkCellAreaContext *context,
 }
 
 void
-gtk_cell_area_context_push_preferred_height_for_width (GtkCellAreaContext *context,
-						       gint                for_width,
-						       gint                minimum_height,
-						       gint                natural_height)
-{
-  GtkCellAreaContextPrivate *priv;
-  CachedSize             *size;
-  gboolean                changed = FALSE;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  priv = context->priv;
-
-  size = g_hash_table_lookup (priv->heights, GINT_TO_POINTER (for_width));
-
-  if (!size)
-    {
-      size = cached_size_new (minimum_height, natural_height);
-
-      g_hash_table_insert (priv->heights, GINT_TO_POINTER (for_width), size);
-
-      changed = TRUE;
-    }
-  else
-    {
-      if (minimum_height > size->min_size)
-	{
-	  size->min_size = minimum_height;
-	  changed = TRUE;
-	}
-
-      if (natural_height > size->nat_size)
-	{
-	  size->nat_size = natural_height;
-	  changed = TRUE;
-	}
-    }
-  
-  if (changed)
-    g_signal_emit (context, cell_area_context_signals[SIGNAL_HEIGHT_CHANGED], 0, 
-		   for_width, size->min_size, size->nat_size);
-}
-
-void
 gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
 					     gint                minimum_height,
 					     gint                natural_height)
@@ -817,47 +478,3 @@ gtk_cell_area_context_push_preferred_height (GtkCellAreaContext *context,
 
   g_object_thaw_notify (G_OBJECT (context));
 }
-
-void
-gtk_cell_area_context_push_preferred_width_for_height (GtkCellAreaContext *context,
-						       gint                for_height,
-						       gint                minimum_width,
-						       gint                natural_width)
-{
-  GtkCellAreaContextPrivate *priv;
-  CachedSize             *size;
-  gboolean                changed = FALSE;
-
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-
-  priv = context->priv;
-
-  size = g_hash_table_lookup (priv->widths, GINT_TO_POINTER (for_height));
-
-  if (!size)
-    {
-      size = cached_size_new (minimum_width, natural_width);
-
-      g_hash_table_insert (priv->widths, GINT_TO_POINTER (for_height), size);
-
-      changed = TRUE;
-    }
-  else
-    {
-      if (minimum_width > size->min_size)
-	{
-	  size->min_size = minimum_width;
-	  changed = TRUE;
-	}
-
-      if (natural_width > size->nat_size)
-	{
-	  size->nat_size = natural_width;
-	  changed = TRUE;
-	}
-    }
-  
-  if (changed)
-    g_signal_emit (context, cell_area_context_signals[SIGNAL_WIDTH_CHANGED], 0, 
-		   for_height, size->min_size, size->nat_size);
-}
diff --git a/gtk/gtkcellareacontext.h b/gtk/gtkcellareacontext.h
index 8e3621f..0796908 100644
--- a/gtk/gtkcellareacontext.h
+++ b/gtk/gtkcellareacontext.h
@@ -74,9 +74,8 @@ struct _GtkCellAreaContextClass
 
   /* Store an allocation value for a GtkCellArea contextual to a range of
    * treemodel rows */
-  void    (* allocate_width)                     (GtkCellAreaContext *context,
-						  gint                width);
-  void    (* allocate_height)                    (GtkCellAreaContext *context,
+  void    (* allocate)                           (GtkCellAreaContext *context,
+						  gint                width,
 						  gint                height);
 
   /* Padding for future expansion */
@@ -93,44 +92,27 @@ GtkCellArea *gtk_cell_area_context_get_area                         (GtkCellArea
 /* Apis for GtkCellArea clients to flush the cache */
 void         gtk_cell_area_context_flush                            (GtkCellAreaContext *context);
 void         gtk_cell_area_context_flush_preferred_width            (GtkCellAreaContext *context);
-void         gtk_cell_area_context_flush_preferred_height_for_width (GtkCellAreaContext *context,
-								     gint                for_width);
 void         gtk_cell_area_context_flush_preferred_height           (GtkCellAreaContext *context);
-void         gtk_cell_area_context_flush_preferred_width_for_height (GtkCellAreaContext *context,
-								     gint                for_height);
 void         gtk_cell_area_context_flush_allocation                 (GtkCellAreaContext *context);
 
 /* Apis for GtkCellArea clients to sum up the results of a series of requests, this
  * call is required to reduce the processing while calculating the size of each row */
 void         gtk_cell_area_context_sum_preferred_width              (GtkCellAreaContext *context);
-void         gtk_cell_area_context_sum_preferred_height_for_width   (GtkCellAreaContext *context,
-								     gint                for_width);
 void         gtk_cell_area_context_sum_preferred_height             (GtkCellAreaContext *context);
-void         gtk_cell_area_context_sum_preferred_width_for_height   (GtkCellAreaContext *context,
-								     gint                for_height);
 
 /* Apis to set an allocation size in one dimension or another, the subclass specific context
  * will store allocated positions/sizes for individual cells or groups of cells */
-void         gtk_cell_area_context_allocate_width                   (GtkCellAreaContext *context,
-								     gint                width);
-void         gtk_cell_area_context_allocate_height                  (GtkCellAreaContext *context,
+void         gtk_cell_area_context_allocate                         (GtkCellAreaContext *context,
+								     gint                width,
 								     gint                height);
 
 /* Apis for GtkCellArea clients to consult cached values for multiple GtkTreeModel rows */
 void         gtk_cell_area_context_get_preferred_width              (GtkCellAreaContext *context,
 								     gint               *minimum_width,
 								     gint               *natural_width);
-void         gtk_cell_area_context_get_preferred_height_for_width   (GtkCellAreaContext *context,
-								     gint                for_width,
-								     gint               *minimum_height,
-								     gint               *natural_height);
 void         gtk_cell_area_context_get_preferred_height             (GtkCellAreaContext *context,
 								     gint               *minimum_height,
 								     gint               *natural_height);
-void         gtk_cell_area_context_get_preferred_width_for_height   (GtkCellAreaContext *context,
-								     gint                for_height,
-								     gint               *minimum_width,
-								     gint               *natural_width);
 void         gtk_cell_area_context_get_allocation                   (GtkCellAreaContext *context,
 								     gint               *width,
 								     gint               *height);
@@ -139,17 +121,9 @@ void         gtk_cell_area_context_get_allocation                   (GtkCellArea
 void         gtk_cell_area_context_push_preferred_width             (GtkCellAreaContext *context,
 								     gint                minimum_width,
 								     gint                natural_width);
-void         gtk_cell_area_context_push_preferred_height_for_width  (GtkCellAreaContext *context,
-								     gint                for_width,
-								     gint                minimum_height,
-								     gint                natural_height);
 void         gtk_cell_area_context_push_preferred_height            (GtkCellAreaContext *context,
 								     gint                minimum_height,
 								     gint                natural_height);
-void         gtk_cell_area_context_push_preferred_width_for_height  (GtkCellAreaContext *context,
-								     gint                for_height,
-								     gint                minimum_width,
-								     gint                natural_width);
 
 G_END_DECLS
 



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