[egg-list-box/row-widget: 2/7] listbox: Make all children EggListBoxRows



commit 2e4703dd822808f2a917ac1229f5f9ebde997ba0
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Jun 7 11:36:28 2013 +0200

    listbox: Make all children EggListBoxRows
    
    The add function adds a wrapper row if needed, as a simple herlper,
    but in most cases you should use a EggListBoxRow yourself.
    
    This is a direct conversion to just use the row widgets, later changes
    will be using the row widgets.
    
    We also rename some APIs to say "row" instead of "child" as they now
    don't apply to any kind of child.

 Makefile.am               |   11 +-
 egg-list-box-accessible.c |   40 +--
 egg-list-box-accessible.h |    4 +-
 egg-list-box.c            |  897 +++++++++++++++++++++++----------------------
 egg-list-box.h            |   97 +++---
 egglistbox.vapi           |  140 +++++---
 test-focus.c              |   17 +-
 test-list.vala            |  136 ++++---
 test-scrolled.vala        |   15 +-
 test-sel.c                |    2 +-
 10 files changed, 720 insertions(+), 639 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 282ff54..5a12f85 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,6 +29,11 @@ libeggflowbox_la_LIBADD = $(LISTBOX_LIBS)
 
 noinst_PROGRAMS = test-list test-scrolled test-focus test-sel test-flow-box
 
+noinst_DATA = egglistbox.vapi
+
+egglistbox.vapi: Egg-1.0.gir
+       vapigen @LISTBOX_PACKAGES@ --library egglistbox --vapidir=. --metadatadir=$(srcdir) Egg-1.0.gir
+
 test_sel_SOURCES = \
        test-sel.c \
        $(NULL)
@@ -47,6 +52,7 @@ test_list_LDADD = \
        libegglistbox.la \
        $(NULL)
 
+test_list_vala.stamp: egglistbox.vapi
 test_list_VALAFLAGS = \
        $(AM_VALAFLAGS) \
        --pkg egglistbox \
@@ -56,6 +62,7 @@ test_scrolled_SOURCES = \
        test-scrolled.vala \
        $(NULL)
 
+test_scrolled_vala.stamp: egglistbox.vapi
 test_scrolled_LDADD = \
        $(LISTBOX_LIBS) \
        libegglistbox.la \
@@ -113,9 +120,9 @@ Egg_1_0_gir_INCLUDES = GObject-2.0 Gtk-3.0
 Egg_1_0_gir_FILES = $(libegglistbox_la_SOURCES) $(libeggflowbox_la_SOURCES)
 INTROSPECTION_GIRS += Egg-1.0.gir
 
-noinst_DATA = $(INTROSPECTION_GIRS)
+noinst_DATA += $(INTROSPECTION_GIRS)
 
 CLEANFILES += $(gir_DATA) $(typelib_DATA)
-DISTCLEANFILES = $(builddir)/Egg-1.0.gir
+DISTCLEANFILES = $(builddir)/Egg-1.0.gir $(builddir)/egglistbox.vapi
 
 endif
diff --git a/egg-list-box-accessible.c b/egg-list-box-accessible.c
index e1477df..f13b9f7 100644
--- a/egg-list-box-accessible.c
+++ b/egg-list-box-accessible.c
@@ -68,17 +68,16 @@ egg_list_box_accessible_add_selection (AtkSelection *selection,
   GtkWidget *box;
   GList *children;
   GtkWidget *child;
+  EggListBoxRow *row;
 
   box = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
   if (box == NULL)
     return FALSE;
 
-  children = gtk_container_get_children (GTK_CONTAINER (box));
-  child = g_list_nth_data (children, idx);
-  g_list_free (children);
-  if (child)
+  row = egg_list_box_get_row_at_index (EGG_LIST_BOX (box), idx);
+  if (row)
     {
-      egg_list_box_select_child (EGG_LIST_BOX (box), child);
+      egg_list_box_select_row (EGG_LIST_BOX (box), row);
       return TRUE;
     }
   return FALSE;
@@ -93,7 +92,7 @@ egg_list_box_accessible_clear_selection (AtkSelection *selection)
   if (box == NULL)
     return FALSE;
 
-  egg_list_box_select_child (EGG_LIST_BOX (box), NULL);
+  egg_list_box_select_row (EGG_LIST_BOX (box), NULL);
   return TRUE;
 }
 
@@ -102,7 +101,7 @@ egg_list_box_accessible_ref_selection (AtkSelection *selection,
                                        gint          idx)
 {
   GtkWidget *box;
-  GtkWidget *widget;
+  EggListBoxRow *row;
   AtkObject *accessible;
 
   if (idx != 0)
@@ -112,11 +111,11 @@ egg_list_box_accessible_ref_selection (AtkSelection *selection,
   if (box == NULL)
     return NULL;
 
-  widget = egg_list_box_get_selected_child (EGG_LIST_BOX (box));
-  if (widget == NULL)
+  row = egg_list_box_get_selected_row (EGG_LIST_BOX (box));
+  if (row == NULL)
     return NULL;
 
-  accessible = gtk_widget_get_accessible (widget);
+  accessible = gtk_widget_get_accessible (GTK_WIDGET (row));
   g_object_ref (accessible);
   return accessible;
 }
@@ -125,14 +124,14 @@ static gint
 egg_list_box_accessible_get_selection_count (AtkSelection *selection)
 {
   GtkWidget *box;
-  GtkWidget *widget;
+  EggListBoxRow *row;
 
   box = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
   if (box == NULL)
     return 0;
 
-  widget = egg_list_box_get_selected_child (EGG_LIST_BOX (box));
-  if (widget == NULL)
+  row = egg_list_box_get_selected_row (EGG_LIST_BOX (box));
+  if (row == NULL)
     return 0;
 
   return 1;
@@ -145,20 +144,17 @@ egg_list_box_accessible_is_child_selected (AtkSelection *selection,
   GtkWidget *box;
   GtkWidget *widget;
   GList *children;
-  GtkWidget *child;
+  EggListBoxRow *row;
 
   box = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
   if (box == NULL)
     return FALSE;
 
-  widget = egg_list_box_get_selected_child (EGG_LIST_BOX (box));
-  if (widget == NULL)
+  row = egg_list_box_get_selected_row (EGG_LIST_BOX (box));
+  if (row == NULL)
     return FALSE;
 
-  children = gtk_container_get_children (GTK_CONTAINER (box));
-  child = g_list_nth_data (children, idx);
-  g_list_free (children);
-  return child == widget;
+  return row == egg_list_box_get_row_at_index (EGG_LIST_BOX (box), idx);
 }
 
 static void atk_selection_interface_init (AtkSelectionIface *iface)
@@ -180,11 +176,11 @@ _egg_list_box_accessible_selection_changed (EggListBox *box)
 
 void
 _egg_list_box_accessible_update_cursor (EggListBox *box,
-                                        GtkWidget  *child)
+                                        EggListBoxRow *row)
 {
   AtkObject *accessible;
   AtkObject *descendant;
   accessible = gtk_widget_get_accessible (GTK_WIDGET (box));
-  descendant = child ? gtk_widget_get_accessible (child) : NULL;
+  descendant = row ? gtk_widget_get_accessible (GTK_WIDGET (row)) : NULL;
   g_signal_emit_by_name (accessible, "active-descendant-changed", descendant);
 }
diff --git a/egg-list-box-accessible.h b/egg-list-box-accessible.h
index db5b00c..6a094e2 100644
--- a/egg-list-box-accessible.h
+++ b/egg-list-box-accessible.h
@@ -47,8 +47,8 @@ struct _EggListBoxAccessibleClass
 
 GType egg_list_box_accessible_get_type (void);
 
-void _egg_list_box_accessible_update_selected (EggListBox *box, GtkWidget *child);
-void _egg_list_box_accessible_update_cursor   (EggListBox *box, GtkWidget *child);
+void _egg_list_box_accessible_update_selected (EggListBox *box, EggListBoxRow *child);
+void _egg_list_box_accessible_update_cursor   (EggListBox *box, EggListBoxRow *child);
 
 G_END_DECLS
 
diff --git a/egg-list-box.c b/egg-list-box.c
index bb4d294..09c12b3 100644
--- a/egg-list-box.c
+++ b/egg-list-box.c
@@ -56,12 +56,9 @@ _egg_marshal_VOID__ENUM_INT (GClosure * closure,
   callback (data1, g_value_get_enum (param_values + 1), g_value_get_int (param_values + 2), data2);
 }
 
-typedef struct _EggListBoxChildInfo EggListBoxChildInfo;
-
 struct _EggListBoxPrivate
 {
   GSequence *children;
-  GHashTable *child_hash;
   GHashTable *separator_hash;
 
   EggListBoxSortFunc sort_func;
@@ -76,12 +73,12 @@ struct _EggListBoxPrivate
   gpointer update_separator_func_target;
   GDestroyNotify update_separator_func_target_destroy_notify;
 
-  EggListBoxChildInfo *selected_child;
-  EggListBoxChildInfo *prelight_child;
-  EggListBoxChildInfo *cursor_child;
+  EggListBoxRow *selected_row;
+  EggListBoxRow *prelight_row;
+  EggListBoxRow *cursor_row;
 
-  gboolean active_child_active;
-  EggListBoxChildInfo *active_child;
+  gboolean active_row_active;
+  EggListBoxRow *active_row;
 
   GtkSelectionMode selection_mode;
 
@@ -95,24 +92,17 @@ struct _EggListBoxPrivate
 
 struct _EggListBoxRowPrivate
 {
-  int dummy;
-};
-
-
-struct _EggListBoxChildInfo
-{
   GSequenceIter *iter;
-  GtkWidget *widget;
   GtkWidget *separator;
   gint y;
   gint height;
 };
 
 enum {
-  CHILD_SELECTED,
-  CHILD_ACTIVATED,
-  ACTIVATE_CURSOR_CHILD,
-  TOGGLE_CURSOR_CHILD,
+  ROW_SELECTED,
+  ROW_ACTIVATED,
+  ACTIVATE_CURSOR_ROW,
+  TOGGLE_CURSOR_ROW,
   MOVE_CURSOR,
   REFILTER,
   LAST_SIGNAL
@@ -128,32 +118,28 @@ enum  {
 G_DEFINE_TYPE (EggListBox, egg_list_box, GTK_TYPE_CONTAINER)
 G_DEFINE_TYPE (EggListBoxRow, egg_list_box_row, GTK_TYPE_BIN)
 
-static EggListBoxChildInfo *egg_list_box_find_child_at_y              (EggListBox          *list_box,
-                                                                      gint                 y);
-static EggListBoxChildInfo *egg_list_box_lookup_info                  (EggListBox          *list_box,
-                                                                      GtkWidget           *widget);
 static void                 egg_list_box_update_selected              (EggListBox          *list_box,
-                                                                      EggListBoxChildInfo *child);
+                                                                      EggListBoxRow       *row);
 static void                 egg_list_box_apply_filter_all             (EggListBox          *list_box);
 static void                 egg_list_box_update_separator             (EggListBox          *list_box,
                                                                       GSequenceIter       *iter);
 static GSequenceIter *      egg_list_box_get_next_visible             (EggListBox          *list_box,
                                                                       GSequenceIter       *_iter);
 static void                 egg_list_box_apply_filter                 (EggListBox          *list_box,
-                                                                      GtkWidget           *child);
+                                                                      EggListBoxRow       *row);
 static void                 egg_list_box_add_move_binding             (GtkBindingSet       *binding_set,
                                                                       guint                keyval,
                                                                       GdkModifierType      modmask,
                                                                       GtkMovementStep      step,
                                                                       gint                 count);
 static void                 egg_list_box_update_cursor                (EggListBox          *list_box,
-                                                                      EggListBoxChildInfo *child);
+                                                                      EggListBoxRow       *row);
 static void                 egg_list_box_select_and_activate          (EggListBox          *list_box,
-                                                                      EggListBoxChildInfo *child);
+                                                                      EggListBoxRow       *row);
 static void                 egg_list_box_update_prelight              (EggListBox          *list_box,
-                                                                      EggListBoxChildInfo *child);
+                                                                      EggListBoxRow       *row);
 static void                 egg_list_box_update_active                (EggListBox          *list_box,
-                                                                      EggListBoxChildInfo *child);
+                                                                      EggListBoxRow       *row);
 static gboolean             egg_list_box_real_enter_notify_event      (GtkWidget           *widget,
                                                                       GdkEventCrossing    *event);
 static gboolean             egg_list_box_real_leave_notify_event      (GtkWidget           *widget,
@@ -169,8 +155,8 @@ static gboolean             egg_list_box_real_focus                   (GtkWidget
                                                                       GtkDirectionType     direction);
 static GSequenceIter*       egg_list_box_get_previous_visible         (EggListBox          *list_box,
                                                                       GSequenceIter       *_iter);
-static EggListBoxChildInfo *egg_list_box_get_first_visible            (EggListBox          *list_box);
-static EggListBoxChildInfo *egg_list_box_get_last_visible             (EggListBox          *list_box);
+static EggListBoxRow       *egg_list_box_get_first_visible            (EggListBox          *list_box);
+static EggListBoxRow       *egg_list_box_get_last_visible             (EggListBox          *list_box);
 static gboolean             egg_list_box_real_draw                    (GtkWidget           *widget,
                                                                       cairo_t             *cr);
 static void                 egg_list_box_real_realize                 (GtkWidget           *widget);
@@ -197,8 +183,8 @@ static gboolean             egg_list_box_real_drag_motion             (GtkWidget
                                                                       gint                 x,
                                                                       gint                 y,
                                                                       guint                time_);
-static void                 egg_list_box_real_activate_cursor_child   (EggListBox          *list_box);
-static void                 egg_list_box_real_toggle_cursor_child     (EggListBox          *list_box);
+static void                 egg_list_box_real_activate_cursor_row     (EggListBox          *list_box);
+static void                 egg_list_box_real_toggle_cursor_row       (EggListBox          *list_box);
 static void                 egg_list_box_real_move_cursor             (EggListBox          *list_box,
                                                                       GtkMovementStep      step,
                                                                       gint                 count);
@@ -224,24 +210,6 @@ static void                 egg_list_box_real_get_preferred_width_for_height (Gt
 static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
 static guint signals[LAST_SIGNAL] = { 0 };
 
-static EggListBoxChildInfo*
-egg_list_box_child_info_new (GtkWidget *widget)
-{
-  EggListBoxChildInfo *info;
-
-  info = g_new0 (EggListBoxChildInfo, 1);
-  info->widget = g_object_ref (widget);
-  return info;
-}
-
-static void
-egg_list_box_child_info_free (EggListBoxChildInfo *info)
-{
-  g_clear_object (&info->widget);
-  g_clear_object (&info->separator);
-  g_free (info);
-}
-
 GtkWidget *
 egg_list_box_new (void)
 {
@@ -262,8 +230,7 @@ egg_list_box_init (EggListBox *list_box)
   priv->selection_mode = GTK_SELECTION_SINGLE;
   priv->activate_single_click = TRUE;
 
-  priv->children = g_sequence_new ((GDestroyNotify)egg_list_box_child_info_free);
-  priv->child_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+  priv->children = g_sequence_new (NULL);
   priv->separator_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
 }
 
@@ -331,7 +298,6 @@ egg_list_box_finalize (GObject *obj)
   g_clear_object (&priv->drag_highlighted_widget);
 
   g_sequence_free (priv->children);
-  g_hash_table_unref (priv->child_hash);
   g_hash_table_unref (priv->separator_hash);
 
   G_OBJECT_CLASS (egg_list_box_parent_class)->finalize (obj);
@@ -376,8 +342,8 @@ egg_list_box_class_init (EggListBoxClass *klass)
   container_class->remove = egg_list_box_real_remove;
   container_class->forall = egg_list_box_real_forall_internal;
   container_class->child_type = egg_list_box_real_child_type;
-  klass->activate_cursor_child = egg_list_box_real_activate_cursor_child;
-  klass->toggle_cursor_child = egg_list_box_real_toggle_cursor_child;
+  klass->activate_cursor_row = egg_list_box_real_activate_cursor_row;
+  klass->toggle_cursor_row = egg_list_box_real_toggle_cursor_row;
   klass->move_cursor = egg_list_box_real_move_cursor;
   klass->refilter = egg_list_box_real_refilter;
 
@@ -398,37 +364,37 @@ egg_list_box_class_init (EggListBoxClass *klass)
 
   g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
 
-  signals[CHILD_SELECTED] =
-    g_signal_new ("child-selected",
+  signals[ROW_SELECTED] =
+    g_signal_new ("row-selected",
                  EGG_TYPE_LIST_BOX,
                  G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (EggListBoxClass, child_selected),
+                 G_STRUCT_OFFSET (EggListBoxClass, row_selected),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1,
                  GTK_TYPE_WIDGET);
-  signals[CHILD_ACTIVATED] =
-    g_signal_new ("child-activated",
+  signals[ROW_ACTIVATED] =
+    g_signal_new ("row-activated",
                  EGG_TYPE_LIST_BOX,
                  G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (EggListBoxClass, child_activated),
+                 G_STRUCT_OFFSET (EggListBoxClass, row_activated),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1,
                  GTK_TYPE_WIDGET);
-  signals[ACTIVATE_CURSOR_CHILD] =
-    g_signal_new ("activate-cursor-child",
+  signals[ACTIVATE_CURSOR_ROW] =
+    g_signal_new ("activate-cursor-row",
                  EGG_TYPE_LIST_BOX,
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                 G_STRUCT_OFFSET (EggListBoxClass, activate_cursor_child),
+                 G_STRUCT_OFFSET (EggListBoxClass, activate_cursor_row),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
-  signals[TOGGLE_CURSOR_CHILD] =
-    g_signal_new ("toggle-cursor-child",
+  signals[TOGGLE_CURSOR_ROW] =
+    g_signal_new ("toggle-cursor-row",
                  EGG_TYPE_LIST_BOX,
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                 G_STRUCT_OFFSET (EggListBoxClass, toggle_cursor_child),
+                 G_STRUCT_OFFSET (EggListBoxClass, toggle_cursor_row),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
@@ -450,7 +416,7 @@ egg_list_box_class_init (EggListBoxClass *klass)
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
-  widget_class->activate_signal = signals[ACTIVATE_CURSOR_CHILD];
+  widget_class->activate_signal = signals[ACTIVATE_CURSOR_ROW];
 
   binding_set = gtk_binding_set_by_class (klass);
   egg_list_box_add_move_binding (binding_set, GDK_KEY_Home, 0,
@@ -478,70 +444,106 @@ egg_list_box_class_init (EggListBoxClass *klass)
   egg_list_box_add_move_binding (binding_set, GDK_KEY_KP_Page_Down, 0,
                                 GTK_MOVEMENT_PAGES, 1);
   gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, GDK_CONTROL_MASK,
-                               "toggle-cursor-child", 0, NULL);
+                               "toggle-cursor-row", 0, NULL);
 }
 
 /**
- * egg_list_box_get_selected_child:
- * @self: An #EggListBox.
+ * egg_list_box_get_selected_row:
+ * @list_box: An #EggListBox.
  *
- * Gets the selected child.
+ * Gets the selected row.
  *
  * Return value: (transfer none): The selected #GtkWidget.
  **/
-GtkWidget *
-egg_list_box_get_selected_child (EggListBox *list_box)
+EggListBoxRow *
+egg_list_box_get_selected_row (EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
   g_return_val_if_fail (list_box != NULL, NULL);
 
-  if (priv->selected_child != NULL)
-    return priv->selected_child->widget;
+  if (priv->selected_row != NULL)
+    return priv->selected_row;
 
   return NULL;
 }
 
 /**
- * egg_list_box_get_child_at_y:
- * @self: An #EggListBox.
- * @y: position
+ * egg_list_box_get_row_at_index:
+ * @list_box: An #EggListBox.
+ * @index: the index of the row
  *
- * Gets the child at the position.
+ * Gets the n:th child in the list (not counting separators).
  *
  * Return value: (transfer none): The child #GtkWidget.
  **/
-GtkWidget *
-egg_list_box_get_child_at_y (EggListBox *list_box, gint y)
+EggListBoxRow *
+egg_list_box_get_row_at_index (EggListBox *list_box, gint index)
 {
-  EggListBoxChildInfo *child;
+  EggListBoxRow *row, *found_row;
+  EggListBoxRowPrivate *row_priv;
+  EggListBoxPrivate *priv = list_box->priv;
+  GSequenceIter *iter;
 
   g_return_val_if_fail (list_box != NULL, NULL);
 
-  child = egg_list_box_find_child_at_y (list_box, y);
-  if (child == NULL)
-    return NULL;
+  iter = g_sequence_get_iter_at_pos (priv->children, index);
+  if (iter)
+    return g_sequence_get (iter);
 
-  return child->widget;
+  return NULL;
+}
+
+/**
+ * egg_list_box_get_row_at_y:
+ * @list_box: An #EggListBox.
+ * @y: position
+ *
+ * Gets the row at the y position.
+ *
+ * Return value: (transfer none): The row.
+ **/
+EggListBoxRow *
+egg_list_box_get_row_at_y (EggListBox *list_box, gint y)
+{
+  EggListBoxRow *row, *found_row;
+  EggListBoxRowPrivate *row_priv;
+  EggListBoxPrivate *priv = list_box->priv;
+  GSequenceIter *iter;
+
+  g_return_val_if_fail (list_box != NULL, NULL);
+
+  /* TODO: This should use g_sequence_search */
+
+  found_row = NULL;
+  for (iter = g_sequence_get_begin_iter (priv->children);
+       !g_sequence_iter_is_end (iter);
+       iter = g_sequence_iter_next (iter))
+    {
+      row = (EggListBoxRow*) g_sequence_get (iter);
+      row_priv = row->priv;
+      if (y >= row_priv->y && y < (row_priv->y + row_priv->height))
+        {
+          found_row = row;
+          break;
+        }
+    }
+
+  return found_row;
 }
 
 
 /**
- * egg_list_box_select_child:
- * @self: a #EggListBox
- * @child: (allow-none): The child to select or %NULL
+ * egg_list_box_select_row:
+ * @list_box: a #EggListBox
+ * @row: (allow-none): The row to select or %NULL
  */
 void
-egg_list_box_select_child (EggListBox *list_box, GtkWidget *child)
+egg_list_box_select_row (EggListBox *list_box, EggListBoxRow *row)
 {
-  EggListBoxChildInfo *info = NULL;
-
   g_return_if_fail (list_box != NULL);
 
-  if (child != NULL)
-    info = egg_list_box_lookup_info (list_box, child);
-
-  egg_list_box_update_selected (list_box, info);
+  egg_list_box_update_selected (list_box, row);
 }
 
 void
@@ -596,12 +598,17 @@ egg_list_box_set_selection_mode (EggListBox *list_box, GtkSelectionMode mode)
   g_object_notify_by_pspec (G_OBJECT (list_box), properties[PROP_SELECTION_MODE]);
 }
 
-
+/**
+ * egg_list_box_set_filter_func:
+ * @filter_func: (allow-none):
+ * @user_data:
+ * @destroy:
+ */
 void
 egg_list_box_set_filter_func (EggListBox *list_box,
-                             EggListBoxFilterFunc f,
-                             void *f_target,
-                             GDestroyNotify f_target_destroy_notify)
+                             EggListBoxFilterFunc filter_func,
+                             gpointer user_data,
+                             GDestroyNotify destroy)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
@@ -610,18 +617,24 @@ egg_list_box_set_filter_func (EggListBox *list_box,
   if (priv->filter_func_target_destroy_notify != NULL)
     priv->filter_func_target_destroy_notify (priv->filter_func_target);
 
-  priv->filter_func = f;
-  priv->filter_func_target = f_target;
-  priv->filter_func_target_destroy_notify = f_target_destroy_notify;
+  priv->filter_func = filter_func;
+  priv->filter_func_target = user_data;
+  priv->filter_func_target_destroy_notify = destroy;
 
   egg_list_box_refilter (list_box);
 }
 
+/**
+ * egg_list_box_set_separator_funcs:
+ * @update_separator: (allow-none):
+ * @user_data:
+ * @destroy:
+ */
 void
 egg_list_box_set_separator_funcs (EggListBox *list_box,
                                  EggListBoxUpdateSeparatorFunc update_separator,
-                                 void *update_separator_target,
-                                 GDestroyNotify update_separator_target_destroy_notify)
+                                 gpointer user_data,
+                                 GDestroyNotify destroy)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
@@ -631,8 +644,8 @@ egg_list_box_set_separator_funcs (EggListBox *list_box,
     priv->update_separator_func_target_destroy_notify (priv->update_separator_func_target);
 
   priv->update_separator_func = update_separator;
-  priv->update_separator_func_target = update_separator_target;
-  priv->update_separator_func_target_destroy_notify = update_separator_target_destroy_notify;
+  priv->update_separator_func_target = user_data;
+  priv->update_separator_func_target_destroy_notify = destroy;
   egg_list_box_reseparate (list_box);
 }
 
@@ -653,14 +666,13 @@ egg_list_box_refilter (EggListBox *list_box)
 }
 
 static gint
-do_sort (EggListBoxChildInfo *a,
-        EggListBoxChildInfo *b,
+do_sort (EggListBoxRow *a,
+        EggListBoxRow *b,
         EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
-  return priv->sort_func (a->widget, b->widget,
-                         priv->sort_func_target);
+  return priv->sort_func (a, b, priv->sort_func_target);
 }
 
 void
@@ -694,15 +706,15 @@ egg_list_box_reseparate (EggListBox *list_box)
 
 /**
  * egg_list_box_set_sort_func:
- * @f: (closure f_target):
- * @f_target: (allow-none):
- * @f_target_destroy_notify: (allow-none):
+ * @sort_func: (closure user_data) (allow-none):
+ * @user_data:
+ * @destroy:
  */
 void
 egg_list_box_set_sort_func (EggListBox *list_box,
-                           EggListBoxSortFunc f,
-                           void *f_target,
-                           GDestroyNotify f_target_destroy_notify)
+                           EggListBoxSortFunc sort_func,
+                           gpointer user_data,
+                           GDestroyNotify destroy)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
@@ -711,39 +723,34 @@ egg_list_box_set_sort_func (EggListBox *list_box,
   if (priv->sort_func_target_destroy_notify != NULL)
     priv->sort_func_target_destroy_notify (priv->sort_func_target);
 
-  priv->sort_func = f;
-  priv->sort_func_target = f_target;
-  priv->sort_func_target_destroy_notify = f_target_destroy_notify;
+  priv->sort_func = sort_func;
+  priv->sort_func_target = user_data;
+  priv->sort_func_target_destroy_notify = destroy;
   egg_list_box_resort (list_box);
 }
 
 void
-egg_list_box_child_changed (EggListBox *list_box, GtkWidget *widget)
+egg_list_box_row_changed (EggListBox *list_box, EggListBoxRow *row)
 {
   EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *info;
   GSequenceIter *prev_next, *next;
 
   g_return_if_fail (list_box != NULL);
-  g_return_if_fail (widget != NULL);
-
-  info = egg_list_box_lookup_info (list_box, widget);
-  if (info == NULL)
-    return;
+  g_return_if_fail (row != NULL);
 
-  prev_next = egg_list_box_get_next_visible (list_box, info->iter);
+  prev_next = egg_list_box_get_next_visible (list_box, row->priv->iter);
   if (priv->sort_func != NULL)
     {
-      g_sequence_sort_changed (info->iter,
+      g_sequence_sort_changed (row->priv->iter,
                               (GCompareDataFunc)do_sort,
                               list_box);
       gtk_widget_queue_resize (GTK_WIDGET (list_box));
     }
-  egg_list_box_apply_filter (list_box, info->widget);
+  egg_list_box_apply_filter (list_box, row);
   if (gtk_widget_get_visible (GTK_WIDGET (list_box)))
     {
-      next = egg_list_box_get_next_visible (list_box, info->iter);
-      egg_list_box_update_separator (list_box, info->iter);
+      next = egg_list_box_get_next_visible (list_box, row->priv->iter);
+      egg_list_box_update_separator (list_box, row->priv->iter);
       egg_list_box_update_separator (list_box, next);
       egg_list_box_update_separator (list_box, prev_next);
     }
@@ -784,106 +791,77 @@ egg_list_box_add_move_binding (GtkBindingSet *binding_set,
                                "move-cursor", (guint) 2, GTK_TYPE_MOVEMENT_STEP, step, G_TYPE_INT, count, 
NULL);
 }
 
-static EggListBoxChildInfo*
-egg_list_box_find_child_at_y (EggListBox *list_box, gint y)
-{
-  EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *child_info;
-  GSequenceIter *iter;
-  EggListBoxChildInfo *info;
-
-  child_info = NULL;
-  for (iter = g_sequence_get_begin_iter (priv->children);
-       !g_sequence_iter_is_end (iter);
-       iter = g_sequence_iter_next (iter))
-    {
-      info = (EggListBoxChildInfo*) g_sequence_get (iter);
-      if (y >= info->y && y < (info->y + info->height))
-       {
-         child_info = info;
-         break;
-       }
-    }
-
-  return child_info;
-}
-
 static void
 egg_list_box_update_cursor (EggListBox *list_box,
-                           EggListBoxChildInfo *child)
+                           EggListBoxRow *row)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
-  priv->cursor_child = child;
+  priv->cursor_row = row;
   gtk_widget_grab_focus (GTK_WIDGET (list_box));
   gtk_widget_queue_draw (GTK_WIDGET (list_box));
-  if (child != NULL && priv->adjustment != NULL)
+  if (row != NULL && priv->adjustment != NULL)
     {
       GtkAllocation allocation;
       gtk_widget_get_allocation (GTK_WIDGET (list_box), &allocation);
       gtk_adjustment_clamp_page (priv->adjustment,
-                                priv->cursor_child->y + allocation.y,
-                                priv->cursor_child->y + allocation.y + priv->cursor_child->height);
+                                priv->cursor_row->priv->y + allocation.y,
+                                priv->cursor_row->priv->y + allocation.y + priv->cursor_row->priv->height);
   }
-  _egg_list_box_accessible_update_cursor (list_box, child ? child->widget : NULL);
+  _egg_list_box_accessible_update_cursor (list_box, row);
 }
 
 static void
 egg_list_box_update_selected (EggListBox *list_box,
-                             EggListBoxChildInfo *child)
+                             EggListBoxRow *row)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
-  if (child != priv->selected_child &&
-      (child == NULL || priv->selection_mode != GTK_SELECTION_NONE))
+  if (row != priv->selected_row &&
+      (row == NULL || priv->selection_mode != GTK_SELECTION_NONE))
     {
-      priv->selected_child = child;
-      g_signal_emit (list_box, signals[CHILD_SELECTED], 0,
-                    (priv->selected_child != NULL) ? priv->selected_child->widget : NULL);
+      priv->selected_row = row;
+      g_signal_emit (list_box, signals[ROW_SELECTED], 0,
+                    priv->selected_row);
       gtk_widget_queue_draw (GTK_WIDGET (list_box));
     }
   _egg_list_box_accessible_selection_changed (list_box);
-  if (child != NULL)
-    egg_list_box_update_cursor (list_box, child);
+  if (row != NULL)
+    egg_list_box_update_cursor (list_box, row);
 }
 
 static void
-egg_list_box_select_and_activate (EggListBox *list_box, EggListBoxChildInfo *child)
+egg_list_box_select_and_activate (EggListBox *list_box, EggListBoxRow *row)
 {
-  GtkWidget *w = NULL;
+  egg_list_box_update_selected (list_box, row);
 
-  if (child != NULL)
-    w = child->widget;
-
-  egg_list_box_update_selected (list_box, child);
-
-  if (w != NULL)
-    g_signal_emit (list_box, signals[CHILD_ACTIVATED], 0, w);
+  if (row != NULL)
+    g_signal_emit (list_box, signals[ROW_ACTIVATED], 0, row);
 }
 
 static void
-egg_list_box_update_prelight (EggListBox *list_box, EggListBoxChildInfo *child)
+egg_list_box_update_prelight (EggListBox *list_box, EggListBoxRow *row)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
-  if (child != priv->prelight_child)
+  if (row != priv->prelight_row)
     {
-      priv->prelight_child = child;
+      priv->prelight_row = row;
       gtk_widget_queue_draw (GTK_WIDGET (list_box));
     }
 }
 
 static void
-egg_list_box_update_active (EggListBox *list_box, EggListBoxChildInfo *child)
+egg_list_box_update_active (EggListBox *list_box, EggListBoxRow *row)
 {
   EggListBoxPrivate *priv = list_box->priv;
   gboolean val;
 
-  val = priv->active_child == child;
-  if (priv->active_child != NULL &&
-      val != priv->active_child_active)
+  val = priv->active_row == row;
+  if (priv->active_row != NULL &&
+      val != priv->active_row_active)
     {
-      priv->active_child_active = val;
+      priv->active_row_active = val;
       gtk_widget_queue_draw (GTK_WIDGET (list_box));
     }
 }
@@ -893,15 +871,15 @@ egg_list_box_real_enter_notify_event (GtkWidget *widget,
                                      GdkEventCrossing *event)
 {
   EggListBox *list_box = EGG_LIST_BOX (widget);
-  EggListBoxChildInfo *child;
+  EggListBoxRow *row;
 
 
   if (event->window != gtk_widget_get_window (GTK_WIDGET (list_box)))
     return FALSE;
 
-  child = egg_list_box_find_child_at_y (list_box, event->y);
-  egg_list_box_update_prelight (list_box, child);
-  egg_list_box_update_active (list_box, child);
+  row = egg_list_box_get_row_at_y (list_box, event->y);
+  egg_list_box_update_prelight (list_box, row);
+  egg_list_box_update_active (list_box, row);
 
   return FALSE;
 }
@@ -911,18 +889,18 @@ egg_list_box_real_leave_notify_event (GtkWidget *widget,
                                      GdkEventCrossing *event)
 {
   EggListBox *list_box = EGG_LIST_BOX (widget);
-  EggListBoxChildInfo *child = NULL;
+  EggListBoxRow *row = NULL;
 
   if (event->window != gtk_widget_get_window (GTK_WIDGET (list_box)))
     return FALSE;
 
   if (event->detail != GDK_NOTIFY_INFERIOR)
-    child = NULL;
+    row = NULL;
   else
-    child = egg_list_box_find_child_at_y (list_box, event->y);
+    row = egg_list_box_get_row_at_y (list_box, event->y);
 
-  egg_list_box_update_prelight (list_box, child);
-  egg_list_box_update_active (list_box, child);
+  egg_list_box_update_prelight (list_box, row);
+  egg_list_box_update_active (list_box, row);
 
   return FALSE;
 }
@@ -932,7 +910,7 @@ egg_list_box_real_motion_notify_event (GtkWidget *widget,
                                       GdkEventMotion *event)
 {
   EggListBox *list_box = EGG_LIST_BOX (widget);
-  EggListBoxChildInfo *child;
+  EggListBoxRow *row;
   GdkWindow *window, *event_window;
   gint relative_y;
   gdouble parent_y;
@@ -948,9 +926,9 @@ egg_list_box_real_motion_notify_event (GtkWidget *widget,
       event_window = gdk_window_get_effective_parent (event_window);
     }
 
-  child = egg_list_box_find_child_at_y (list_box, relative_y);
-  egg_list_box_update_prelight (list_box, child);
-  egg_list_box_update_active (list_box, child);
+  row = egg_list_box_get_row_at_y (list_box, relative_y);
+  egg_list_box_update_prelight (list_box, row);
+  egg_list_box_update_active (list_box, row);
 
   return FALSE;
 }
@@ -964,17 +942,17 @@ egg_list_box_real_button_press_event (GtkWidget *widget,
 
   if (event->button == GDK_BUTTON_PRIMARY)
     {
-      EggListBoxChildInfo *child;
-      child = egg_list_box_find_child_at_y (list_box, event->y);
-      if (child != NULL)
+      EggListBoxRow *row;
+      row = egg_list_box_get_row_at_y (list_box, event->y);
+      if (row != NULL)
        {
-         priv->active_child = child;
-         priv->active_child_active = TRUE;
+         priv->active_row = row;
+         priv->active_row_active = TRUE;
          gtk_widget_queue_draw (GTK_WIDGET (list_box));
          if (event->type == GDK_2BUTTON_PRESS &&
              !priv->activate_single_click)
-           g_signal_emit (list_box, signals[CHILD_ACTIVATED], 0,
-                          child->widget);
+           g_signal_emit (list_box, signals[ROW_ACTIVATED], 0,
+                          row);
 
        }
       /* TODO:
@@ -994,16 +972,16 @@ egg_list_box_real_button_release_event (GtkWidget *widget,
 
   if (event->button == GDK_BUTTON_PRIMARY)
     {
-      if (priv->active_child != NULL &&
-          priv->active_child_active)
+      if (priv->active_row != NULL &&
+          priv->active_row_active)
         {
           if (priv->activate_single_click)
-            egg_list_box_select_and_activate (list_box, priv->active_child);
+            egg_list_box_select_and_activate (list_box, priv->active_row);
           else
-            egg_list_box_update_selected (list_box, priv->active_child);
+            egg_list_box_update_selected (list_box, priv->active_row);
         }
-      priv->active_child = NULL;
-      priv->active_child_active = FALSE;
+      priv->active_row = NULL;
+      priv->active_row_active = FALSE;
       gtk_widget_queue_draw (GTK_WIDGET (list_box));
   }
 
@@ -1017,7 +995,7 @@ egg_list_box_real_show (GtkWidget *widget)
 
   egg_list_box_reseparate (list_box);
 
-  GTK_WIDGET_CLASS (egg_list_box_parent_class)->show ((GtkWidget*) G_TYPE_CHECK_INSTANCE_CAST (list_box, 
GTK_TYPE_CONTAINER, GtkContainer));
+  GTK_WIDGET_CLASS (egg_list_box_parent_class)->show (widget);
 }
 
 
@@ -1028,9 +1006,9 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
   EggListBoxPrivate *priv = list_box->priv;
   gboolean had_focus = FALSE;
   gboolean focus_into = FALSE;
-  GtkWidget* recurse_into;
-  EggListBoxChildInfo *current_focus_child;
-  EggListBoxChildInfo *next_focus_child;
+  EggListBoxRow *recurse_into;
+  EggListBoxRow *current_focus_row;
+  EggListBoxRow *next_focus_row;
   gboolean modify_selection_pressed;
   GdkModifierType state = 0;
 
@@ -1038,17 +1016,17 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
   focus_into = TRUE;
 
   g_object_get (GTK_WIDGET (list_box), "has-focus", &had_focus, NULL);
-  current_focus_child = NULL;
-  next_focus_child = NULL;
+  current_focus_row = NULL;
+  next_focus_row = NULL;
   if (had_focus)
     {
       /* If on row, going right, enter into possible container */
       if (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD)
        {
-         if (priv->cursor_child != NULL)
-           recurse_into = priv->cursor_child->widget;
+         if (priv->cursor_row != NULL)
+           recurse_into = priv->cursor_row;
        }
-      current_focus_child = priv->cursor_child;
+      current_focus_row = priv->cursor_row;
       /* Unless we're going up/down we're always leaving
       the container */
       if (direction != GTK_DIR_UP && direction != GTK_DIR_DOWN)
@@ -1056,9 +1034,9 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
     }
   else if (gtk_container_get_focus_child ((GtkContainer*) list_box) != NULL)
     {
-      /* There is a focus child, always navigat inside it first */
-      recurse_into = gtk_container_get_focus_child ((GtkContainer*) list_box);
-      current_focus_child = egg_list_box_lookup_info (list_box, recurse_into);
+      /* There is a focus child, always navigate inside it first */
+      recurse_into = EGG_LIST_BOX_ROW (gtk_container_get_focus_child ((GtkContainer*) list_box));
+      current_focus_row = recurse_into;
 
       /* If exiting child container to the right, exit row */
       if (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD)
@@ -1066,21 +1044,21 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
 
       /* If exiting child container to the left, select row or out */
       if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
-       next_focus_child = current_focus_child;
+       next_focus_row = current_focus_row;
     }
   else
     {
       /* If coming from the left, enter into possible container */
       if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
        {
-         if (priv->selected_child != NULL)
-           recurse_into = priv->selected_child->widget;
+         if (priv->selected_row != NULL)
+           recurse_into = priv->selected_row;
        }
     }
 
   if (recurse_into != NULL)
     {
-      if (gtk_widget_child_focus (recurse_into, direction))
+      if (gtk_widget_child_focus (GTK_WIDGET (recurse_into), direction))
        return TRUE;
     }
 
@@ -1089,24 +1067,23 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
 
   /* TODO: This doesn't handle up/down going into a focusable separator */
 
-  if (next_focus_child == NULL)
+  if (next_focus_row == NULL)
     {
-      if (current_focus_child != NULL)
+      if (current_focus_row != NULL)
        {
          GSequenceIter* i;
          if (direction == GTK_DIR_UP)
            {
-             i = egg_list_box_get_previous_visible (list_box, current_focus_child->iter);
+             i = egg_list_box_get_previous_visible (list_box, current_focus_row->priv->iter);
              if (i != NULL)
-               next_focus_child = g_sequence_get (i);
+               next_focus_row = g_sequence_get (i);
 
            }
          else
            {
-             i = egg_list_box_get_next_visible (list_box, current_focus_child->iter);
+             i = egg_list_box_get_next_visible (list_box, current_focus_row->priv->iter);
              if (!g_sequence_iter_is_end (i))
-               next_focus_child = g_sequence_get (i);
-
+               next_focus_row = g_sequence_get (i);
            }
        }
       else
@@ -1115,21 +1092,21 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
            {
            case GTK_DIR_UP:
            case GTK_DIR_TAB_BACKWARD:
-             next_focus_child = priv->selected_child;
-             if (next_focus_child == NULL)
-               next_focus_child = egg_list_box_get_last_visible (list_box);
+             next_focus_row = priv->selected_row;
+             if (next_focus_row == NULL)
+               next_focus_row = egg_list_box_get_last_visible (list_box);
              break;
            default:
-             next_focus_child = priv->selected_child;
-             if (next_focus_child == NULL)
-               next_focus_child =
+             next_focus_row = priv->selected_row;
+             if (next_focus_row == NULL)
+               next_focus_row =
                  egg_list_box_get_first_visible (list_box);
              break;
            }
        }
     }
 
-  if (next_focus_child == NULL)
+  if (next_focus_row == NULL)
     {
       if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
        {
@@ -1152,33 +1129,33 @@ egg_list_box_real_focus (GtkWidget* widget, GtkDirectionType direction)
     }
 
   if (modify_selection_pressed)
-    egg_list_box_update_cursor (list_box, next_focus_child);
+    egg_list_box_update_cursor (list_box, next_focus_row);
   else
-    egg_list_box_update_selected (list_box, next_focus_child);
+    egg_list_box_update_selected (list_box, next_focus_row);
 
   return TRUE;
 }
 
 typedef struct {
-  EggListBoxChildInfo *child;
+  EggListBoxRow *row;
   GtkStateFlags state;
-} ChildFlags;
+} RowFlags;
 
-static ChildFlags*
-child_flags_find_or_add (ChildFlags *array,
-                        int *array_length,
-                        EggListBoxChildInfo *to_find)
+static RowFlags*
+row_flags_find_or_add (RowFlags *array,
+                       int *array_length,
+                       EggListBoxRow *to_find)
 {
   gint i;
 
   for (i = 0; i < *array_length; i++)
     {
-      if (array[i].child == to_find)
+      if (array[i].row == to_find)
        return &array[i];
     }
 
   *array_length = *array_length + 1;
-  array[*array_length - 1].child = to_find;
+  array[*array_length - 1].row = to_find;
   array[*array_length - 1].state = 0;
   return &array[*array_length - 1];
 }
@@ -1191,7 +1168,7 @@ egg_list_box_real_draw (GtkWidget* widget, cairo_t* cr)
   GtkAllocation allocation = {0};
   GtkStyleContext* context;
   GtkStateFlags state;
-  ChildFlags flags[3], *found;
+  RowFlags flags[3], *found;
   gint flags_length;
   gint focus_pad;
   int i;
@@ -1202,40 +1179,40 @@ egg_list_box_real_draw (GtkWidget* widget, cairo_t* cr)
   gtk_render_background (context, cr, (gdouble) 0, (gdouble) 0, (gdouble) allocation.width, (gdouble) 
allocation.height);
   flags_length = 0;
 
-  if (priv->selected_child != NULL)
+  if (priv->selected_row != NULL)
     {
-      found = child_flags_find_or_add (flags, &flags_length, priv->selected_child);
+      found = row_flags_find_or_add (flags, &flags_length, priv->selected_row);
       found->state |= (state | GTK_STATE_FLAG_SELECTED);
     }
 
-  if (priv->prelight_child != NULL)
+  if (priv->prelight_row != NULL)
     {
-      found = child_flags_find_or_add (flags, &flags_length, priv->prelight_child);
+      found = row_flags_find_or_add (flags, &flags_length, priv->prelight_row);
       found->state |= (state | GTK_STATE_FLAG_PRELIGHT);
     }
 
-  if (priv->active_child != NULL && priv->active_child_active)
+  if (priv->active_row != NULL && priv->active_row_active)
     {
-      found = child_flags_find_or_add (flags, &flags_length, priv->active_child);
+      found = row_flags_find_or_add (flags, &flags_length, priv->active_row);
       found->state |= (state | GTK_STATE_FLAG_ACTIVE);
     }
 
   for (i = 0; i < flags_length; i++)
     {
-      ChildFlags *flag = &flags[i];
+      RowFlags *flag = &flags[i];
       gtk_style_context_save (context);
       gtk_style_context_set_state (context, flag->state);
-      gtk_render_background (context, cr, 0, flag->child->y, allocation.width, flag->child->height);
+      gtk_render_background (context, cr, 0, flag->row->priv->y, allocation.width, flag->row->priv->height);
       gtk_style_context_restore (context);
     }
 
-  if (gtk_widget_has_visible_focus (GTK_WIDGET (list_box)) && priv->cursor_child != NULL)
+  if (gtk_widget_has_visible_focus (GTK_WIDGET (list_box)) && priv->cursor_row != NULL)
     {
       gtk_style_context_get_style (context,
                                    "focus-padding", &focus_pad,
                                    NULL);
-      gtk_render_focus (context, cr, focus_pad, priv->cursor_child->y + focus_pad,
-                        allocation.width - 2 * focus_pad, priv->cursor_child->height - 2 * focus_pad);
+      gtk_render_focus (context, cr, focus_pad, priv->cursor_row->priv->y + focus_pad,
+                        allocation.width - 2 * focus_pad, priv->cursor_row->priv->height - 2 * focus_pad);
     }
 
   GTK_WIDGET_CLASS (egg_list_box_parent_class)->draw ((GtkWidget*) G_TYPE_CHECK_INSTANCE_CAST (list_box, 
GTK_TYPE_CONTAINER, GtkContainer), cr);
@@ -1274,76 +1251,76 @@ egg_list_box_real_realize (GtkWidget* widget)
 
 
 static void
-egg_list_box_apply_filter (EggListBox *list_box, GtkWidget *child)
+egg_list_box_apply_filter (EggListBox *list_box, EggListBoxRow *row)
 {
   EggListBoxPrivate *priv = list_box->priv;
   gboolean do_show;
 
   do_show = TRUE;
   if (priv->filter_func != NULL)
-    do_show = priv->filter_func (child, priv->filter_func_target);
+    do_show = priv->filter_func (row, priv->filter_func_target);
 
-  gtk_widget_set_child_visible (child, do_show);
+  gtk_widget_set_child_visible (GTK_WIDGET (row), do_show);
 }
 
 static void
 egg_list_box_apply_filter_all (EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
   GSequenceIter *iter;
 
   for (iter = g_sequence_get_begin_iter (priv->children);
        !g_sequence_iter_is_end (iter);
        iter = g_sequence_iter_next (iter))
     {
-      child_info = g_sequence_get (iter);
-      egg_list_box_apply_filter (list_box, child_info->widget);
+      row = g_sequence_get (iter);
+      egg_list_box_apply_filter (list_box, row);
     }
 }
 
 /* Children are visible if they are shown by the app (visible)
    and not filtered out (child_visible) by the listbox */
 static gboolean
-child_is_visible (GtkWidget *child)
+row_is_visible (EggListBoxRow *row)
 {
-  return gtk_widget_get_visible (child) && gtk_widget_get_child_visible (child);
+  return gtk_widget_get_visible (GTK_WIDGET (row)) && gtk_widget_get_child_visible (GTK_WIDGET (row));
 }
 
-static EggListBoxChildInfo*
+static EggListBoxRow *
 egg_list_box_get_first_visible (EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
   GSequenceIter *iter;
 
   for (iter = g_sequence_get_begin_iter (priv->children);
        !g_sequence_iter_is_end (iter);
        iter = g_sequence_iter_next (iter))
     {
-       child_info = g_sequence_get (iter);
-       if (child_is_visible (child_info->widget))
-         return child_info;
+       row = g_sequence_get (iter);
+       if (row_is_visible (row))
+         return row;
     }
 
   return NULL;
 }
 
 
-static EggListBoxChildInfo*
+static EggListBoxRow *
 egg_list_box_get_last_visible (EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
   GSequenceIter *iter;
 
   iter = g_sequence_get_end_iter (priv->children);
   while (!g_sequence_iter_is_begin (iter))
     {
       iter = g_sequence_iter_prev (iter);
-      child_info = g_sequence_get (iter);
-      if (child_is_visible (child_info->widget))
-       return child_info;
+      row = g_sequence_get (iter);
+      if (row_is_visible (row))
+       return row;
     }
 
   return NULL;
@@ -1353,7 +1330,7 @@ static GSequenceIter*
 egg_list_box_get_previous_visible (EggListBox *list_box,
                                   GSequenceIter* iter)
 {
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
 
   if (g_sequence_iter_is_begin (iter))
     return NULL;
@@ -1361,8 +1338,8 @@ egg_list_box_get_previous_visible (EggListBox *list_box,
   do
     {
       iter = g_sequence_iter_prev (iter);
-      child_info = g_sequence_get (iter);
-      if (child_is_visible (child_info->widget))
+      row = g_sequence_get (iter);
+      if (row_is_visible (row))
        return iter;
     }
   while (!g_sequence_iter_is_begin (iter));
@@ -1373,7 +1350,7 @@ egg_list_box_get_previous_visible (EggListBox *list_box,
 static GSequenceIter*
 egg_list_box_get_next_visible (EggListBox *list_box, GSequenceIter* iter)
 {
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
 
   if (g_sequence_iter_is_end (iter))
     return iter;
@@ -1383,8 +1360,8 @@ egg_list_box_get_next_visible (EggListBox *list_box, GSequenceIter* iter)
       iter = g_sequence_iter_next (iter);
       if (!g_sequence_iter_is_end (iter))
        {
-       child_info = g_sequence_get (iter);
-       if (child_is_visible (child_info->widget))
+       row = g_sequence_get (iter);
+       if (row_is_visible (row))
          return iter;
        }
     }
@@ -1398,52 +1375,47 @@ static void
 egg_list_box_update_separator (EggListBox *list_box, GSequenceIter* iter)
 {
   EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *info;
+  EggListBoxRow *row;
   GSequenceIter *before_iter;
-  GtkWidget *child;
-  GtkWidget *before_child;
-  EggListBoxChildInfo *before_info;
+  EggListBoxRow *before_row;
   GtkWidget *old_separator;
 
   if (iter == NULL || g_sequence_iter_is_end (iter))
     return;
 
-  info = g_sequence_get (iter);
+  row = g_sequence_get (iter);
   before_iter = egg_list_box_get_previous_visible (list_box, iter);
-  child = info->widget;
-  if (child)
-    g_object_ref (child);
-  before_child = NULL;
+  if (row)
+    g_object_ref (row);
+  before_row = NULL;
   if (before_iter != NULL)
     {
-      before_info = g_sequence_get (before_iter);
-      before_child = before_info->widget;
-      if (before_child)
-       g_object_ref (before_child);
+      before_row = g_sequence_get (before_iter);
+      if (before_row)
+       g_object_ref (before_row);
     }
 
   if (priv->update_separator_func != NULL &&
-      child_is_visible (child))
+      row_is_visible (row))
     {
-      old_separator = info->separator;
+      old_separator = row->priv->separator;
       if (old_separator)
        g_object_ref (old_separator);
-      priv->update_separator_func (&info->separator,
-                                  child,
-                                  before_child,
+      priv->update_separator_func (row,
+                                  before_row,
                                   priv->update_separator_func_target);
-      if (old_separator != info->separator)
+      if (old_separator != row->priv->separator)
        {
          if (old_separator != NULL)
            {
              gtk_widget_unparent (old_separator);
              g_hash_table_remove (priv->separator_hash, old_separator);
            }
-         if (info->separator != NULL)
+         if (row->priv->separator != NULL)
            {
-             g_hash_table_insert (priv->separator_hash, info->separator, info);
-             gtk_widget_set_parent (info->separator, GTK_WIDGET (list_box));
-             gtk_widget_show (info->separator);
+             g_hash_table_insert (priv->separator_hash, row->priv->separator, row);
+             gtk_widget_set_parent (row->priv->separator, GTK_WIDGET (list_box));
+             gtk_widget_show (row->priv->separator);
            }
          gtk_widget_queue_resize (GTK_WIDGET (list_box));
        }
@@ -1452,69 +1424,66 @@ egg_list_box_update_separator (EggListBox *list_box, GSequenceIter* iter)
     }
   else
     {
-      if (info->separator != NULL)
+      if (row->priv->separator != NULL)
        {
-         g_hash_table_remove (priv->separator_hash, info->separator);
-         gtk_widget_unparent (info->separator);
-         g_clear_object (&info->separator);
+         g_hash_table_remove (priv->separator_hash, row->priv->separator);
+         gtk_widget_unparent (row->priv->separator);
+          egg_list_box_row_set_separator (row, NULL);
          gtk_widget_queue_resize (GTK_WIDGET (list_box));
        }
     }
-  if (before_child)
-    g_object_unref (before_child);
-  if (child)
-    g_object_unref (child);
-}
-
-static EggListBoxChildInfo*
-egg_list_box_lookup_info (EggListBox *list_box, GtkWidget* child)
-{
-  EggListBoxPrivate *priv = list_box->priv;
-
-  return g_hash_table_lookup (priv->child_hash, child);
+  if (before_row)
+    g_object_unref (before_row);
+  if (row)
+    g_object_unref (row);
 }
 
 static void
 child_visibility_changed (GObject* object, GParamSpec* pspec, EggListBox *list_box)
 {
-  EggListBoxChildInfo *info;
+  EggListBoxRow *row;
 
   if (gtk_widget_get_visible (GTK_WIDGET (list_box)))
     {
-      info = egg_list_box_lookup_info (list_box, GTK_WIDGET (object));
-      if (info != NULL)
-       {
-         egg_list_box_update_separator (list_box, info->iter);
-         egg_list_box_update_separator (list_box,
-                                        egg_list_box_get_next_visible (list_box, info->iter));
-       }
+      row = EGG_LIST_BOX_ROW (object);
+      egg_list_box_update_separator (list_box, row->priv->iter);
+      egg_list_box_update_separator (list_box,
+                                     egg_list_box_get_next_visible (list_box, row->priv->iter));
     }
 }
 
 static void
-egg_list_box_real_add (GtkContainer* container, GtkWidget* child)
+egg_list_box_real_add (GtkContainer* container, GtkWidget *child)
 {
   EggListBox *list_box = EGG_LIST_BOX (container);
   EggListBoxPrivate *priv = list_box->priv;
-  EggListBoxChildInfo *info;
+  EggListBoxRow *row;
   GSequenceIter* iter = NULL;
-  info = egg_list_box_child_info_new (child);
-  g_hash_table_insert (priv->child_hash, child, info);
+
+  if (EGG_IS_LIST_BOX_ROW (child))
+    row = EGG_LIST_BOX_ROW (child);
+  else
+    {
+      row = EGG_LIST_BOX_ROW (egg_list_box_row_new ());
+      gtk_widget_show (GTK_WIDGET (row));
+      gtk_container_add (GTK_CONTAINER (row), child);
+    }
+
   if (priv->sort_func != NULL)
-    iter = g_sequence_insert_sorted (priv->children, info,
+    iter = g_sequence_insert_sorted (priv->children, row,
                                     (GCompareDataFunc)do_sort, list_box);
   else
-    iter = g_sequence_append (priv->children, info);
+    iter = g_sequence_append (priv->children, row);
 
-  info->iter = iter;
-  gtk_widget_set_parent (child, GTK_WIDGET (list_box));
-  egg_list_box_apply_filter (list_box, child);
+  row->priv->iter = iter;
+  gtk_widget_set_parent (GTK_WIDGET (row), GTK_WIDGET (list_box));
+  egg_list_box_apply_filter (list_box, row);
   if (gtk_widget_get_visible (GTK_WIDGET (list_box)))
     {
       egg_list_box_update_separator (list_box, iter);
       egg_list_box_update_separator (list_box, egg_list_box_get_next_visible (list_box, iter));
     }
-  g_signal_connect_object (child, "notify::visible",
+  g_signal_connect_object (row, "notify::visible",
                           (GCallback) child_visibility_changed, list_box, 0);
 }
 
@@ -1524,7 +1493,7 @@ egg_list_box_real_remove (GtkContainer* container, GtkWidget* child)
   EggListBox *list_box = EGG_LIST_BOX (container);
   EggListBoxPrivate *priv = list_box->priv;
   gboolean was_visible;
-  EggListBoxChildInfo *info;
+  EggListBoxRow *row;
   GSequenceIter *next;
 
   g_return_if_fail (child != NULL);
@@ -1532,45 +1501,50 @@ egg_list_box_real_remove (GtkContainer* container, GtkWidget* child)
 
   g_signal_handlers_disconnect_by_func (child, (GCallback) child_visibility_changed, list_box);
 
-  info = egg_list_box_lookup_info (list_box, child);
-  if (info == NULL)
+  if (!EGG_IS_LIST_BOX_ROW (child))
     {
-      info = g_hash_table_lookup (priv->separator_hash, child);
-      if (info != NULL)
+      row = g_hash_table_lookup (priv->separator_hash, child);
+      if (row != NULL)
        {
          g_hash_table_remove (priv->separator_hash, child);
-         g_clear_object (&info->separator);
+         g_clear_object (&row->priv->separator);
          gtk_widget_unparent (child);
          if (was_visible && gtk_widget_get_visible (GTK_WIDGET (list_box)))
            gtk_widget_queue_resize (GTK_WIDGET (list_box));
        }
       else
        {
-         g_warning ("egg-list-box.vala:846: Tried to remove non-child %p\n", child);
+         g_warning ("Tried to remove non-child %p\n", child);
        }
       return;
     }
 
-  if (info->separator != NULL)
+  row = EGG_LIST_BOX_ROW (child);
+  if (g_sequence_iter_get_sequence (row->priv->iter) != priv->children)
     {
-      g_hash_table_remove (priv->separator_hash, info->separator);
-      gtk_widget_unparent (info->separator);
-      g_clear_object (&info->separator);
+      g_warning ("Tried to remove non-child %p\n", child);
+      return;
     }
 
-  if (info == priv->selected_child)
+  if (row->priv->separator != NULL)
+    {
+      g_hash_table_remove (priv->separator_hash, row->priv->separator);
+      gtk_widget_unparent (row->priv->separator);
+      g_clear_object (&row->priv->separator);
+    }
+
+  if (row == priv->selected_row)
       egg_list_box_update_selected (list_box, NULL);
-  if (info == priv->prelight_child)
-    priv->prelight_child = NULL;
-  if (info == priv->cursor_child)
-    priv->cursor_child = NULL;
-  if (info == priv->active_child)
-    priv->active_child = NULL;
-
-  next = egg_list_box_get_next_visible (list_box, info->iter);
+  if (row == priv->prelight_row)
+    priv->prelight_row = NULL;
+  if (row == priv->cursor_row)
+    priv->cursor_row = NULL;
+  if (row == priv->active_row)
+    priv->active_row = NULL;
+
+  next = egg_list_box_get_next_visible (list_box, row->priv->iter);
   gtk_widget_unparent (child);
-  g_hash_table_remove (priv->child_hash, child);
-  g_sequence_remove (info->iter);
+  g_sequence_remove (row->priv->iter);
   if (gtk_widget_get_visible (GTK_WIDGET (list_box)))
     egg_list_box_update_separator (list_box, next);
 
@@ -1588,16 +1562,16 @@ egg_list_box_real_forall_internal (GtkContainer* container,
   EggListBox *list_box = EGG_LIST_BOX (container);
   EggListBoxPrivate *priv = list_box->priv;
   GSequenceIter *iter;
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
 
   iter = g_sequence_get_begin_iter (priv->children);
   while (!g_sequence_iter_is_end (iter))
     {
-      child_info = g_sequence_get (iter);
+      row = g_sequence_get (iter);
       iter = g_sequence_iter_next (iter);
-      if (child_info->separator != NULL && include_internals)
-       callback (child_info->separator, callback_target);
-      callback (child_info->widget, callback_target);
+      if (row->priv->separator != NULL && include_internals)
+       callback (row->priv->separator, callback_target);
+      callback (GTK_WIDGET (row), callback_target);
     }
 }
 
@@ -1617,7 +1591,10 @@ egg_list_box_real_compute_expand_internal (GtkWidget* widget,
 static GType
 egg_list_box_real_child_type (GtkContainer* container)
 {
-  return GTK_TYPE_WIDGET;
+  /* We really support any type but we wrap it in a row. But that is more
+     like a C helper function, in an abstract sense we only support
+     row children, so that is what tools accessing this should use. */
+  return EGG_TYPE_LIST_BOX_ROW;
 }
 
 static GtkSizeRequestMode
@@ -1661,23 +1638,21 @@ egg_list_box_real_get_preferred_height_for_width (GtkWidget* widget, gint width,
        !g_sequence_iter_is_end (iter);
        iter = g_sequence_iter_next (iter))
     {
-      EggListBoxChildInfo *child_info;
-      GtkWidget *child;
-      gint child_min = 0;
-      child_info = g_sequence_get (iter);
-      child = child_info->widget;
+      EggListBoxRow *row;
+      gint row_min = 0;
 
-      if (!child_is_visible (child))
+      row = g_sequence_get (iter);
+      if (!row_is_visible (row))
        continue;
 
-      if (child_info->separator != NULL)
+      if (row->priv->separator != NULL)
        {
-         gtk_widget_get_preferred_height_for_width (child_info->separator, width, &child_min, NULL);
-         minimum_height += child_min;
+         gtk_widget_get_preferred_height_for_width (row->priv->separator, width, &row_min, NULL);
+         minimum_height += row_min;
        }
-      gtk_widget_get_preferred_height_for_width (child, width - 2 * (focus_width + focus_pad),
-                                                &child_min, NULL);
-      minimum_height += child_min + 2 * (focus_width + focus_pad);
+      gtk_widget_get_preferred_height_for_width (GTK_WIDGET (row), width - 2 * (focus_width + focus_pad),
+                                                &row_min, NULL);
+      minimum_height += row_min + 2 * (focus_width + focus_pad);
     }
 
   /* We always allocate the minimum height, since handling
@@ -1703,10 +1678,9 @@ egg_list_box_real_get_preferred_width (GtkWidget* widget, gint* minimum_width_ou
   gint focus_width;
   gint focus_pad;
   GSequenceIter *iter;
-  EggListBoxChildInfo *child_info;
-  GtkWidget *child;
-  gint child_min;
-  gint child_nat;
+  EggListBoxRow *row;
+  gint row_min;
+  gint row_nat;
 
   context = gtk_widget_get_style_context (GTK_WIDGET (list_box));
   gtk_style_context_get_style (context, "focus-line-width", &focus_width, "focus-padding", &focus_pad, NULL);
@@ -1718,21 +1692,20 @@ egg_list_box_real_get_preferred_width (GtkWidget* widget, gint* minimum_width_ou
        !g_sequence_iter_is_end (iter);
        iter = g_sequence_iter_next (iter))
     {
-      child_info = g_sequence_get (iter);
-      child = child_info->widget;
-      if (!child_is_visible (child))
-       continue;
+      row = g_sequence_get (iter);
+      if (!row_is_visible (row))
+        continue;
 
-      gtk_widget_get_preferred_width (child, &child_min, &child_nat);
-      minimum_width = MAX (minimum_width, child_min + 2 * (focus_width + focus_pad));
-      natural_width = MAX (natural_width, child_nat + 2 * (focus_width + focus_pad));
+      gtk_widget_get_preferred_width (GTK_WIDGET (row), &row_min, &row_nat);
+      minimum_width = MAX (minimum_width, row_min + 2 * (focus_width + focus_pad));
+      natural_width = MAX (natural_width, row_nat + 2 * (focus_width + focus_pad));
 
-      if (child_info->separator != NULL)
-       {
-         gtk_widget_get_preferred_width (child_info->separator, &child_min, &child_nat);
-         minimum_width = MAX (minimum_width, child_min);
-         natural_width = MAX (natural_width, child_nat);
-       }
+      if (row->priv->separator != NULL)
+        {
+          gtk_widget_get_preferred_width (row->priv->separator, &row_min, &row_nat);
+          minimum_width = MAX (minimum_width, row_min);
+          natural_width = MAX (natural_width, row_nat);
+        }
     }
 
   if (minimum_width_out)
@@ -1743,7 +1716,7 @@ egg_list_box_real_get_preferred_width (GtkWidget* widget, gint* minimum_width_ou
 
 static void
 egg_list_box_real_get_preferred_width_for_height (GtkWidget *widget, gint height,
-                                                 gint *minimum_width, gint *natural_width)
+                                                  gint *minimum_width, gint *natural_width)
 {
   EggListBox *list_box = EGG_LIST_BOX (widget);
   egg_list_box_real_get_preferred_width (GTK_WIDGET (list_box), minimum_width, natural_width);
@@ -1756,7 +1729,7 @@ egg_list_box_real_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
   EggListBoxPrivate *priv = list_box->priv;
   GtkAllocation child_allocation;
   GtkAllocation separator_allocation;
-  EggListBoxChildInfo *child_info;
+  EggListBoxRow *row;
   GdkWindow *window;
   GtkWidget *child;
   GSequenceIter *iter;
@@ -1798,34 +1771,33 @@ egg_list_box_real_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
        !g_sequence_iter_is_end (iter);
        iter = g_sequence_iter_next (iter))
     {
-      child_info = g_sequence_get (iter);
-      child = child_info->widget;
-      if (!child_is_visible (child))
+      row = g_sequence_get (iter);
+      if (!row_is_visible (row))
        {
-         child_info->y = child_allocation.y;
-         child_info->height = 0;
+         row->priv->y = child_allocation.y;
+         row->priv->height = 0;
          continue;
        }
 
-      if (child_info->separator != NULL)
+      if (row->priv->separator != NULL)
        {
-         gtk_widget_get_preferred_height_for_width (child_info->separator,
+         gtk_widget_get_preferred_height_for_width (row->priv->separator,
                                                     allocation->width, &child_min, NULL);
          separator_allocation.height = child_min;
          separator_allocation.y = child_allocation.y;
-         gtk_widget_size_allocate (child_info->separator,
+         gtk_widget_size_allocate (row->priv->separator,
                                    &separator_allocation);
          child_allocation.y += child_min;
        }
 
-      child_info->y = child_allocation.y;
+      row->priv->y = child_allocation.y;
       child_allocation.y += focus_width + focus_pad;
 
-      gtk_widget_get_preferred_height_for_width (child, child_allocation.width, &child_min, NULL);
+      gtk_widget_get_preferred_height_for_width (GTK_WIDGET (row), child_allocation.width, &child_min, NULL);
       child_allocation.height = child_min;
 
-      child_info->height = child_allocation.height + 2 * (focus_width + focus_pad);
-      gtk_widget_size_allocate (child, &child_allocation);
+      row->priv->height = child_allocation.height + 2 * (focus_width + focus_pad);
+      gtk_widget_size_allocate (GTK_WIDGET (row), &child_allocation);
 
       child_allocation.y += child_min + focus_width + focus_pad;
     }
@@ -1954,26 +1926,26 @@ egg_list_box_real_drag_motion (GtkWidget *widget, GdkDragContext *context,
 }
 
 static void
-egg_list_box_real_activate_cursor_child (EggListBox *list_box)
+egg_list_box_real_activate_cursor_row (EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
-  egg_list_box_select_and_activate (list_box, priv->cursor_child);
+  egg_list_box_select_and_activate (list_box, priv->cursor_row);
 }
 
 static void
-egg_list_box_real_toggle_cursor_child (EggListBox *list_box)
+egg_list_box_real_toggle_cursor_row (EggListBox *list_box)
 {
   EggListBoxPrivate *priv = list_box->priv;
 
-  if (priv->cursor_child == NULL)
+  if (priv->cursor_row == NULL)
     return;
 
   if (priv->selection_mode == GTK_SELECTION_SINGLE &&
-      priv->selected_child == priv->cursor_child)
+      priv->selected_row == priv->cursor_row)
     egg_list_box_update_selected (list_box, NULL);
   else
-    egg_list_box_select_and_activate (list_box, priv->cursor_child);
+    egg_list_box_select_and_activate (list_box, priv->cursor_row);
 }
 
 static void
@@ -1984,10 +1956,10 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
   EggListBoxPrivate *priv = list_box->priv;
   GdkModifierType state;
   gboolean modify_selection_pressed;
-  EggListBoxChildInfo *child;
+  EggListBoxRow *row;
   GdkModifierType modify_mod_mask;
-  EggListBoxChildInfo *prev;
-  EggListBoxChildInfo *next;
+  EggListBoxRow *prev;
+  EggListBoxRow *next;
   gint page_size;
   GSequenceIter *iter;
   gint start_y;
@@ -2003,19 +1975,19 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
        modify_selection_pressed = TRUE;
     }
 
-  child = NULL;
+  row = NULL;
   switch (step)
     {
     case GTK_MOVEMENT_BUFFER_ENDS:
       if (count < 0)
-       child = egg_list_box_get_first_visible (list_box);
+       row = egg_list_box_get_first_visible (list_box);
       else
-       child = egg_list_box_get_last_visible (list_box);
+       row = egg_list_box_get_last_visible (list_box);
       break;
     case GTK_MOVEMENT_DISPLAY_LINES:
-      if (priv->cursor_child != NULL)
+      if (priv->cursor_row != NULL)
        {
-         iter = priv->cursor_child->iter;
+         iter = priv->cursor_row->priv->iter;
 
          while (count < 0  && iter != NULL)
            {
@@ -2029,7 +2001,7 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
            }
 
          if (iter != NULL && !g_sequence_iter_is_end (iter))
-           child = g_sequence_get (iter);
+           row = g_sequence_get (iter);
        }
       break;
     case GTK_MOVEMENT_PAGES:
@@ -2037,13 +2009,13 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
       if (priv->adjustment != NULL)
        page_size = gtk_adjustment_get_page_increment (priv->adjustment);
 
-      if (priv->cursor_child != NULL)
+      if (priv->cursor_row != NULL)
        {
-         start_y = priv->cursor_child->y;
+         start_y = priv->cursor_row->priv->y;
          end_y = start_y;
-         iter = priv->cursor_child->iter;
+         iter = priv->cursor_row->priv->iter;
 
-         child = priv->cursor_child;
+         row = priv->cursor_row;
          if (count < 0)
            {
              /* Up */
@@ -2054,10 +2026,10 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
                    break;
 
                  prev = g_sequence_get (iter);
-                 if (prev->y < start_y - page_size)
+                 if (prev->priv->y < start_y - page_size)
                    break;
 
-                 child = prev;
+                 row = prev;
                }
            }
          else
@@ -2070,13 +2042,13 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
                    break;
 
                  next = g_sequence_get (iter);
-                 if (next->y > start_y + page_size)
+                 if (next->priv->y > start_y + page_size)
                    break;
 
-                 child = next;
+                 row = next;
                }
            }
-         end_y = child->y;
+         end_y = row->priv->y;
          if (end_y != start_y && priv->adjustment != NULL)
            gtk_adjustment_set_value (priv->adjustment,
                                      gtk_adjustment_get_value (priv->adjustment) +
@@ -2087,7 +2059,7 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
       return;
     }
 
-  if (child == NULL || child == priv->cursor_child)
+  if (row == NULL || row == priv->cursor_row)
     {
       GtkDirectionType direction = count < 0 ? GTK_DIR_UP : GTK_DIR_DOWN;
 
@@ -2106,9 +2078,9 @@ egg_list_box_real_move_cursor (EggListBox *list_box,
       return;
     }
 
-  egg_list_box_update_cursor (list_box, child);
+  egg_list_box_update_cursor (list_box, row);
   if (!modify_selection_pressed)
-    egg_list_box_update_selected (list_box, child);
+    egg_list_box_update_selected (list_box, row);
 }
 
 
@@ -2126,7 +2098,6 @@ egg_list_box_row_init (EggListBoxRow *row)
   row->priv = priv =
     G_TYPE_INSTANCE_GET_PRIVATE (row, EGG_TYPE_LIST_BOX_ROW, EggListBoxRowPrivate);
 
-  gtk_widget_set_can_focus (GTK_WIDGET (row), TRUE);
   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (row), TRUE);
 }
 
@@ -2162,12 +2133,44 @@ egg_list_box_row_set_property (GObject      *obj,
     }
 }
 
+/**
+ * egg_list_box_row_get_separator:
+ *
+ * Return value: (transfer none): The current separator.
+ */
+GtkWidget *
+egg_list_box_row_get_separator (EggListBoxRow *row)
+{
+  return row->priv->separator;
+}
+
+/**
+ * egg_list_box_row_set_separator:
+ * @separator: (allow-none):
+ *
+ */
+void
+egg_list_box_row_set_separator (EggListBoxRow *row,
+                                GtkWidget *separator)
+{
+  if (row->priv->separator)
+    g_object_unref (row->priv->separator);
+
+  row->priv->separator = separator;
+
+  if (separator)
+    g_object_ref (separator);
+}
+
+
 static void
 egg_list_box_row_finalize (GObject *obj)
 {
   EggListBoxRow *row = EGG_LIST_BOX_ROW (obj);
   EggListBoxRowPrivate *priv = row->priv;
 
+  g_clear_object (&priv->separator);
+
   G_OBJECT_CLASS (egg_list_box_row_parent_class)->finalize (obj);
 }
 
diff --git a/egg-list-box.h b/egg-list-box.h
index fe27282..84e2261 100644
--- a/egg-list-box.h
+++ b/egg-list-box.h
@@ -18,6 +18,10 @@ typedef struct _EggListBox EggListBox;
 typedef struct _EggListBoxClass EggListBoxClass;
 typedef struct _EggListBoxPrivate EggListBoxPrivate;
 
+typedef struct _EggListBoxRow EggListBoxRow;
+typedef struct _EggListBoxRowClass EggListBoxRowClass;
+typedef struct _EggListBoxRowPrivate EggListBoxRowPrivate;
+
 struct _EggListBox
 {
   GtkContainer parent_instance;
@@ -29,10 +33,10 @@ struct _EggListBoxClass
 {
   GtkContainerClass parent_class;
 
-  void (*child_selected) (EggListBox* self, GtkWidget* child);
-  void (*child_activated) (EggListBox* self, GtkWidget* child);
-  void (*activate_cursor_child) (EggListBox* self);
-  void (*toggle_cursor_child) (EggListBox* self);
+  void (*row_selected) (EggListBox* self, EggListBoxRow* row);
+  void (*row_activated) (EggListBox* self, EggListBoxRow* row);
+  void (*activate_cursor_row) (EggListBox* self);
+  void (*toggle_cursor_row) (EggListBox* self);
   void (*move_cursor) (EggListBox* self, GtkMovementStep step, gint count);
   void (*refilter) (EggListBox* self);
 
@@ -52,10 +56,6 @@ struct _EggListBoxClass
 #define EGG_IS_LIST_BOX_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_LIST_BOX_ROW))
 #define EGG_LIST_BOX_ROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_LIST_BOX_ROW, 
EggListBoxRowClass))
 
-typedef struct _EggListBoxRow EggListBoxRow;
-typedef struct _EggListBoxRowClass EggListBoxRowClass;
-typedef struct _EggListBoxRowPrivate EggListBoxRowPrivate;
-
 struct _EggListBoxRow
 {
   GtkBin parent_instance;
@@ -76,49 +76,54 @@ struct _EggListBoxRowClass
   void (*_egg_reserved6) (void);
 };
 
-typedef gboolean (*EggListBoxFilterFunc) (GtkWidget* child, void* user_data);
-typedef gint (*EggListBoxSortFunc) (GtkWidget* child1, GtkWidget* child2, void* user_data);
-typedef void (*EggListBoxUpdateSeparatorFunc) (GtkWidget** separator, GtkWidget* child, GtkWidget* before, 
void* user_data);
+typedef gboolean (*EggListBoxFilterFunc) (EggListBoxRow* row, void* user_data);
+typedef gint (*EggListBoxSortFunc) (EggListBoxRow* row1, EggListBoxRow* row2, void* user_data);
+typedef void (*EggListBoxUpdateSeparatorFunc) (EggListBoxRow* row, EggListBoxRow* before, void* user_data);
 
 GType egg_list_box_row_get_type (void) G_GNUC_CONST;
 GtkWidget* egg_list_box_row_new  (void);
-
+GtkWidget* egg_list_box_row_get_separator  (EggListBoxRow *row);
+void egg_list_box_row_set_separator  (EggListBoxRow *row,
+                                      GtkWidget *separator);
 
 GType egg_list_box_get_type (void) G_GNUC_CONST;
-GtkWidget*  egg_list_box_get_selected_child           (EggListBox                    *self);
-GtkWidget*  egg_list_box_get_child_at_y               (EggListBox                    *self,
-                                                      gint                           y);
-void        egg_list_box_select_child                 (EggListBox                    *self,
-                                                      GtkWidget                     *child);
-void        egg_list_box_set_adjustment               (EggListBox                    *self,
-                                                      GtkAdjustment                 *adjustment);
-void        egg_list_box_add_to_scrolled              (EggListBox                    *self,
-                                                      GtkScrolledWindow             *scrolled);
-void        egg_list_box_set_selection_mode           (EggListBox                    *self,
-                                                      GtkSelectionMode               mode);
-void        egg_list_box_set_filter_func              (EggListBox                    *self,
-                                                      EggListBoxFilterFunc           f,
-                                                      void                          *f_target,
-                                                      GDestroyNotify                 
f_target_destroy_notify);
-void        egg_list_box_set_separator_funcs          (EggListBox                    *self,
-                                                      EggListBoxUpdateSeparatorFunc  update_separator,
-                                                      void                          *update_separator_target,
-                                                      GDestroyNotify                 
update_separator_target_destroy_notify);
-void        egg_list_box_refilter                     (EggListBox                    *self);
-void        egg_list_box_resort                       (EggListBox                    *self);
-void        egg_list_box_reseparate                   (EggListBox                    *self);
-void        egg_list_box_set_sort_func                (EggListBox                    *self,
-                                                      EggListBoxSortFunc             f,
-                                                      void                          *f_target,
-                                                      GDestroyNotify                 
f_target_destroy_notify);
-void        egg_list_box_child_changed                (EggListBox                    *self,
-                                                      GtkWidget                     *widget);
-void        egg_list_box_set_activate_on_single_click (EggListBox                    *self,
-                                                      gboolean                       single);
-void        egg_list_box_drag_unhighlight_widget      (EggListBox                    *self);
-void        egg_list_box_drag_highlight_widget        (EggListBox                    *self,
-                                                      GtkWidget                     *widget);
-GtkWidget*  egg_list_box_new                          (void);
+EggListBoxRow* egg_list_box_get_selected_row             (EggListBox                    *list_box);
+EggListBoxRow* egg_list_box_get_row_at_index             (EggListBox                    *list_box,
+                                                          int                           index);
+EggListBoxRow* egg_list_box_get_row_at_y                 (EggListBox                    *list_box,
+                                                          gint                           y);
+void           egg_list_box_select_row                   (EggListBox                    *list_box,
+                                                          EggListBoxRow                 *row);
+void           egg_list_box_set_adjustment               (EggListBox                    *list_box,
+                                                          GtkAdjustment                 *adjustment);
+void           egg_list_box_add_to_scrolled              (EggListBox                    *list_box,
+                                                          GtkScrolledWindow             *scrolled);
+void           egg_list_box_set_selection_mode           (EggListBox                    *list_box,
+                                                          GtkSelectionMode               mode);
+void           egg_list_box_set_filter_func              (EggListBox                    *list_box,
+                                                          EggListBoxFilterFunc           filter_func,
+                                                          gpointer                       user_data,
+                                                          GDestroyNotify                 destroy);
+void           egg_list_box_set_separator_funcs          (EggListBox                    *list_box,
+                                                          EggListBoxUpdateSeparatorFunc  update_separator,
+                                                          gpointer                       user_data,
+                                                          GDestroyNotify                 destroy);
+void           egg_list_box_refilter                     (EggListBox                    *list_box);
+void           egg_list_box_resort                       (EggListBox                    *list_box);
+void           egg_list_box_reseparate                   (EggListBox                    *list_box);
+void           egg_list_box_set_sort_func                (EggListBox                    *list_box,
+                                                          EggListBoxSortFunc             sort_func,
+                                                          gpointer                       user_data,
+                                                          GDestroyNotify                 destroy);
+void           egg_list_box_row_changed                  (EggListBox                    *list_box,
+                                                          EggListBoxRow                 *row);
+void           egg_list_box_set_activate_on_single_click (EggListBox                    *list_box,
+                                                          gboolean                       single);
+void           egg_list_box_drag_unhighlight_widget      (EggListBox                    *list_box);
+void           egg_list_box_drag_highlight_widget        (EggListBox                    *list_box,
+                                                          GtkWidget                     *widget);
+GtkWidget*     egg_list_box_new                          (void);
+
 
 G_END_DECLS
 
diff --git a/egglistbox.vapi b/egglistbox.vapi
index 8fe65cb..240ab40 100644
--- a/egglistbox.vapi
+++ b/egglistbox.vapi
@@ -1,55 +1,111 @@
+/* egglistbox.vapi generated by vapigen, do not modify. */
+
+[CCode (cprefix = "Egg", gir_namespace = "Egg", gir_version = "1.0", lower_case_cprefix = "egg_")]
 namespace Egg {
-       [CCode (cheader_filename = "egg-list-box.h")]
-       public class ListBox : Gtk.Container {
-               public delegate bool FilterFunc (Gtk.Widget child);
-               public delegate void UpdateSeparatorFunc (ref Gtk.Widget? separator, Gtk.Widget child, 
Gtk.Widget? before);
+       [CCode (cheader_filename = "egg-list-box.h", type_id = "egg_flow_box_get_type ()")]
+       public class FlowBox : Gtk.Container, Atk.Implementor, Gtk.Buildable, Gtk.Orientable {
+               [CCode (has_construct_function = false, type = "GtkWidget*")]
+               public FlowBox ();
+               public bool get_activate_on_single_click ();
+               public uint get_column_spacing ();
+               public Gtk.Align get_halign_policy ();
+               public bool get_homogeneous ();
+               public uint get_max_children_per_line ();
+               public uint get_min_children_per_line ();
+               public uint get_row_spacing ();
+               public GLib.List<weak Gtk.Widget> get_selected_children ();
+               public Gtk.SelectionMode get_selection_mode ();
+               public Gtk.Align get_valign_policy ();
+               public bool is_child_selected (Gtk.Widget child);
+               public void select_child (Gtk.Widget child);
+               public void selected_foreach (Egg.FlowBoxForeachFunc func);
+               public void set_activate_on_single_click (bool single);
+               public void set_adjustment (Gtk.Adjustment adjustment);
+               public void set_column_spacing (uint spacing);
+               public void set_halign_policy (Gtk.Align align);
+               public void set_homogeneous (bool homogeneous);
+               public void set_max_children_per_line (uint n_children);
+               public void set_min_children_per_line (uint n_children);
+               public void set_row_spacing (uint spacing);
+               public void set_selection_mode (Gtk.SelectionMode mode);
+               public void set_valign_policy (Gtk.Align align);
+               public void unselect_child (Gtk.Widget child);
+               public bool activate_on_single_click { get; set; }
+               public Gtk.Align halign_policy { get; set; }
+               public bool homogeneous { get; set; }
+               [NoAccessorMethod]
+               public uint horizontal_spacing { get; set; }
+               public uint max_children_per_line { get; set; }
+               public uint min_children_per_line { get; set; }
+               public Gtk.SelectionMode selection_mode { get; set; }
+               public Gtk.Align valign_policy { get; set; }
+               [NoAccessorMethod]
+               public uint vertical_spacing { get; set; }
+               public virtual signal void activate_cursor_child ();
+               public virtual signal void child_activated (Gtk.Widget child);
+               public virtual signal void move_cursor (Gtk.MovementStep step, int count);
+               [HasEmitter]
+               public virtual signal void select_all ();
+               public virtual signal void selected_children_changed ();
+               public virtual signal void toggle_cursor_child ();
+               [HasEmitter]
+               public virtual signal void unselect_all ();
+       }
+       [CCode (cheader_filename = "egg-list-box.h", type_id = "egg_flow_box_accessible_get_type ()")]
+       public class FlowBoxAccessible : Gtk.Accessible, Atk.Component, Atk.Selection {
                [CCode (has_construct_function = false)]
+               protected FlowBoxAccessible ();
+       }
+       [CCode (cheader_filename = "egg-list-box.h", type_id = "egg_list_box_get_type ()")]
+       public class ListBox : Gtk.Container, Atk.Implementor, Gtk.Buildable {
+               [CCode (has_construct_function = false, type = "GtkWidget*")]
                public ListBox ();
-               public override void add (Gtk.Widget widget);
                public void add_to_scrolled (Gtk.ScrolledWindow scrolled);
-               public override bool button_press_event (Gdk.EventButton event);
-               public override bool button_release_event (Gdk.EventButton event);
-               public void child_changed (Gtk.Widget widget);
-               public override GLib.Type child_type ();
-               public override void compute_expand_internal (out bool hexpand, out bool vexpand);
                public void drag_highlight_widget (Gtk.Widget widget);
-               public override void drag_leave (Gdk.DragContext context, uint time_);
-               public override bool drag_motion (Gdk.DragContext context, int x, int y, uint time_);
                public void drag_unhighlight_widget ();
-               public override bool draw (Cairo.Context cr);
-               public override bool enter_notify_event (Gdk.EventCrossing event);
-               public override bool focus (Gtk.DirectionType direction);
-               public override void forall_internal (bool include_internals, Gtk.Callback callback);
-               public unowned Gtk.Widget? get_child_at_y (int y);
-               public override void get_preferred_height (out int minimum_height, out int natural_height);
-               public override void get_preferred_height_for_width (int width, out int minimum_height, out 
int natural_height);
-               public override void get_preferred_width (out int minimum_width, out int natural_width);
-               public override void get_preferred_width_for_height (int height, out int minimum_width, out 
int natural_width);
-               public override Gtk.SizeRequestMode get_request_mode ();
-               public unowned Gtk.Widget? get_selected_child ();
-               public override bool leave_notify_event (Gdk.EventCrossing event);
-               public override bool motion_notify_event (Gdk.EventMotion event);
-               public override void realize ();
-               public void refilter ();
-               public override void remove (Gtk.Widget widget);
+               public unowned Egg.ListBoxRow get_row_at_index (int index);
+               public unowned Egg.ListBoxRow get_row_at_y (int y);
+               public unowned Egg.ListBoxRow get_selected_row ();
                public void reseparate ();
                public void resort ();
-               public void select_child (Gtk.Widget? child);
+               public void row_changed (Egg.ListBoxRow row);
+               public void select_row (Egg.ListBoxRow? row);
                public void set_activate_on_single_click (bool single);
-               public void set_adjustment (Gtk.Adjustment? adjustment);
-               public void set_filter_func (owned Egg.ListBox.FilterFunc? f);
+               public void set_adjustment (Gtk.Adjustment adjustment);
+               public void set_filter_func (owned Egg.ListBoxFilterFunc? filter_func);
                public void set_selection_mode (Gtk.SelectionMode mode);
-               public void set_separator_funcs (owned Egg.ListBox.UpdateSeparatorFunc? update_separator);
-               public void set_sort_func (owned GLib.CompareDataFunc<Gtk.Widget>? f);
-               public override void show ();
-               public override void size_allocate (Gtk.Allocation allocation);
-               [Signal (action = true)]
-               public virtual signal void activate_cursor_child ();
-               public virtual signal void child_activated (Gtk.Widget? child);
-               public virtual signal void child_selected (Gtk.Widget? child);
-               [Signal (action = true)]
+               public void set_separator_funcs (owned Egg.ListBoxUpdateSeparatorFunc? update_separator);
+               public void set_sort_func (owned Egg.ListBoxSortFunc? sort_func);
+               [NoAccessorMethod]
+               public bool activate_on_single_click { get; set; }
+               [NoAccessorMethod]
+               public Gtk.SelectionMode selection_mode { get; set; }
+               public virtual signal void activate_cursor_row ();
                public virtual signal void move_cursor (Gtk.MovementStep step, int count);
-               [Signal (action = true)]
-               public virtual signal void toggle_cursor_child ();
+               [HasEmitter]
+               public virtual signal void refilter ();
+               public virtual signal void row_activated (Gtk.Widget row);
+               public virtual signal void row_selected (Gtk.Widget row);
+               public virtual signal void toggle_cursor_row ();
+       }
+       [CCode (cheader_filename = "egg-list-box.h", type_id = "egg_list_box_accessible_get_type ()")]
+       public class ListBoxAccessible : Gtk.Accessible, Atk.Component, Atk.Selection {
+               [CCode (has_construct_function = false)]
+               protected ListBoxAccessible ();
+       }
+       [CCode (cheader_filename = "egg-list-box.h", type_id = "egg_list_box_row_get_type ()")]
+       public class ListBoxRow : Gtk.Bin, Atk.Implementor, Gtk.Buildable {
+               [CCode (has_construct_function = false, type = "GtkWidget*")]
+               public ListBoxRow ();
+               public unowned Gtk.Widget get_separator ();
+               public void set_separator (Gtk.Widget? separator);
        }
+       [CCode (cheader_filename = "egg-list-box.h", has_target = false)]
+       public delegate void FlowBoxForeachFunc (Egg.FlowBox flow_box, Gtk.Widget child, void* data);
+       [CCode (cheader_filename = "egg-list-box.h", instance_pos = 1.9)]
+       public delegate bool ListBoxFilterFunc (Egg.ListBoxRow row);
+       [CCode (cheader_filename = "egg-list-box.h", instance_pos = 2.9)]
+       public delegate int ListBoxSortFunc (Egg.ListBoxRow row1, Egg.ListBoxRow row2);
+       [CCode (cheader_filename = "egg-list-box.h", instance_pos = 2.9)]
+       public delegate void ListBoxUpdateSeparatorFunc (Egg.ListBoxRow row, Egg.ListBoxRow before);
 }
diff --git a/test-focus.c b/test-focus.c
index a1c0c3d..b3c0075 100644
--- a/test-focus.c
+++ b/test-focus.c
@@ -71,15 +71,15 @@ new_image (const gchar *icon_name,
 }
 
 static void
-add_row (EggListBox *view)
+add_row (GtkWidget *view)
 {
   GtkWidget *main_box, *box, *first_line_box;
   GtkStyleContext *context;
   GtkWidget *avatar;
   GtkWidget *first_line_alig;
-  //GtkWidget *alias;
+  GtkWidget *alias;
   GtkWidget *phone_icon;
-  //GtkWidget *presence_msg;
+  GtkWidget *presence_msg;
   GtkWidget *presence_icon;
 
   main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
@@ -98,14 +98,13 @@ add_row (EggListBox *view)
   first_line_alig = gtk_alignment_new (0, 0.5, 1, 1);
   first_line_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
-/*
   alias = gtk_label_new ("My Cool Alias");
   gtk_label_set_ellipsize (GTK_LABEL (alias), PANGO_ELLIPSIZE_END);
   gtk_box_pack_start (GTK_BOX (first_line_box), alias,
       FALSE, FALSE, 0);
   gtk_misc_set_alignment (GTK_MISC (alias), 0, 0.5);
   gtk_widget_show (alias);
-*/
+
   phone_icon = new_image ("phone-symbolic", 24);
   gtk_misc_set_alignment (GTK_MISC (phone_icon), 0, 0.5);
   gtk_box_pack_start (GTK_BOX (first_line_box), phone_icon,
@@ -123,7 +122,7 @@ add_row (EggListBox *view)
   gtk_widget_show (box);
 
   /* Presence */
-/*
+
   presence_msg = gtk_label_new ("My Cool Presence Message");
   gtk_label_set_ellipsize (GTK_LABEL (presence_msg),
       PANGO_ELLIPSIZE_END);
@@ -132,7 +131,7 @@ add_row (EggListBox *view)
 
   context = gtk_widget_get_style_context (presence_msg);
   gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
-*/
+
   /* Presence icon */
   presence_icon = new_image ("user-available", 16);
 
@@ -150,7 +149,7 @@ main (gint argc,
 {
   GtkWidget *window;
   GtkWidget *sw;
-  EggListBox *view;
+  GtkWidget *view;
   guint i;
 
   gtk_init (&argc, &argv);
@@ -161,7 +160,7 @@ main (gint argc,
   gtk_widget_show (sw);
 
   view = egg_list_box_new ();
-  egg_list_box_add_to_scrolled (view, GTK_SCROLLED_WINDOW (sw));
+  egg_list_box_add_to_scrolled (EGG_LIST_BOX (view), GTK_SCROLLED_WINDOW (sw));
   gtk_widget_show (GTK_WIDGET (view));
 
   for (i = 0; i < 1000; i++)
diff --git a/test-list.vala b/test-list.vala
index e18d258..42b2997 100644
--- a/test-list.vala
+++ b/test-list.vala
@@ -19,13 +19,28 @@
 using Gtk;
 using Egg;
 
-public void update_separator (ref Widget? separator,
-                             Widget widget,
-                             Widget? before)
+public class Row : Egg.ListBoxRow {
+  public Label? label;
+  public int sort_id;
+
+  public Row (string? text, int sort_id) {
+    if (text != null) {
+      label = new Label(text);
+      this.add (label);
+      label.show ();
+    }
+    this.sort_id = sort_id;
+  }
+}
+
+public void update_separator (Egg.ListBoxRow list_row,
+                             Egg.ListBoxRow? before)
 {
+  Row row = list_row as Row;
+
   if (before == null ||
-      (widget is Label && (widget as Label).get_text () == "blah3")) {
-    if (separator == null) {
+      (row.label != null && row.label.get_text () == "blah3")) {
+    if (row.get_separator() == null) {
       var hbox = new Box(Orientation.HORIZONTAL, 0);
       var l = new Label ("Separator");
       hbox.add (l);
@@ -33,35 +48,37 @@ public void update_separator (ref Widget? separator,
       hbox.add (b);
       l.show ();
       b.show ();
-      separator = hbox;
+      row.set_separator (hbox);
     }
 
-    var hbox = separator as Box;
-    var id = widget.get_data<int>("sort_id");
+    var hbox = row.get_separator() as Box;
     var l = hbox.get_children ().data as Label;
-    l.set_text ("Separator %d".printf (id));
+    l.set_text ("Separator %d".printf (row.sort_id));
   } else {
-    separator = null;
+    row.set_separator (null);
   }
-  print ("update separator => %p\n", separator);
+  print ("update separator => %p\n", row.get_separator());
 }
 
 public static int
-compare_label (Widget a, Widget b) {
-  var aa = a.get_data<int>("sort_id");
-  var bb = b.get_data<int>("sort_id");
-  return bb - aa;
+compare_label (Egg.ListBoxRow a, Egg.ListBoxRow b) {
+  return (a as Row).sort_id - (b as Row).sort_id;
 }
 
 public static int
-compare_label_reverse (Widget a, Widget b) {
-       return - compare_label (a, b);
+compare_label_reverse (Egg.ListBoxRow a, Egg.ListBoxRow b) {
+  return - compare_label (a, b);
 }
 
 public static bool
-filter (Widget widget) {
-       var text = (widget as Label).get_text ();
-       return strcmp (text, "blah3") != 0;
+filter (Egg.ListBoxRow _row) {
+  var row = _row as Row;
+
+  if (row.label != null) {
+    var text = row.label.get_text ();
+    return strcmp (text, "blah3") != 0;
+  }
+  return true;
 }
 
 public static int
@@ -76,31 +93,29 @@ main (string[] args) {
   var list = new ListBox();
   hbox.add (list);
 
-  list.child_activated.connect ( (child) => {
+  list.row_activated.connect ( (child) => {
       print ("activated %p\n", child);
     });
 
-  list.child_selected.connect ( (child) => {
+  list.row_selected.connect ( (child) => {
       print ("selected %p\n", child);
     });
 
-  var l = new Label ("blah4");
-  l.set_data ("sort_id", 4);
-  list.add (l);
-  var l3 = new Label ("blah3");
-  l3.set_data ("sort_id", 3);
-  list.add (l3);
-  l = new Label ("blah1");
-  l.set_data ("sort_id", 1);
-  list.add (l);
-  l = new Label ("blah2");
-  l.set_data ("sort_id", 2);
-  list.add (l);
+  var row = new Row("blah4", 4);
+  list.add (row);
+  row = new Row("blah3", 3);
+  list.add (row);
+  var row3 = row;
+  row = new Row("blah1", 1);
+  list.add (row);
+  row = new Row("blah2", 2);
+  list.add (row);
+
 
+  row = new Row(null, 0);
   var row_vbox = new Box (Orientation.VERTICAL, 0);
   var row_hbox = new Box (Orientation.HORIZONTAL, 0);
-  row_vbox.set_data ("sort_id", 3);
-  l = new Label ("da box for da man");
+  var l = new Label ("da box for da man");
   row_hbox.add (l);
   var check = new CheckButton ();
   row_hbox.add (check);
@@ -109,12 +124,15 @@ main (string[] args) {
   row_vbox.add (row_hbox);
   check = new CheckButton ();
   row_vbox.add (check);
-  list.add (row_vbox);
+  row.add (row_vbox);
+  list.add (row);
 
+  row = new Row(null, 0);
   button = new Button.with_label ("focusable row");
   button.set_hexpand (false);
   button.set_halign (Align.START);
-  list.add (button);
+  row.add(button);
+  list.add (row);
 
   var vbox = new Box(Orientation.VERTICAL, 0);
   hbox.add (vbox);
@@ -122,27 +140,27 @@ main (string[] args) {
   var b = new Button.with_label ("sort");
   vbox.add (b);
   b.clicked.connect ( () => {
-                 list.set_sort_func (compare_label);
-         });
+      list.set_sort_func (compare_label);
+    });
 
   b = new Button.with_label ("reverse");
   vbox.add (b);
   b.clicked.connect ( () => {
-                 list.set_sort_func (compare_label_reverse);
-         });
+      list.set_sort_func (compare_label_reverse);
+    });
 
   b = new Button.with_label ("change");
   vbox.add (b);
   b.clicked.connect ( () => {
-                 if (l3.get_text () == "blah3") {
-                         l3.set_text ("blah5");
-                         l3.set_data ("sort_id", 5);
-                 } else {
-                         l3.set_text ("blah3");
-                         l3.set_data ("sort_id", 3);
-                 }
-                 list.child_changed (l3);
-         });
+      if (row3.label.get_text () == "blah3") {
+       row3.label.set_text ("blah5");
+       row3.sort_id = 5;
+      } else {
+       row3.label.set_text ("blah3");
+       row3.sort_id = 3;
+      }
+      list.row_changed (row3);
+    });
 
   b = new Button.with_label ("filter");
   vbox.add (b);
@@ -153,20 +171,18 @@ main (string[] args) {
   b = new Button.with_label ("unfilter");
   vbox.add (b);
   b.clicked.connect ( () => {
-                 list.set_filter_func (null);
-         });
+      list.set_filter_func (null);
+    });
 
   int new_button_nr = 1;
   b = new Button.with_label ("add");
   vbox.add (b);
   b.clicked.connect ( () => {
-                 var ll = new Label ("blah2 new %d".printf (new_button_nr));
-                 l.set_data ("sort_id", new_button_nr);
-                 new_button_nr++;
-
-                 list.add (ll);
-                 l.show ();
-         });
+      var new_row = new Row ("blah2 new %d".printf (new_button_nr), new_button_nr);
+      new_row.show_all ();
+      list.add (new_row);
+      new_button_nr++;
+    });
 
   b = new Button.with_label ("separate");
   vbox.add (b);
diff --git a/test-scrolled.vala b/test-scrolled.vala
index 1044ed2..4f3b96d 100644
--- a/test-scrolled.vala
+++ b/test-scrolled.vala
@@ -19,7 +19,7 @@
 using Gtk;
 using Egg;
 
-class Row : Grid {
+class Row : Egg.ListBoxRow {
   public int32 value;
   public Row () {
        value = Random.int_range (0, 10000);
@@ -27,17 +27,16 @@ class Row : Grid {
        this.add (l);
        l.show ();
   }
-
-       
 }
+
 public static int
-compare (Widget a, Widget b) {
+compare (Egg.ListBoxRow a, Egg.ListBoxRow b) {
   return (int32)(b as Row).value - (int32)(a as Row).value;
 }
 
 public static bool
-filter (Widget widget) {
-  return (widget as Row).value % 2 == 0;
+filter (Egg.ListBoxRow row) {
+  return (row as Row).value % 2 == 0;
 }
 
 public static int
@@ -51,7 +50,7 @@ main (string[] args) {
 
   if (num_rows == 0)
        num_rows = 1000;
-  
+
   var w = new Window ();
   var hbox = new Box(Orientation.HORIZONTAL, 0);
   w.add (hbox);
@@ -65,7 +64,7 @@ main (string[] args) {
 
   var label = new Label ("This is \na LABEL\nwith rows");
   scrolled_box.add (label);
-  
+
   var list = new ListBox();
   scrolled_box.add (list);
   list.set_adjustment (scrolled.get_vadjustment ());
diff --git a/test-sel.c b/test-sel.c
index ee2577b..1b4de34 100644
--- a/test-sel.c
+++ b/test-sel.c
@@ -13,7 +13,7 @@ int main() {
     gtk_container_add (GTK_CONTAINER (box), gtk_label_new ("one"));
     s = gtk_label_new ("two");
     gtk_container_add (GTK_CONTAINER (box), s);
-    egg_list_box_select_child (EGG_LIST_BOX (box), s);
+    egg_list_box_select_row (EGG_LIST_BOX (box), EGG_LIST_BOX_ROW (gtk_widget_get_parent (s)));
     gtk_container_add (GTK_CONTAINER (box), gtk_label_new ("three"));
     gtk_container_add (GTK_CONTAINER (window), box);
     gtk_widget_show_all (window);



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