[gtk+/treeview-refactor] GtkCellArea now paints focus on cells



commit f330b40521cf1f5b2b33b33bf7c5df0f59355838
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Thu Nov 11 16:13:06 2010 +0900

    GtkCellArea now paints focus on cells
    
    Added concept of "Focus Siblings" to GtkCellArea so that some
    static text/icon may be included in the focus/click area of
    an activatable or editable cell, implemented focus drawing
    as well, updated testcellarea to reflect the changes.

 gtk/gtkcellarea.c        |  173 +++++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkcellarea.h        |   25 ++++++-
 gtk/gtkcellareabox.c     |   98 ++++++++++++++++++++++----
 tests/cellareascaffold.c |   19 +++---
 tests/testcellarea.c     |   26 ++++++-
 5 files changed, 311 insertions(+), 30 deletions(-)
---
diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c
index de24277..e34c163 100644
--- a/gtk/gtkcellarea.c
+++ b/gtk/gtkcellarea.c
@@ -97,6 +97,13 @@ static void      gtk_cell_area_reorder                       (GtkCellLayout
 							      gint                   position);
 static GList    *gtk_cell_area_get_cells                     (GtkCellLayout         *cell_layout);
 
+
+/* Used in forall loop to check if a child renderer is present */
+typedef struct {
+  GtkCellRenderer *renderer;
+  gboolean         has_renderer;
+} HasRendererCheck;
+
 /* Attribute/Cell metadata */
 typedef struct {
   const gchar *attribute;
@@ -154,6 +161,9 @@ struct _GtkCellAreaPrivate
    */
   GHashTable      *cell_info;
 
+  /* Tracking which cells are focus siblings of focusable cells */
+  GHashTable      *focus_siblings;
+
   /* The cell border decides how much space to reserve
    * around each cell for the background_area
    */
@@ -222,6 +232,11 @@ gtk_cell_area_init (GtkCellArea *area)
 					   NULL, 
 					   (GDestroyNotify)cell_info_free);
 
+  priv->focus_siblings = g_hash_table_new_full (g_direct_hash, 
+						g_direct_equal,
+						NULL, 
+						(GDestroyNotify)g_list_free);
+
   priv->cell_border.left   = 0;
   priv->cell_border.right  = 0;
   priv->cell_border.top    = 0;
@@ -470,9 +485,10 @@ gtk_cell_area_finalize (GObject *object)
   GtkCellAreaPrivate *priv   = area->priv;
 
   /* All cell renderers should already be removed at this point,
-   * just kill our hash table here. 
+   * just kill our (empty) hash tables here. 
    */
   g_hash_table_destroy (priv->cell_info);
+  g_hash_table_destroy (priv->focus_siblings);
 
   g_free (priv->current_path);
 
@@ -858,6 +874,7 @@ gtk_cell_area_remove (GtkCellArea        *area,
 {
   GtkCellAreaClass   *class;
   GtkCellAreaPrivate *priv;
+  GList              *renderers, *l;
 
   g_return_if_fail (GTK_IS_CELL_AREA (area));
   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
@@ -868,6 +885,25 @@ gtk_cell_area_remove (GtkCellArea        *area,
   /* Remove any custom attributes and custom cell data func here first */
   g_hash_table_remove (priv->cell_info, renderer);
 
+  /* Remove focus siblings of this renderer */
+  g_hash_table_remove (priv->focus_siblings, renderer);
+
+  /* Remove this renderer from any focus renderer's sibling list */ 
+  renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area));
+
+  for (l = renderers; l; l = l->next)
+    {
+      GtkCellRenderer *focus_renderer = l->data;
+
+      if (gtk_cell_area_is_focus_sibling (area, focus_renderer, renderer))
+	{
+	  gtk_cell_area_remove_focus_sibling (area, focus_renderer, renderer);
+	  break;
+	}
+    }
+
+  g_list_free (renderers);
+
   if (class->remove)
     class->remove (area, renderer);
   else
@@ -875,6 +911,28 @@ gtk_cell_area_remove (GtkCellArea        *area,
 	       g_type_name (G_TYPE_FROM_INSTANCE (area)));
 }
 
+static void
+get_has_renderer (GtkCellRenderer  *renderer,
+		  HasRendererCheck *check)
+{
+  if (renderer == check->renderer)
+    check->has_renderer = TRUE;
+}
+
+gboolean
+gtk_cell_area_has_renderer (GtkCellArea     *area,
+			    GtkCellRenderer *renderer)
+{
+  HasRendererCheck check = { renderer, FALSE };
+
+  g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
+  g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), FALSE);
+
+  gtk_cell_area_forall (area, (GtkCellCallback)get_has_renderer, &check);
+
+  return check.has_renderer;
+}
+
 /**
  * gtk_cell_area_forall
  * @area: a #GtkCellArea
@@ -972,8 +1030,10 @@ gtk_cell_area_render (GtkCellArea          *area,
 		      GtkCellAreaIter      *iter,
 		      GtkWidget            *widget,
 		      cairo_t              *cr,
+		      const GdkRectangle   *background_area,
 		      const GdkRectangle   *cell_area,
-		      GtkCellRendererState  flags)
+		      GtkCellRendererState  flags,
+		      gboolean              paint_focus)
 {
   GtkCellAreaClass *class;
 
@@ -981,12 +1041,13 @@ gtk_cell_area_render (GtkCellArea          *area,
   g_return_if_fail (GTK_IS_CELL_AREA_ITER (iter));
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (cr != NULL);
+  g_return_if_fail (background_area != NULL);
   g_return_if_fail (cell_area != NULL);
 
   class = GTK_CELL_AREA_GET_CLASS (area);
 
   if (class->render)
-    class->render (area, iter, widget, cr, cell_area, flags);
+    class->render (area, iter, widget, cr, background_area, cell_area, flags, paint_focus);
   else
     g_warning ("GtkCellAreaClass::render not implemented for `%s'", 
 	       g_type_name (G_TYPE_FROM_INSTANCE (area)));
@@ -1136,6 +1197,7 @@ gtk_cell_area_attribute_connect (GtkCellArea        *area,
   g_return_if_fail (GTK_IS_CELL_AREA (area));
   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
   g_return_if_fail (attribute != NULL);
+  g_return_if_fail (gtk_cell_area_has_renderer (area, renderer));
 
   priv = area->priv;
   info = g_hash_table_lookup (priv->cell_info, renderer);
@@ -1202,6 +1264,7 @@ gtk_cell_area_attribute_disconnect (GtkCellArea        *area,
   g_return_if_fail (GTK_IS_CELL_AREA (area));
   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
   g_return_if_fail (attribute != NULL);
+  g_return_if_fail (gtk_cell_area_has_renderer (area, renderer));
 
   priv = area->priv;
   info = g_hash_table_lookup (priv->cell_info, renderer);
@@ -1822,6 +1885,110 @@ gtk_cell_area_get_focus_cell (GtkCellArea *area)
 
 
 /*************************************************************
+ *                    API: Focus Siblings                    *
+ *************************************************************/
+void
+gtk_cell_area_add_focus_sibling (GtkCellArea     *area,
+				 GtkCellRenderer *renderer,
+				 GtkCellRenderer *sibling)
+{
+  GtkCellAreaPrivate *priv;
+  GList              *siblings;
+
+  g_return_if_fail (GTK_IS_CELL_AREA (area));
+  g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
+  g_return_if_fail (GTK_IS_CELL_RENDERER (sibling));
+  g_return_if_fail (renderer != sibling);
+  g_return_if_fail (gtk_cell_area_has_renderer (area, renderer));
+  g_return_if_fail (gtk_cell_area_has_renderer (area, sibling));
+  g_return_if_fail (!gtk_cell_area_is_focus_sibling (area, renderer, sibling));
+
+  /* XXX We should also check that sibling is not in any other renderer's sibling
+   * list already, a renderer can be sibling of only one focusable renderer
+   * at a time.
+   */
+
+  priv = area->priv;
+
+  siblings = g_hash_table_lookup (priv->focus_siblings, renderer);
+
+  if (siblings)
+    siblings = g_list_append (siblings, sibling);
+  else
+    {
+      siblings = g_list_append (siblings, sibling);
+      g_hash_table_insert (priv->focus_siblings, renderer, siblings);
+    }
+}
+
+void
+gtk_cell_area_remove_focus_sibling (GtkCellArea     *area,
+				    GtkCellRenderer *renderer,
+				    GtkCellRenderer *sibling)
+{
+  GtkCellAreaPrivate *priv;
+  GList              *siblings;
+
+  g_return_if_fail (GTK_IS_CELL_AREA (area));
+  g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
+  g_return_if_fail (GTK_IS_CELL_RENDERER (sibling));
+  g_return_if_fail (gtk_cell_area_is_focus_sibling (area, renderer, sibling));
+
+  priv = area->priv;
+
+  siblings = g_hash_table_lookup (priv->focus_siblings, renderer);
+
+  siblings = g_list_copy (siblings);
+  siblings = g_list_remove (siblings, sibling);
+
+  if (!siblings)
+    g_hash_table_remove (priv->focus_siblings, renderer);
+  else
+    g_hash_table_insert (priv->focus_siblings, renderer, siblings);
+}
+
+gboolean
+gtk_cell_area_is_focus_sibling (GtkCellArea     *area,
+				GtkCellRenderer *renderer,
+				GtkCellRenderer *sibling)
+{
+  GtkCellAreaPrivate *priv;
+  GList              *siblings, *l;
+
+  g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
+  g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), FALSE);
+  g_return_val_if_fail (GTK_IS_CELL_RENDERER (sibling), FALSE);
+
+  priv = area->priv;
+
+  siblings = g_hash_table_lookup (priv->focus_siblings, renderer);
+
+  for (l = siblings; l; l = l->next)
+    {
+      GtkCellRenderer *a_sibling = l->data;
+
+      if (a_sibling == sibling)
+	return TRUE;
+    }
+
+  return FALSE;
+}
+
+const GList *
+gtk_cell_area_get_focus_siblings (GtkCellArea     *area,
+				  GtkCellRenderer *renderer)
+{
+  GtkCellAreaPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
+  g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), NULL);
+
+  priv = area->priv;
+
+  return g_hash_table_lookup (priv->focus_siblings, renderer);  
+}
+
+/*************************************************************
  *              API: Cell Activation/Editing                 *
  *************************************************************/
 static void
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index 6271e99..c120354 100644
--- a/gtk/gtkcellarea.h
+++ b/gtk/gtkcellarea.h
@@ -95,8 +95,10 @@ struct _GtkCellAreaClass
 							  GtkCellAreaIter         *iter,
 							  GtkWidget               *widget,
 							  cairo_t                 *cr,
+							  const GdkRectangle      *background_area,
 							  const GdkRectangle      *cell_area,
-							  GtkCellRendererState     flags);
+							  GtkCellRendererState     flags,
+							  gboolean                 paint_focus);
 
   /* Geometry */
   GtkCellAreaIter   *(* create_iter)                     (GtkCellArea             *area);
@@ -165,6 +167,8 @@ void               gtk_cell_area_add                            (GtkCellArea
 								 GtkCellRenderer      *renderer);
 void               gtk_cell_area_remove                         (GtkCellArea          *area,
 								 GtkCellRenderer      *renderer);
+gboolean           gtk_cell_area_has_renderer                   (GtkCellArea          *area,
+								 GtkCellRenderer      *renderer);
 void               gtk_cell_area_forall                         (GtkCellArea          *area,
 								 GtkCellCallback       callback,
 								 gpointer              callback_data);
@@ -184,8 +188,10 @@ void               gtk_cell_area_render                         (GtkCellArea
 								 GtkCellAreaIter      *iter,
 								 GtkWidget            *widget,
 								 cairo_t              *cr,
+								 const GdkRectangle   *background_area,
 								 const GdkRectangle   *cell_area,
-								 GtkCellRendererState  flags);
+								 GtkCellRendererState  flags,
+								 gboolean              paint_focus);
 
 /* Geometry */
 GtkCellAreaIter   *gtk_cell_area_create_iter                    (GtkCellArea        *area);
@@ -283,6 +289,21 @@ void               gtk_cell_area_set_focus_cell                 (GtkCellArea
 								 GtkCellRenderer      *renderer);
 GtkCellRenderer   *gtk_cell_area_get_focus_cell                 (GtkCellArea          *area);
 
+
+/* Focus siblings */
+void               gtk_cell_area_add_focus_sibling              (GtkCellArea          *area,
+								 GtkCellRenderer      *renderer,
+								 GtkCellRenderer      *sibling);
+void               gtk_cell_area_remove_focus_sibling           (GtkCellArea          *area,
+								 GtkCellRenderer      *renderer,
+								 GtkCellRenderer      *sibling);
+gboolean           gtk_cell_area_is_focus_sibling               (GtkCellArea          *area,
+								 GtkCellRenderer      *renderer,
+								 GtkCellRenderer      *sibling);
+G_CONST_RETURN GList *gtk_cell_area_get_focus_siblings          (GtkCellArea          *area,
+								 GtkCellRenderer      *renderer);
+
+
 /* Cell Activation/Editing */
 void               gtk_cell_area_set_edited_cell                (GtkCellArea          *area,
 								 GtkCellRenderer      *renderer);
diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c
index 66058d8..45355ae 100644
--- a/gtk/gtkcellareabox.c
+++ b/gtk/gtkcellareabox.c
@@ -66,8 +66,10 @@ static void      gtk_cell_area_box_render                         (GtkCellArea
 								   GtkCellAreaIter      *iter,
 								   GtkWidget            *widget,
 								   cairo_t              *cr,
+								   const GdkRectangle   *background_area,
 								   const GdkRectangle   *cell_area,
-								   GtkCellRendererState  flags);
+								   GtkCellRendererState  flags,
+								   gboolean              paint_focus);
 static void      gtk_cell_area_box_set_cell_property              (GtkCellArea          *area,
 								   GtkCellRenderer      *renderer,
 								   guint                 prop_id,
@@ -900,15 +902,19 @@ gtk_cell_area_box_render (GtkCellArea          *area,
 			  GtkCellAreaIter      *iter,
 			  GtkWidget            *widget,
 			  cairo_t              *cr,
+			  const GdkRectangle   *background_area,
 			  const GdkRectangle   *cell_area,
-			  GtkCellRendererState  flags)
+			  GtkCellRendererState  flags,
+			  gboolean              paint_focus)
 {
   GtkCellAreaBox        *box      = GTK_CELL_AREA_BOX (area);
   GtkCellAreaBoxPrivate *priv     = box->priv;
   GtkCellAreaBoxIter    *box_iter = GTK_CELL_AREA_BOX_ITER (iter);
   GSList                *allocated_cells, *l;
-  GdkRectangle           background_area, inner_area;
+  GdkRectangle           cell_background, inner_area;
   GtkCellRenderer       *focus_cell = NULL;
+  GdkRectangle           focus_rect = { 0, };
+  gboolean               first_focus_cell = TRUE;
 
   if (flags & GTK_CELL_RENDERER_FOCUSED)
     {
@@ -916,7 +922,7 @@ gtk_cell_area_box_render (GtkCellArea          *area,
       flags &= ~GTK_CELL_RENDERER_FOCUSED;
     }
 
-  background_area = *cell_area;
+  cell_background = *cell_area;
 
   /* Get a list of cells with allocation sizes decided regardless
    * of alignments and pack order etc. */
@@ -929,29 +935,95 @@ gtk_cell_area_box_render (GtkCellArea          *area,
 
       if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
 	{
-	  background_area.x     = cell_area->x + cell->position;
-	  background_area.width = cell->size;
+	  cell_background.x     = cell_area->x + cell->position;
+	  cell_background.width = cell->size;
 	}
       else
 	{
-	  background_area.y      = cell_area->y + cell->position;
-	  background_area.height = cell->size;
+	  cell_background.y      = cell_area->y + cell->position;
+	  cell_background.height = cell->size;
 	}
 
-      if (cell->renderer == focus_cell)
-	cell_fields |= GTK_CELL_RENDERER_FOCUSED;
-
       /* Remove margins from the background area to produce the cell area
        */
-      gtk_cell_area_inner_cell_area (area, &background_area, &inner_area);
+      gtk_cell_area_inner_cell_area (area, &cell_background, &inner_area);
+
+      if (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;
+	      gint         opposite_size, x_offset, y_offset;
+
+	      cell_focus = inner_area;
+
+	      /* Trim up the focus size */
+	      if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+		{
+		  gtk_cell_renderer_get_preferred_height_for_width (cell->renderer, widget, 
+								    cell_focus.width, 
+								    NULL, &opposite_size);
+
+		  cell_focus.height = MIN (opposite_size, cell_focus.height);
+		}
+	      else
+		{
+		  gtk_cell_renderer_get_preferred_width_for_height (cell->renderer, widget, 
+								    cell_focus.height, 
+								    NULL, &opposite_size);
+
+		  cell_focus.width = MIN (opposite_size, cell_focus.width);
+		}
+
+	      /* offset the cell position */
+	      _gtk_cell_renderer_calc_offset (cell->renderer, &inner_area, GTK_TEXT_DIR_LTR,
+					      cell_focus.width, cell_focus.height,
+					      &x_offset, &y_offset);
+
+	      cell_focus.x += x_offset;
+	      cell_focus.y += y_offset;
+
+	      /* 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);
+	    }
+	}
 
       /* We have to do some per-cell considerations for the 'flags'
        * for focus handling */
       gtk_cell_renderer_render (cell->renderer, cr, widget,
-				&background_area, &inner_area,
+				&cell_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,
+		       /* XXX This hint should be a property on GtkCellArea I suppose */
+		       "treeview",
+		       focus_rect.x,
+		       focus_rect.y,
+		       focus_rect.width,
+		       focus_rect.height);
+    }
+
+
   g_slist_foreach (allocated_cells, (GFunc)allocated_cell_free, NULL);
   g_slist_free (allocated_cells);
 }
diff --git a/tests/cellareascaffold.c b/tests/cellareascaffold.c
index c0b72d7..6d40be9 100644
--- a/tests/cellareascaffold.c
+++ b/tests/cellareascaffold.c
@@ -405,7 +405,9 @@ cell_area_scaffold_draw (GtkWidget       *widget,
 	}
 
       gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE);
-      gtk_cell_area_render (priv->area, priv->iter, widget, cr, &render_area, flags);
+      gtk_cell_area_render (priv->area, priv->iter, widget, cr, 
+			    &render_area, &render_area, flags,
+			    (have_focus && i == priv->focus_row));
 
       if (orientation == GTK_ORIENTATION_HORIZONTAL)
 	{
@@ -726,13 +728,11 @@ cell_area_scaffold_focus (GtkWidget       *widget,
       /* If focus stays in the area we dont need to do any more */
       if (gtk_cell_area_focus (priv->area, direction))
 	{
-	  GtkCellRenderer *renderer = gtk_cell_area_get_focus_cell (priv->area);
-	  
 	  priv->focus_row = focus_row;
-	  
-	  g_print ("focusing in direction %s: focus set on a %s in row %d\n", 
-		   DIRECTION_STR (direction), G_OBJECT_TYPE_NAME (renderer), priv->focus_row);
-	  
+
+	  /* XXX A smarter implementation would only invalidate the rectangles where
+	   * focus was removed from and new focus was placed */
+	  gtk_widget_queue_draw (widget);
 	  return TRUE;
 	}
       else
@@ -802,8 +802,9 @@ cell_area_scaffold_focus (GtkWidget       *widget,
 	}
     }
 
-  g_print ("focus leaving with no cells in focus (direction %s, focus_row %d)\n",
-	   DIRECTION_STR (direction), priv->focus_row);
+  /* XXX A smarter implementation would only invalidate the rectangles where
+   * focus was removed from and new focus was placed */
+  gtk_widget_queue_draw (widget);
 
   return FALSE;
 }
diff --git a/tests/testcellarea.c b/tests/testcellarea.c
index d547f71..0acf2eb 100644
--- a/tests/testcellarea.c
+++ b/tests/testcellarea.c
@@ -246,6 +246,8 @@ simple_cell_area (void)
 /*******************************************************
  *                      Focus Test                     *
  *******************************************************/
+static GtkCellRenderer *focus_renderer, *sibling_renderer;
+
 enum {
   FOCUS_COLUMN_NAME,
   FOCUS_COLUMN_CHECK,
@@ -328,7 +330,7 @@ focus_scaffold (void)
   gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_NAME);
 
   /* Catch signal ... */
-  renderer = gtk_cell_renderer_toggle_new ();
+  focus_renderer = renderer = gtk_cell_renderer_toggle_new ();
   g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL);
   gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);
   gtk_cell_area_attribute_connect (area, renderer, "active", FOCUS_COLUMN_CHECK);
@@ -336,7 +338,7 @@ focus_scaffold (void)
   g_signal_connect (G_OBJECT (renderer), "toggled",
 		    G_CALLBACK (cell_toggled), scaffold);
 
-  renderer = gtk_cell_renderer_text_new ();
+  sibling_renderer = renderer = gtk_cell_renderer_text_new ();
   g_object_set (G_OBJECT (renderer), 
 		"wrap-mode", PANGO_WRAP_WORD,
 		"wrap-width", 150,
@@ -347,6 +349,21 @@ focus_scaffold (void)
   return scaffold;
 }
 
+static void
+focus_sibling_toggled (GtkToggleButton  *toggle,
+		       CellAreaScaffold *scaffold)
+{
+  GtkCellArea *area = cell_area_scaffold_get_area (scaffold);
+  gboolean     active = gtk_toggle_button_get_active (toggle);
+
+  if (active)
+    gtk_cell_area_add_focus_sibling (area, focus_renderer, sibling_renderer);
+  else
+    gtk_cell_area_remove_focus_sibling (area, focus_renderer, sibling_renderer);
+
+  gtk_widget_queue_draw (GTK_WIDGET (scaffold));
+}
+
 
 static void
 focus_cell_area (void)
@@ -375,10 +392,13 @@ focus_cell_area (void)
   gtk_widget_show (vbox);
   gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
 
-  widget = gtk_check_button_new_with_label ("check button");
+  widget = gtk_check_button_new_with_label ("Focus Sibling");
   gtk_widget_show (widget);
   gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
 
+  g_signal_connect (G_OBJECT (widget), "toggled",
+                    G_CALLBACK (focus_sibling_toggled), scaffold);
+
   gtk_container_add (GTK_CONTAINER (window), hbox);
 
   gtk_widget_show (window);



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