]> Pileus Git - ~andy/gtk/commitdiff
Added 'background_area' calculation to GtkCellAreaClass->foreach_alloc vfunc
authorTristan Van Berkom <tristan.van.berkom@gmail.com>
Wed, 8 Dec 2010 12:18:05 +0000 (21:18 +0900)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Wed, 8 Dec 2010 12:18:05 +0000 (21:18 +0900)
This allows us to reduce code allocation code paths in subclasses, as
a result GtkCellArea implements the ->render() vfunc and the subclass
only decides the cell area and background area distributions in a single
code path.

gtk/gtkcellarea.c
gtk/gtkcellarea.h
gtk/gtkcellareabox.c

index 1fabc94d0d2b3a188e929088291b33efd1d03890..73831b9939c7eaafd70e43a1391438b627fe16a8 100644 (file)
  * The #GtkCellArea introduces <emphasis>cell properties</emphasis> for #GtkCellRenderers in very
  * much the same way that #GtkContainer introduces <link linkend="child-properties">child properties</link>
  * for #GtkWidgets. This provides some general interfaces for defining the relationship cell areas
- * have with thier cells. For instance in a #GtkCellAreaBox a cell might "expand" and recieve extra
+ * have with their cells. For instance in a #GtkCellAreaBox a cell might "expand" and recieve extra
  * space when the area is allocated more than it's full natural request, or a cell might be configured
  * to "align" with adjacent rows which were requested and rendered with the same #GtkCellAreaContext.
  *
@@ -371,6 +371,14 @@ static gint      gtk_cell_area_real_event                          (GtkCellArea
                                                                    GdkEvent             *event,
                                                                    const GdkRectangle   *cell_area,
                                                                    GtkCellRendererState  flags);
+static void      gtk_cell_area_real_render                         (GtkCellArea          *area,
+                                                                   GtkCellAreaContext   *context,
+                                                                   GtkWidget            *widget,
+                                                                   cairo_t              *cr,
+                                                                   const GdkRectangle   *background_area,
+                                                                   const GdkRectangle   *cell_area,
+                                                                   GtkCellRendererState  flags,
+                                                                   gboolean              paint_focus);
 static void      gtk_cell_area_real_apply_attributes               (GtkCellArea           *area,
                                                                    GtkTreeModel          *tree_model,
                                                                    GtkTreeIter           *iter,
@@ -430,6 +438,18 @@ typedef struct {
   GdkRectangle     allocation;
 } RendererAllocationData;
 
+/* Used in foreach loop to render cells */
+typedef struct {
+  GtkCellArea         *area;
+  GtkWidget           *widget;
+  cairo_t             *cr;
+  GdkRectangle         focus_rect;
+  GtkCellRendererState render_flags;
+  guint                paint_focus : 1;
+  guint                focus_all   : 1;
+  guint                first_focus : 1;
+} CellRenderData;
+
 /* Used in foreach loop to get a cell by position */
 typedef struct {
   gint             x;
@@ -587,7 +607,7 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
   class->remove           = NULL;
   class->foreach          = NULL;
   class->event            = gtk_cell_area_real_event;
-  class->render           = NULL;
+  class->render           = gtk_cell_area_real_render;
   class->apply_attributes = gtk_cell_area_real_apply_attributes;
 
   /* geometry */
@@ -1005,6 +1025,103 @@ gtk_cell_area_real_event (GtkCellArea          *area,
   return retval;
 }
 
+static gboolean
+render_cell (GtkCellRenderer        *renderer,
+            const GdkRectangle     *cell_area,
+            const GdkRectangle     *cell_background,
+            CellRenderData         *data)
+{
+  GtkCellRenderer      *focus_cell;
+  GtkCellRendererState  flags;
+  GdkRectangle          inner_area;
+
+  focus_cell = gtk_cell_area_get_focus_cell (data->area);
+  flags      = data->render_flags;
+
+  gtk_cell_area_inner_cell_area (data->area, data->widget, cell_area, &inner_area);
+
+  if ((flags & GTK_CELL_RENDERER_FOCUSED) &&
+      (data->focus_all || 
+       (focus_cell && 
+       (renderer == focus_cell || 
+        gtk_cell_area_is_focus_sibling (data->area, focus_cell, renderer)))))
+    {
+      GdkRectangle cell_focus;
+
+      gtk_cell_renderer_get_aligned_area (renderer, data->widget, flags, &inner_area, &cell_focus);
+
+      if (data->first_focus)
+       {
+         data->first_focus = FALSE;
+         data->focus_rect  = cell_focus;
+       }
+      else
+       {
+         gdk_rectangle_union (&data->focus_rect, &cell_focus, &data->focus_rect);
+       }
+    }
+  else
+    flags &= ~GTK_CELL_RENDERER_FOCUSED;
+
+  gtk_cell_renderer_render (renderer, data->cr, data->widget,
+                           cell_background, &inner_area, flags);
+
+  return FALSE;
+}
+
+static void
+gtk_cell_area_real_render (GtkCellArea          *area,
+                          GtkCellAreaContext   *context,
+                          GtkWidget            *widget,
+                          cairo_t              *cr,
+                          const GdkRectangle   *background_area,
+                          const GdkRectangle   *cell_area,
+                          GtkCellRendererState  flags,
+                          gboolean              paint_focus)
+{
+  CellRenderData render_data = 
+    { 
+      area, 
+      widget, 
+      cr, 
+      { 0, }, 
+      flags, 
+      paint_focus, 
+      FALSE, TRUE
+    };
+
+  /* Make sure we dont paint a focus rectangle while there
+   * is an editable widget in play 
+   */
+  if (gtk_cell_area_get_edited_cell (area))
+    render_data.paint_focus = FALSE;
+
+  /* If no cell can activate but the caller wants focus painted,
+   * then we paint focus around all cells */
+  if ((flags & GTK_CELL_RENDERER_FOCUSED) != 0 && paint_focus && 
+      !gtk_cell_area_is_activatable (area))
+    render_data.focus_all = TRUE;
+
+  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, 
+                              (GtkCellAllocCallback)render_cell, &render_data);
+
+  if (render_data.paint_focus && 
+      render_data.focus_rect.width != 0 && 
+      render_data.focus_rect.height != 0)
+    {
+      GtkStateType renderer_state = 
+       flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
+       (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
+        (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL));
+
+      gtk_paint_focus (gtk_widget_get_style (widget), cr, 
+                      renderer_state, widget,
+                      gtk_cell_area_get_style_detail (area),
+                      render_data.focus_rect.x,     render_data.focus_rect.y,
+                      render_data.focus_rect.width, render_data.focus_rect.height);
+    }
+}
+
 static void
 apply_cell_attributes (GtkCellRenderer *renderer,
                       CellInfo        *info,
@@ -1476,6 +1593,7 @@ gtk_cell_area_foreach (GtkCellArea        *area,
  * @context: the #GtkCellAreaContext for this row of data.
  * @widget: the #GtkWidget that @area is rendering to
  * @cell_area: the @widget relative coordinates and size for @area
+ * @background_area: the @widget relative coordinates of the background area
  * @callback: the #GtkCellAllocCallback to call
  * @callback_data: user provided data pointer
  *
@@ -1489,6 +1607,7 @@ gtk_cell_area_foreach_alloc (GtkCellArea          *area,
                             GtkCellAreaContext   *context,
                             GtkWidget            *widget,
                             const GdkRectangle   *cell_area,
+                            const GdkRectangle   *background_area,
                             GtkCellAllocCallback  callback,
                             gpointer              callback_data)
 {
@@ -1503,7 +1622,7 @@ gtk_cell_area_foreach_alloc (GtkCellArea          *area,
   class = GTK_CELL_AREA_GET_CLASS (area);
 
   if (class->foreach_alloc)
-    class->foreach_alloc (area, context, widget, cell_area, callback, callback_data);
+    class->foreach_alloc (area, context, widget, cell_area, background_area, callback, callback_data);
   else
     g_warning ("GtkCellAreaClass::foreach_alloc not implemented for `%s'", 
               g_type_name (G_TYPE_FROM_INSTANCE (area)));
@@ -1647,6 +1766,7 @@ gtk_cell_area_get_style_detail (GtkCellArea *area)
 static gboolean
 get_cell_allocation (GtkCellRenderer        *renderer,
                     const GdkRectangle     *cell_area,
+                    const GdkRectangle     *cell_background,
                     RendererAllocationData *data)
 {
   if (data->renderer == renderer)
@@ -1687,7 +1807,7 @@ gtk_cell_area_get_cell_allocation (GtkCellArea          *area,
   g_return_if_fail (cell_area != NULL);
   g_return_if_fail (allocation != NULL);
 
-  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, 
+  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, 
                               (GtkCellAllocCallback)get_cell_allocation, &data);
 
   *allocation = data.allocation;
@@ -1696,6 +1816,7 @@ gtk_cell_area_get_cell_allocation (GtkCellArea          *area,
 static gboolean
 get_cell_by_position (GtkCellRenderer     *renderer,
                      const GdkRectangle  *cell_area,
+                     const GdkRectangle  *cell_background,
                      CellByPositionData  *data)
 {
   if (data->x >= cell_area->x && data->x < cell_area->x + cell_area->width &&
@@ -1723,7 +1844,7 @@ get_cell_by_position (GtkCellRenderer     *renderer,
  * Gets the #GtkCellRenderer at @x and @y coordinates inside @area and optionally
  * returns the full cell allocation for it inside @cell_area.
  *
- * Returns: the #GtkCellRenderer at @x and @y.
+ * Returns value: the #GtkCellRenderer at @x and @y.
  *
  * Since: 3.0
  */
@@ -1745,7 +1866,7 @@ gtk_cell_area_get_cell_at_position (GtkCellArea          *area,
   g_return_val_if_fail (x >= cell_area->x && x <= cell_area->x + cell_area->width, NULL);
   g_return_val_if_fail (y >= cell_area->y && y <= cell_area->y + cell_area->height, NULL);
 
-  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, 
+  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, 
                               (GtkCellAllocCallback)get_cell_by_position, &data);
 
   if (alloc_area)
@@ -1754,7 +1875,6 @@ gtk_cell_area_get_cell_at_position (GtkCellArea          *area,
   return data.renderer;
 }
 
-
 /*************************************************************
  *                      API: Geometry                        *
  *************************************************************/
index c8021f73c73053e596b235cdf888dc9e4f532382..15d2856711142b73455e9d676ba637f4400d9e6c 100644 (file)
@@ -76,6 +76,8 @@ typedef gboolean    (*GtkCellCallback) (GtkCellRenderer  *renderer,
  * GtkCellAllocCallback:
  * @renderer: the cell renderer to operate on
  * @cell_area: the area allocated to @renderer inside the rectangle provided to gtk_cell_area_foreach_alloc().
+ * @cell_background: the background area for @renderer inside the background 
+ *                   area provided to gtk_cell_area_foreach_alloc().
  * @data: user-supplied data
  *
  * The type of the callback functions used for iterating over
@@ -86,6 +88,7 @@ typedef gboolean    (*GtkCellCallback) (GtkCellRenderer  *renderer,
  */
 typedef gboolean    (*GtkCellAllocCallback) (GtkCellRenderer    *renderer,
                                             const GdkRectangle *cell_area,
+                                            const GdkRectangle *cell_background,
                                             gpointer            data);
 
 
@@ -174,6 +177,7 @@ struct _GtkCellAreaClass
                                                          GtkCellAreaContext      *context,
                                                          GtkWidget               *widget,
                                                          const GdkRectangle      *cell_area,
+                                                         const GdkRectangle      *background_area,
                                                          GtkCellAllocCallback     callback,
                                                          gpointer                 callback_data);
   gint               (* event)                           (GtkCellArea             *area,
@@ -273,6 +277,7 @@ void                  gtk_cell_area_foreach_alloc                  (GtkCellArea
                                                                    GtkCellAreaContext   *context,
                                                                    GtkWidget            *widget,
                                                                    const GdkRectangle   *cell_area,
+                                                                   const GdkRectangle   *background_area,
                                                                    GtkCellAllocCallback  callback,
                                                                    gpointer              callback_data);
 gint                  gtk_cell_area_event                          (GtkCellArea          *area,
@@ -308,7 +313,6 @@ GtkCellRenderer      *gtk_cell_area_get_cell_at_position           (GtkCellArea
                                                                    gint                  y,
                                                                    GdkRectangle         *alloc_area);
 
-
 /* Geometry */
 GtkCellAreaContext   *gtk_cell_area_create_context                 (GtkCellArea        *area);
 GtkSizeRequestMode    gtk_cell_area_get_request_mode               (GtkCellArea        *area);
index e97767962f030dd81f2253c81a62977474b7d00f..2222b4b36d2092313db51f26add9e209227ba260 100644 (file)
@@ -78,16 +78,9 @@ static void      gtk_cell_area_box_foreach_alloc                  (GtkCellArea
                                                                   GtkCellAreaContext   *context,
                                                                   GtkWidget            *widget,
                                                                   const GdkRectangle   *cell_area,
+                                                                  const GdkRectangle   *background_area,
                                                                   GtkCellAllocCallback  callback,
                                                                   gpointer              callback_data);
-static void      gtk_cell_area_box_render                         (GtkCellArea          *area,
-                                                                  GtkCellAreaContext   *context,
-                                                                  GtkWidget            *widget,
-                                                                  cairo_t              *cr,
-                                                                  const GdkRectangle   *background_area,
-                                                                  const GdkRectangle   *cell_area,
-                                                                  GtkCellRendererState  flags,
-                                                                  gboolean              paint_focus);
 static void      gtk_cell_area_box_set_cell_property              (GtkCellArea          *area,
                                                                   GtkCellRenderer      *renderer,
                                                                   guint                 prop_id,
@@ -262,7 +255,6 @@ gtk_cell_area_box_class_init (GtkCellAreaBoxClass *class)
   area_class->remove              = gtk_cell_area_box_remove;
   area_class->foreach             = gtk_cell_area_box_foreach;
   area_class->foreach_alloc       = gtk_cell_area_box_foreach_alloc;
-  area_class->render              = gtk_cell_area_box_render;
   area_class->set_cell_property   = gtk_cell_area_box_set_cell_property;
   area_class->get_cell_property   = gtk_cell_area_box_get_cell_property;
   
@@ -1040,6 +1032,7 @@ gtk_cell_area_box_foreach_alloc (GtkCellArea          *area,
                                 GtkCellAreaContext   *context,
                                 GtkWidget            *widget,
                                 const GdkRectangle   *cell_area,
+                                const GdkRectangle   *background_area,
                                 GtkCellAllocCallback  callback,
                                 gpointer              callback_data)
 {
@@ -1047,80 +1040,13 @@ gtk_cell_area_box_foreach_alloc (GtkCellArea          *area,
   GtkCellAreaBoxPrivate *priv     = box->priv;
   GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
   GSList                *allocated_cells, *l;
-  GdkRectangle           allocation;
-
-  allocation = *cell_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, 
-                                        cell_area->width, cell_area->height);
-
-  for (l = allocated_cells; l; l = l->next)
-    {
-      AllocatedCell *cell = l->data;
-
-      if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-       {
-         allocation.x     = cell_area->x + cell->position;
-         allocation.width = cell->size;
-       }
-      else
-       {
-         allocation.y      = cell_area->y + cell->position;
-         allocation.height = cell->size;
-       }
-
-      if (callback (cell->renderer, &allocation, callback_data))
-       break;
-    }
-
-  g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL);
-  g_slist_free (allocated_cells);
-}
-
-static void
-gtk_cell_area_box_render (GtkCellArea          *area,
-                         GtkCellAreaContext   *context,
-                         GtkWidget            *widget,
-                         cairo_t              *cr,
-                         const GdkRectangle   *background_area,
-                         const GdkRectangle   *cell_area,
-                         GtkCellRendererState  flags,
-                         gboolean              paint_focus)
-{
-  GtkCellAreaBox        *box      = GTK_CELL_AREA_BOX (area);
-  GtkCellAreaBoxPrivate *priv     = box->priv;
-  GtkCellAreaBoxContext *box_context = GTK_CELL_AREA_BOX_CONTEXT (context);
-  GSList                *allocated_cells, *l;
-  GdkRectangle           cell_background, inner_area;
-  GtkCellRenderer       *focus_cell = NULL;
-  GdkRectangle           focus_rect = { 0, };
-  gboolean               first_focus_cell = TRUE;
-  gboolean               focus_all = FALSE;
+  GdkRectangle           cell_alloc, cell_background;
   gboolean               rtl;
 
   rtl = (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
         gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
 
-  /* Make sure we dont paint a focus rectangle while there
-   * is an editable widget in play 
-   */
-  if (gtk_cell_area_get_edited_cell (area))
-    paint_focus = FALSE;
-
-  if (flags & GTK_CELL_RENDERER_FOCUSED)
-    {
-      focus_cell = gtk_cell_area_get_focus_cell (area);
-      flags &= ~GTK_CELL_RENDERER_FOCUSED;
-
-      /* If no cell can activate but the caller wants focus painted,
-       * then we paint focus around all cells */
-      if (paint_focus && !gtk_cell_area_is_activatable (area))
-       focus_all = TRUE;
-    }
-
-  cell_background = *cell_area;
+  cell_alloc = *cell_area;
 
   /* Get a list of cells with allocation sizes decided regardless
    * of alignments and pack order etc. */
@@ -1129,29 +1055,27 @@ gtk_cell_area_box_render (GtkCellArea          *area,
 
   for (l = allocated_cells; l; l = l->next)
     {
-      AllocatedCell       *cell = l->data;
-      GtkCellRendererState cell_fields = 0;
-      GdkRectangle         render_background;
+      AllocatedCell *cell = l->data;
 
       if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        {
-         cell_background.x     = cell_area->x + cell->position;
-         cell_background.width = cell->size;
+         cell_alloc.x     = cell_area->x + cell->position;
+         cell_alloc.width = cell->size;
        }
       else
        {
-         cell_background.y      = cell_area->y + cell->position;
-         cell_background.height = cell->size;
+         cell_alloc.y      = cell_area->y + cell->position;
+         cell_alloc.height = cell->size;
        }
 
-      /* Stop rendering cells if they flow out of the render area,
+      /* Stop iterating over cells if they flow out of the render area,
        * this can happen because the render area can actually be
        * smaller than the requested area (treeview columns can
        * be user resizable and can be resized to be smaller than
        * the actual requested area). */
-      if (cell_background.x > cell_area->x + cell_area->width ||
-         cell_background.x + cell_background.width < cell_area->x ||
-         cell_background.y > cell_area->y + cell_area->height)
+      if (cell_alloc.x > cell_area->x + cell_area->width ||
+         cell_alloc.x + cell_alloc.width < cell_area->x ||
+         cell_alloc.y > cell_area->y + cell_area->height)
        break;
 
       /* Special case for the last cell (or first cell in rtl)... let the last cell consume 
@@ -1164,13 +1088,13 @@ gtk_cell_area_box_render (GtkCellArea          *area,
          if (rtl)
            {
              /* Fill the leading space for the first cell in the area (still last in the list) */
-             cell_background.width = (cell_background.x - cell_area->x) + cell_background.width;
-             cell_background.x     = cell_area->x;
+             cell_alloc.width = (cell_alloc.x - cell_area->x) + cell_alloc.width;
+             cell_alloc.x     = cell_area->x;
            }
          else
            {
-             cell_background.width  = cell_area->x + cell_area->width  - cell_background.x;
-             cell_background.height = cell_area->y + cell_area->height - cell_background.y;
+             cell_alloc.width  = cell_area->x + cell_area->width  - cell_alloc.x;
+             cell_alloc.height = cell_area->y + cell_area->height - cell_alloc.y;
            }
        }
       else
@@ -1179,98 +1103,52 @@ gtk_cell_area_box_render (GtkCellArea          *area,
           * so that the underlying renderer has a chance to deal with it (for instance
           * text renderers get a chance to ellipsize).
           */
-         if (cell_background.x + cell_background.width > cell_area->x + cell_area->width)
-           cell_background.width = cell_area->x + cell_area->width - cell_background.x;
+         if (cell_alloc.x + cell_alloc.width > cell_area->x + cell_area->width)
+           cell_alloc.width = cell_area->x + cell_area->width - cell_alloc.x;
 
-         if (cell_background.y + cell_background.height > cell_area->y + cell_area->height)
-           cell_background.height = cell_area->y + cell_area->height - cell_background.y;
+         if (cell_alloc.y + cell_alloc.height > cell_area->y + cell_area->height)
+           cell_alloc.height = cell_area->y + cell_area->height - cell_alloc.y;
        }
 
-      /* Remove margins from the background area to produce the cell area
-       */
-      gtk_cell_area_inner_cell_area (area, widget, &cell_background, &inner_area);
-
-      /* Add portions of the background_area to the cell_background
-       * to create the render_background */
-      render_background = cell_background;
+      /* Add portions of the background_area to the cell_alloc
+       * to create the cell_background */
+      cell_background = cell_alloc;
 
       if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
        {
          if (l == allocated_cells)
            {
-             render_background.width += render_background.x - background_area->x;
-             render_background.x      = background_area->x;
+             cell_background.width += cell_background.x - background_area->x;
+             cell_background.x      = background_area->x;
            }
 
          if (l->next == NULL)
-             render_background.width = 
-               background_area->width - (render_background.x - background_area->x);
+             cell_background.width = 
+               background_area->width - (cell_background.x - background_area->x);
 
-         render_background.y      = background_area->y;
-         render_background.height = background_area->height;
+         cell_background.y      = background_area->y;
+         cell_background.height = background_area->height;
        }
       else
        {
          if (l == allocated_cells)
            {
-             render_background.height += render_background.y - background_area->y;
-             render_background.y       = background_area->y;
+             cell_background.height += cell_background.y - background_area->y;
+             cell_background.y       = background_area->y;
            }
 
          if (l->next == NULL)
-             render_background.height = 
-               background_area->height - (render_background.y - background_area->y);
-
-         render_background.x     = background_area->x;
-         render_background.width = background_area->width;
-       }
-
-      if (focus_all || 
-         (focus_cell && 
-          (cell->renderer == focus_cell || 
-           gtk_cell_area_is_focus_sibling (area, focus_cell, cell->renderer))))
-       {
-         cell_fields |= GTK_CELL_RENDERER_FOCUSED;
-
-         if (paint_focus)
-           {
-             GdkRectangle cell_focus;
-
-             gtk_cell_renderer_get_aligned_area (cell->renderer, widget, flags, &inner_area, &cell_focus);
+             cell_background.height = 
+               background_area->height - (cell_background.y - background_area->y);
 
-             /* Accumulate the focus rectangle for all focus siblings */
-             if (first_focus_cell)
-               {
-                 focus_rect       = cell_focus;
-                 first_focus_cell = FALSE;
-               }
-             else
-               gdk_rectangle_union (&focus_rect, &cell_focus, &focus_rect);
-           }
+         cell_background.x     = background_area->x;
+         cell_background.width = background_area->width;
        }
 
-      /* We have to do some per-cell considerations for the 'flags'
-       * for focus handling */
-      gtk_cell_renderer_render (cell->renderer, cr, widget,
-                               &render_background, &inner_area,
-                               flags | cell_fields);
-    }
-
-  if (paint_focus && focus_rect.width != 0 && focus_rect.height != 0)
-    {
-      GtkStateType renderer_state = 
-       flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
-       (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
-        (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL));
-
-      gtk_paint_focus (gtk_widget_get_style (widget), cr, 
-                      renderer_state, widget,
-                      gtk_cell_area_get_style_detail (area),
-                      focus_rect.x,     focus_rect.y,
-                      focus_rect.width, focus_rect.height);
+      if (callback (cell->renderer, &cell_alloc, &cell_background, callback_data))
+       break;
     }
 
-
   g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL);
   g_slist_free (allocated_cells);
 }