[gtk+/treeview-refactor] Fixed gtk_cell_layout_set_cell_data_func() to pass the correct layout object



commit 20bd8b9063c7696b8d0255283112a7481a0fbe1a
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Mon Dec 20 19:37:30 2010 +0900

    Fixed gtk_cell_layout_set_cell_data_func() to pass the correct layout object
    
    Added _gtk_cell_area_set_cell_data_func_with_proxy() to be called by
    gtk_cell_layout_set_cell_data_func() when the layouting object itself
    is not the underlying cell area.

 gtk/gtkcellarea.c   |   86 ++++++++++++++++++++++++++++++++------------------
 gtk/gtkcellarea.h   |   13 ++++++++
 gtk/gtkcelllayout.c |   11 ++++++-
 3 files changed, 78 insertions(+), 32 deletions(-)
---
diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c
index 40a5c9e..9e770d6 100644
--- a/gtk/gtkcellarea.c
+++ b/gtk/gtkcellarea.c
@@ -497,6 +497,7 @@ typedef struct {
   GtkCellLayoutDataFunc  func;
   gpointer               data;
   GDestroyNotify         destroy;
+  GtkCellLayout         *proxy;
 } CellInfo;
 
 static CellInfo       *cell_info_new       (GtkCellLayoutDataFunc  func,
@@ -1208,8 +1209,8 @@ apply_cell_attributes (GtkCellRenderer *renderer,
   /* Call any GtkCellLayoutDataFunc that may have been set by the user
    */
   if (info->func)
-    info->func (GTK_CELL_LAYOUT (data->area), renderer,
-                data->model, data->iter, info->data);
+    info->func (info->proxy ? info->proxy : GTK_CELL_LAYOUT (data->area), renderer,
+		data->model, data->iter, info->data);
 
   g_object_thaw_notify (G_OBJECT (renderer));
 }
@@ -1419,36 +1420,9 @@ gtk_cell_area_set_cell_data_func (GtkCellLayout         *cell_layout,
                                   gpointer               func_data,
                                   GDestroyNotify         destroy)
 {
-  GtkCellArea        *area   = GTK_CELL_AREA (cell_layout);
-  GtkCellAreaPrivate *priv   = area->priv;
-  CellInfo           *info;
-
-  info = g_hash_table_lookup (priv->cell_info, renderer);
-
-  if (info)
-    {
-      if (info->destroy && info->data)
-        info->destroy (info->data);
-
-      if (func)
-        {
-          info->func    = func;
-          info->data    = func_data;
-          info->destroy = destroy;
-        }
-      else
-        {
-          info->func    = NULL;
-          info->data    = NULL;
-          info->destroy = NULL;
-        }
-    }
-  else
-    {
-      info = cell_info_new (func, func_data, destroy);
+  GtkCellArea *area   = GTK_CELL_AREA (cell_layout);
 
-      g_hash_table_insert (priv->cell_info, renderer, info);
-    }
+  _gtk_cell_area_set_cell_data_func_with_proxy (area, renderer, (GFunc)func, func_data, destroy, NULL);
 }
 
 static void
@@ -3636,3 +3610,53 @@ gtk_cell_area_request_renderer (GtkCellArea        *area,
   *minimum_size += focus_line_width;
   *natural_size += focus_line_width;
 }
+
+void
+_gtk_cell_area_set_cell_data_func_with_proxy (GtkCellArea           *area,
+					      GtkCellRenderer       *cell,
+					      GFunc                  func,
+					      gpointer               func_data,
+					      GDestroyNotify         destroy,
+					      gpointer               proxy)
+{
+  GtkCellAreaPrivate *priv;
+  CellInfo           *info;
+
+  g_return_if_fail (GTK_IS_CELL_AREA (area));
+  g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
+
+  priv = area->priv;
+
+  info = g_hash_table_lookup (priv->cell_info, cell);
+
+  /* Note we do not take a reference to the proxy, the proxy is a GtkCellLayout
+   * that is forwarding it's implementation to a delegate GtkCellArea therefore
+   * it's life-cycle is longer than the area's life cycle. 
+   */
+  if (info)
+    {
+      if (info->destroy && info->data)
+	info->destroy (info->data);
+
+      if (func)
+	{
+	  info->func    = (GtkCellLayoutDataFunc)func;
+	  info->data    = func_data;
+	  info->destroy = destroy;
+	  info->proxy   = proxy;
+	}
+      else
+	{
+	  info->func    = NULL;
+	  info->data    = NULL;
+	  info->destroy = NULL;
+	  info->proxy   = NULL;
+	}
+    }
+  else
+    {
+      info = cell_info_new ((GtkCellLayoutDataFunc)func, func_data, destroy);
+
+      g_hash_table_insert (priv->cell_info, cell, info);
+    }
+}
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index d8d06cf..78d5e95 100644
--- a/gtk/gtkcellarea.h
+++ b/gtk/gtkcellarea.h
@@ -470,6 +470,19 @@ void                  gtk_cell_area_request_renderer               (GtkCellArea
                                                                     gint               *minimum_size,
                                                                     gint               *natural_size);
 
+/* For api stability, this is called from gtkcelllayout.c in order to ensure the correct
+ * object is passed to the user function in gtk_cell_layout_set_cell_data_func.
+ *
+ * This private api takes gpointer & GFunc arguments to circumvent circular header file
+ * dependancies.
+ */
+void                 _gtk_cell_area_set_cell_data_func_with_proxy  (GtkCellArea           *area,
+								    GtkCellRenderer       *cell,
+								    GFunc                  func,
+								    gpointer               func_data,
+								    GDestroyNotify         destroy,
+								    gpointer               proxy);
+
 G_END_DECLS
 
 #endif /* __GTK_CELL_AREA_H__ */
diff --git a/gtk/gtkcelllayout.c b/gtk/gtkcelllayout.c
index c54a875..5a0ae59 100644
--- a/gtk/gtkcelllayout.c
+++ b/gtk/gtkcelllayout.c
@@ -357,7 +357,16 @@ gtk_cell_layout_set_cell_data_func (GtkCellLayout         *cell_layout,
       area = iface->get_area (cell_layout);
 
       if (area)
-	gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (area), cell, func, func_data, destroy);
+	{
+	  /* Ensure that the correct proxy object is sent to 'func' */
+	  if (GTK_CELL_LAYOUT (area) != cell_layout)
+	    _gtk_cell_area_set_cell_data_func_with_proxy (area, cell, 
+							  (GFunc)func, func_data, destroy, 
+							  cell_layout);
+	  else
+	    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (area), cell, 
+						func, func_data, destroy);
+	}
     }
 }
 



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