[gtk+] iconview: Bring back per-row contexts



commit e31fb77c22baf886f19cd4d5430245145d2b136b
Author: Benjamin Otte <otte redhat com>
Date:   Tue May 8 01:53:48 2012 +0200

    iconview: Bring back per-row contexts
    
    Apparently GtkCellAreaContext is broken enough to not allow multiple
    allocations...

 gtk/a11y/gtkiconviewaccessible.c |    8 ++--
 gtk/gtkiconview.c                |   80 +++++++++++++++++++++++--------------
 gtk/gtkiconviewprivate.h         |    3 +
 3 files changed, 57 insertions(+), 34 deletions(-)
---
diff --git a/gtk/a11y/gtkiconviewaccessible.c b/gtk/a11y/gtkiconviewaccessible.c
index bbb1a68..40333b7 100644
--- a/gtk/a11y/gtkiconviewaccessible.c
+++ b/gtk/a11y/gtkiconviewaccessible.c
@@ -23,7 +23,6 @@
 
 #include "gtk/gtkadjustment.h"
 #include "gtk/gtkiconviewprivate.h"
-#include "gtk/gtkcellareacontext.h"
 #include "gtk/gtkcellrendererpixbuf.h"
 #include "gtk/gtkcellrenderertext.h"
 #include "gtk/gtkpango.h"
@@ -220,11 +219,12 @@ get_pixbuf_box (GtkIconView     *icon_view,
                 GdkRectangle    *box)
 {
   GetPixbufBoxData data = { { 0, }, FALSE };
+  GtkCellAreaContext *context;
+
+  context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
 
   _gtk_icon_view_set_cell_data (icon_view, item);
-  gtk_cell_area_context_allocate (icon_view->priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-  gtk_cell_area_foreach_alloc (icon_view->priv->cell_area,
-                               icon_view->priv->cell_area_context,
+  gtk_cell_area_foreach_alloc (icon_view->priv->cell_area, context,
                                GTK_WIDGET (icon_view),
                                &item->cell_area, &item->cell_area,
                                (GtkCellAllocCallback)get_pixbuf_foreach, &data);
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index ffc47b0..59603bb 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -971,6 +971,9 @@ gtk_icon_view_init (GtkIconView *icon_view)
   icon_view->priv->item_padding = 6;
 
   icon_view->priv->draw_focus = TRUE;
+
+  icon_view->priv->row_contexts = 
+    g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
 }
 
 /* GObject methods */
@@ -1007,6 +1010,12 @@ gtk_icon_view_dispose (GObject *object)
       priv->cell_area_context = NULL;
     }
 
+  if (priv->row_contexts)
+    {
+      g_ptr_array_free (priv->row_contexts, TRUE);
+      priv->row_contexts = NULL;
+    }
+
   if (priv->cell_area)
     {
       gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);
@@ -2091,10 +2100,11 @@ gtk_icon_view_set_cursor (GtkIconView     *icon_view,
   if (start_editing && 
       icon_view->priv->cell_area)
     {
+      GtkCellAreaContext *context;
+
+      context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
       _gtk_icon_view_set_cell_data (icon_view, item);
-      gtk_cell_area_context_allocate (icon_view->priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-      gtk_cell_area_activate (icon_view->priv->cell_area,
-                              icon_view->priv->cell_area_context, 
+      gtk_cell_area_activate (icon_view->priv->cell_area, context, 
 			      GTK_WIDGET (icon_view), &item->cell_area, 
 			      0 /* XXX flags */, TRUE);
     }
@@ -2246,10 +2256,12 @@ gtk_icon_view_button_press (GtkWidget      *widget,
 
 	  if (cell != NULL && gtk_cell_renderer_is_activatable (cell))
 	    {
+	      GtkCellAreaContext *context;
+
+	      context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
+
 	      _gtk_icon_view_set_cell_data (icon_view, item);
-              gtk_cell_area_context_allocate (icon_view->priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-	      gtk_cell_area_activate (icon_view->priv->cell_area,
-                                      icon_view->priv->cell_area_context,
+	      gtk_cell_area_activate (icon_view->priv->cell_area, context,
 				      GTK_WIDGET (icon_view),
 				      &item->cell_area, 0/* XXX flags */, FALSE);
 	    }
@@ -2519,16 +2531,17 @@ gtk_icon_view_item_hit_test (GtkIconView      *icon_view,
 			     gint              height)
 {
   HitTestData data = { { x, y, width, height }, FALSE };
+  GtkCellAreaContext *context;
   GdkRectangle *item_area = &item->cell_area;
    
   if (MIN (x + width, item_area->x + item_area->width) - MAX (x, item_area->x) <= 0 ||
       MIN (y + height, item_area->y + item_area->height) - MAX (y, item_area->y) <= 0)
     return FALSE;
 
+  context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
+
   _gtk_icon_view_set_cell_data (icon_view, item);
-  gtk_cell_area_context_allocate (icon_view->priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-  gtk_cell_area_foreach_alloc (icon_view->priv->cell_area,
-                               icon_view->priv->cell_area_context,
+  gtk_cell_area_foreach_alloc (icon_view->priv->cell_area, context,
 			       GTK_WIDGET (icon_view),
 			       item_area, item_area,
 			       (GtkCellAllocCallback)hit_test, &data);
@@ -2588,16 +2601,15 @@ static gboolean
 gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view)
 {
   GtkTreePath *path;
+  GtkCellAreaContext *context;
 
   if (!icon_view->priv->cursor_item)
     return FALSE;
 
+  context = g_ptr_array_index (icon_view->priv->row_contexts, icon_view->priv->cursor_item->row);
+
   _gtk_icon_view_set_cell_data (icon_view, icon_view->priv->cursor_item);
-  gtk_cell_area_context_allocate (icon_view->priv->cell_area_context,
-                                  icon_view->priv->cursor_item->cell_area.width,
-                                  icon_view->priv->cursor_item->cell_area.height);
-  gtk_cell_area_activate (icon_view->priv->cell_area,
-                          icon_view->priv->cell_area_context,
+  gtk_cell_area_activate (icon_view->priv->cell_area, context,
                           GTK_WIDGET (icon_view),
                           &icon_view->priv->cursor_item->cell_area,
                           0 /* XXX flags */,
@@ -2827,8 +2839,10 @@ gtk_icon_view_layout (GtkIconView *icon_view)
   item_width = MIN (item_width, max_item_width);
   item_width -= 2 * priv->item_padding;
 
+  /* Clear the per row contexts */
+  g_ptr_array_set_size (icon_view->priv->row_contexts, 0);
+
   gtk_cell_area_context_reset (priv->cell_area_context);
-  gtk_cell_area_context_allocate (priv->cell_area_context, item_width, -1);
   /* because layouting is complicated. We designed an API
    * that is O(NÂ) and nonsensical.
    * And we're proud of it. */
@@ -2848,20 +2862,23 @@ gtk_icon_view_layout (GtkIconView *icon_view)
   /* Collect the heights for all rows */
   for (row = 0; row < n_rows; row++)
     {
+      GtkCellAreaContext *context = gtk_cell_area_copy_context (priv->cell_area, priv->cell_area_context);
+      g_ptr_array_add (priv->row_contexts, context);
+
       for (col = 0; col < n_columns && items; col++, items = items->next)
         {
           GtkIconViewItem *item = items->data;
 
           _gtk_icon_view_set_cell_data (icon_view, item);
           gtk_cell_area_get_preferred_height_for_width (priv->cell_area,
-                                                        priv->cell_area_context,
+                                                        context,
                                                         widget,
                                                         item_width, 
                                                         NULL, NULL);
         }
       
       sizes[row].data = GINT_TO_POINTER (row);
-      gtk_cell_area_context_get_preferred_height_for_width (priv->cell_area_context,
+      gtk_cell_area_context_get_preferred_height_for_width (context,
                                                             item_width,
                                                             &sizes[row].minimum_size,
                                                             &sizes[row].natural_size);
@@ -2884,6 +2901,9 @@ gtk_icon_view_layout (GtkIconView *icon_view)
 
   for (row = 0; row < n_rows; row++)
     {
+      GtkCellAreaContext *context = g_ptr_array_index (priv->row_contexts, row);
+      gtk_cell_area_context_allocate (context, item_width, sizes[row].minimum_size);
+
       priv->height += priv->item_padding;
 
       for (col = 0; col < n_columns && items; col++, items = items->next)
@@ -2938,6 +2958,7 @@ gtk_icon_view_paint_item (GtkIconView     *icon_view,
   GtkStyleContext *style_context;
   GtkWidget *widget = GTK_WIDGET (icon_view);
   GtkIconViewPrivate *priv = icon_view->priv;
+  GtkCellAreaContext *context;
 
   if (priv->model == NULL)
     return;
@@ -2992,8 +3013,8 @@ gtk_icon_view_paint_item (GtkIconView     *icon_view,
   cell_area.width  = item->cell_area.width;
   cell_area.height = item->cell_area.height;
 
-  gtk_cell_area_context_allocate (priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-  gtk_cell_area_render (priv->cell_area, priv->cell_area_context,
+  context = g_ptr_array_index (priv->row_contexts, item->row);
+  gtk_cell_area_render (priv->cell_area, context,
                         widget, cr, &cell_area, &cell_area, flags,
                         draw_focus);
 
@@ -3170,19 +3191,17 @@ _gtk_icon_view_get_item_at_coords (GtkIconView          *icon_view,
 	  if (only_in_cell || cell_at_pos)
 	    {
 	      GtkCellRenderer *cell = NULL;
+	      GtkCellAreaContext *context;
 
+	      context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
 	      _gtk_icon_view_set_cell_data (icon_view, item);
 
 	      if (x >= item_area->x && x <= item_area->x + item_area->width &&
 		  y >= item_area->y && y <= item_area->y + item_area->height)
-                {
-                  gtk_cell_area_context_allocate (icon_view->priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-                  cell = gtk_cell_area_get_cell_at_position (icon_view->priv->cell_area,
-                                                             icon_view->priv->cell_area_context,
-                                                             GTK_WIDGET (icon_view),
-                                                             item_area,
-                                                             x, y, NULL);
-                }
+		cell = gtk_cell_area_get_cell_at_position (icon_view->priv->cell_area, context,
+							   GTK_WIDGET (icon_view),
+							   item_area,
+							   x, y, NULL);
 
 	      if (cell_at_pos)
 		*cell_at_pos = cell;
@@ -4423,10 +4442,11 @@ gtk_icon_view_set_tooltip_cell (GtkIconView     *icon_view,
 
   if (cell)
     {
+      GtkCellAreaContext *context;
+
+      context = g_ptr_array_index (icon_view->priv->row_contexts, item->row);
       _gtk_icon_view_set_cell_data (icon_view, item);
-      gtk_cell_area_context_allocate (icon_view->priv->cell_area_context, item->cell_area.width, item->cell_area.height);
-      gtk_cell_area_get_cell_allocation (icon_view->priv->cell_area,
-                                         icon_view->priv->cell_area_context,
+      gtk_cell_area_get_cell_allocation (icon_view->priv->cell_area, context,
 					 GTK_WIDGET (icon_view),
 					 cell, &item->cell_area, &rect);
     }
diff --git a/gtk/gtkiconviewprivate.h b/gtk/gtkiconviewprivate.h
index d51ef6f..093a19c 100644
--- a/gtk/gtkiconviewprivate.h
+++ b/gtk/gtkiconviewprivate.h
@@ -42,6 +42,9 @@ struct _GtkIconViewPrivate
 
   gulong              add_editable_id;
   gulong              remove_editable_id;
+  gulong              context_changed_id;
+
+  GPtrArray          *row_contexts;
 
   gint width, height;
 



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