[goocanvas/new-api: 2/7] removed GooCanvasItem interface and used an abstract base class instead



commit 723fa5398c3f8fbf99b1c690393178e0eaeab0a0
Author: Damon Chaplin <damon gnome org>
Date:   Thu Jun 24 14:39:43 2010 +0100

    removed GooCanvasItem interface and used an abstract base class instead

 src/goocanvas.c           |    4 +-
 src/goocanvasgroup.c      |   42 +--
 src/goocanvasitem.c       | 1025 ++++++++++++++++++++-------------------------
 src/goocanvasitem.h       |   34 +-
 src/goocanvasitemsimple.c |  588 ++++++++++++++-------------
 src/goocanvasitemsimple.h |    4 +-
 src/goocanvastable.c      |   79 ++---
 src/goocanvastext.c       |   18 +-
 src/goocanvasutils.c      |    2 +-
 src/goocanvaswidget.c     |   30 +-
 10 files changed, 852 insertions(+), 974 deletions(-)
---
diff --git a/src/goocanvas.c b/src/goocanvas.c
index 4b7659b..bc4b78c 100644
--- a/src/goocanvas.c
+++ b/src/goocanvas.c
@@ -3681,6 +3681,7 @@ goo_canvas_focus_recurse (GooCanvas          *canvas,
 			  GooCanvasItem      *item,
 			  GooCanvasFocusData *data)
 {
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   GooCanvasItem *child;
   gboolean can_focus = FALSE, is_best;
   gint n_children, i;
@@ -3700,7 +3701,8 @@ goo_canvas_focus_recurse (GooCanvas          *canvas,
 	}
       else
 	{
-	  g_object_get (item, "can-focus", &can_focus, NULL);
+	  if (item_class->get_can_focus)
+	    can_focus = item_class->get_can_focus (item);
 	}
 
       /* If the item can take the focus itself, and it isn't the current
diff --git a/src/goocanvasgroup.c b/src/goocanvasgroup.c
index 1c187b1..66a47fe 100644
--- a/src/goocanvasgroup.c
+++ b/src/goocanvasgroup.c
@@ -52,12 +52,8 @@ enum {
   PROP_HEIGHT
 };
 
-static void canvas_item_interface_init    (GooCanvasItemIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (GooCanvasGroup, goo_canvas_group,
-			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
-			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						canvas_item_interface_init))
+G_DEFINE_TYPE (GooCanvasGroup, goo_canvas_group, GOO_TYPE_CANVAS_ITEM_SIMPLE)
 
 
 static void
@@ -590,35 +586,31 @@ goo_canvas_group_paint (GooCanvasItem         *item,
 
 
 static void
-canvas_item_interface_init (GooCanvasItemIface *iface)
-{
-  iface->set_canvas     = goo_canvas_group_set_canvas;
-  iface->get_n_children = goo_canvas_group_get_n_children;
-  iface->get_child      = goo_canvas_group_get_child;
-  iface->request_update = goo_canvas_group_request_update;
-
-  iface->add_child      = goo_canvas_group_add_child;
-  iface->move_child     = goo_canvas_group_move_child;
-  iface->remove_child   = goo_canvas_group_remove_child;
-
-  iface->get_items_at	= goo_canvas_group_get_items_at;
-  iface->update         = goo_canvas_group_update;
-  iface->paint          = goo_canvas_group_paint;
-
-  iface->set_is_static  = goo_canvas_group_set_is_static;
-}
-
-
-static void
 goo_canvas_group_class_init (GooCanvasGroupClass *klass)
 {
   GObjectClass *gobject_class = (GObjectClass*) klass;
+  GooCanvasItemClass *item_class = (GooCanvasItemClass*) klass;
 
   gobject_class->dispose  = goo_canvas_group_dispose;
   gobject_class->finalize = goo_canvas_group_finalize;
   gobject_class->get_property = goo_canvas_group_get_property;
   gobject_class->set_property = goo_canvas_group_set_property;
 
+  item_class->set_canvas     = goo_canvas_group_set_canvas;
+  item_class->get_n_children = goo_canvas_group_get_n_children;
+  item_class->get_child      = goo_canvas_group_get_child;
+  item_class->request_update = goo_canvas_group_request_update;
+
+  item_class->add_child      = goo_canvas_group_add_child;
+  item_class->move_child     = goo_canvas_group_move_child;
+  item_class->remove_child   = goo_canvas_group_remove_child;
+
+  item_class->get_items_at   = goo_canvas_group_get_items_at;
+  item_class->update         = goo_canvas_group_update;
+  item_class->paint          = goo_canvas_group_paint;
+
+  item_class->set_is_static  = goo_canvas_group_set_is_static;
+
   /* Register our accessible factory, but only if accessibility is enabled. */
   if (!ATK_IS_NO_OP_OBJECT_FACTORY (atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET)))
     {
diff --git a/src/goocanvasitem.c b/src/goocanvasitem.c
index 243310f..805f11d 100644
--- a/src/goocanvasitem.c
+++ b/src/goocanvasitem.c
@@ -1,16 +1,16 @@
 /*
- * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-2010 Damon Chaplin.
  * Released under the GNU LGPL license. See COPYING for details.
  *
- * goocanvasitem.c - interface for canvas items & groups.
+ * goocanvasitem.c - base class for canvas items.
  */
 
 /**
  * SECTION:goocanvasitem
  * @Title: GooCanvasItem
- * @Short_Description: the interface for canvas items.
+ * @Short_Description: the base class for canvas items.
  *
- * #GooCanvasItem defines the interface that canvas items must implement,
+ * #GooCanvasItem defines the methods that canvas items must implement,
  * and contains methods for operating on canvas items.
  */
 #include <config.h>
@@ -56,33 +56,10 @@ enum {
 
 static guint canvas_item_signals[LAST_SIGNAL] = { 0 };
 
-static void goo_canvas_item_base_init (gpointer g_class);
 extern void _goo_canvas_style_init (void);
 
 
-GType
-goo_canvas_item_get_type (void)
-{
-  static GType canvas_item_type = 0;
-
-  if (!canvas_item_type)
-    {
-      static const GTypeInfo canvas_item_info =
-      {
-        sizeof (GooCanvasItemIface), /* class_size */
-	goo_canvas_item_base_init,   /* base_init */
-	NULL,			     /* base_finalize */
-      };
-
-      canvas_item_type = g_type_register_static (G_TYPE_INTERFACE,
-						 "GooCanvasItem",
-						 &canvas_item_info, 0);
-
-      g_type_interface_add_prerequisite (canvas_item_type, G_TYPE_OBJECT);
-    }
-
-  return canvas_item_type;
-}
+G_DEFINE_TYPE (GooCanvasItem, goo_canvas_item, G_TYPE_OBJECT)
 
 
 static void
@@ -99,434 +76,368 @@ child_property_notify_dispatcher (GObject     *object,
 
 
 static void
-goo_canvas_item_base_init (gpointer g_iface)
+goo_canvas_item_class_init (GooCanvasItemClass *klass)
 {
   static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
-  static gboolean initialized = FALSE;
-  
-  if (!initialized)
-    {
-      GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
-
-      _goo_canvas_item_child_property_pool = g_param_spec_pool_new (TRUE);
-
-      cpn_context.quark_notify_queue = g_quark_from_static_string ("GooCanvasItem-child-property-notify-queue");
-      cpn_context.dispatcher = child_property_notify_dispatcher;
-      _goo_canvas_item_child_property_notify_context = &cpn_context;
-
-      /* Mouse events. */
-
-      /**
-       * GooCanvasItem::enter-notify-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data. The x & y fields contain the mouse position
-       *  in the item's coordinate space. The x_root & y_root fields contain
-       *  the same coordinates converted to the canvas coordinate space.
-       *
-       * Emitted when the mouse enters an item.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[ENTER_NOTIFY_EVENT] =
-	g_signal_new ("enter_notify_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       enter_notify_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::leave-notify-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data. The x & y fields contain the mouse position
-       *  in the item's coordinate space. The x_root & y_root fields contain
-       *  the same coordinates converted to the canvas coordinate space.
-       *
-       * Emitted when the mouse leaves an item.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[LEAVE_NOTIFY_EVENT] =
-	g_signal_new ("leave_notify_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       leave_notify_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::motion-notify-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data. The x & y fields contain the mouse position
-       *  in the item's coordinate space. The x_root & y_root fields contain
-       *  the same coordinates converted to the canvas coordinate space.
-       *
-       * Emitted when the mouse moves within an item.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[MOTION_NOTIFY_EVENT] =
-	g_signal_new ("motion_notify_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       motion_notify_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::button-press-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data. The x & y fields contain the mouse position
-       *  in the item's coordinate space. The x_root & y_root fields contain
-       *  the same coordinates converted to the canvas coordinate space.
-       *
-       * Emitted when a mouse button is pressed in an item.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[BUTTON_PRESS_EVENT] =
-	g_signal_new ("button_press_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       button_press_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::button-release-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data. The x & y fields contain the mouse position
-       *  in the item's coordinate space. The x_root & y_root fields contain
-       *  the same coordinates converted to the canvas coordinate space.
-       *
-       * Emitted when a mouse button is released in an item.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[BUTTON_RELEASE_EVENT] =
-	g_signal_new ("button_release_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       button_release_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-
-      /* Keyboard events. */
-
-      /**
-       * GooCanvasItem::focus-in-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data.
-       *
-       * Emitted when the item receives the keyboard focus.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[FOCUS_IN_EVENT] =
-	g_signal_new ("focus_in_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       focus_in_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::focus-out-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data.
-       *
-       * Emitted when the item loses the keyboard focus.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[FOCUS_OUT_EVENT] =
-	g_signal_new ("focus_out_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       focus_out_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::key-press-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data.
-       *
-       * Emitted when a key is pressed and the item has the keyboard
-       * focus.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[KEY_PRESS_EVENT] =
-	g_signal_new ("key_press_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       key_press_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::key-release-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data.
-       *
-       * Emitted when a key is released and the item has the keyboard
-       * focus.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[KEY_RELEASE_EVENT] =
-	g_signal_new ("key_release_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       key_release_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::query-tooltip:
-       * @item: the item which received the signal.
-       * @x: the x coordinate of the mouse.
-       * @y: the y coordinate of the mouse.
-       * @keyboard_mode: %TRUE if the tooltip was triggered using the keyboard.
-       * @tooltip: a #GtkTooltip.
-       *
-       * Emitted when the mouse has paused over the item for a certain amount
-       * of time, or the tooltip was requested via the keyboard.
-       *
-       * Note that if @keyboard_mode is %TRUE, the values of @x and @y are
-       * undefined and should not be used.
-       *
-       * If the item wants to display a tooltip it should update @tooltip
-       * and return %TRUE.
-       *
-       * Returns: %TRUE if the item has set a tooltip to show.
-       */
-      canvas_item_signals[QUERY_TOOLTIP] =
-	g_signal_new ("query-tooltip",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface, query_tooltip),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT,
-		      G_TYPE_BOOLEAN, 4,
-		      G_TYPE_DOUBLE,
-		      G_TYPE_DOUBLE,
-		      G_TYPE_BOOLEAN,
-		      GTK_TYPE_TOOLTIP);
-
-      /**
-       * GooCanvasItem::grab-broken-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data.
-       *
-       * Emitted when the item's keyboard or pointer grab was lost
-       * unexpectedly.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[GRAB_BROKEN_EVENT] =
-	g_signal_new ("grab_broken_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       grab_broken_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      /**
-       * GooCanvasItem::child-notify
-       * @item: the item that received the signal.
-       * @pspec: the #GParamSpec of the changed child property.
-       *
-       * Emitted for each child property that has changed.
-       * The signal's detail holds the property name. 
-       */
-      canvas_item_signals[CHILD_NOTIFY] =
-	g_signal_new ("child_notify",
-		      iface_type,
-		      G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
-		      G_STRUCT_OFFSET (GooCanvasItemIface, child_notify),
-		      NULL, NULL,
-		      g_cclosure_marshal_VOID__PARAM,
-		      G_TYPE_NONE, 1,
-		      G_TYPE_PARAM);
-
-      /**
-       * GooCanvasItem::animation-finished
-       * @item: the item that received the signal.
-       * @stopped: if the animation was explicitly stopped.
-       *
-       * Emitted when the item animation has finished.
-       */
-      canvas_item_signals[ANIMATION_FINISHED] =
-	g_signal_new ("animation-finished",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface, animation_finished),
-		      NULL, NULL,
-		      g_cclosure_marshal_VOID__BOOLEAN,
-		      G_TYPE_NONE, 1,
-		      G_TYPE_BOOLEAN);
-
-      /**
-       * GooCanvasItem::scroll-event
-       * @item: the item that received the signal.
-       * @target_item: the target of the event.
-       * @event: the event data. The x & y fields contain the mouse position
-       *  in the item's coordinate space. The x_root & y_root fields contain
-       *  the same coordinates converted to the canvas coordinate space.
-       *
-       * Emitted when a button in the 4 to 7 range is pressed. Wheel mice are
-       * usually configured to generate button press events for buttons 4 and 5
-       * when the wheel is turned in an item.
-       *
-       * Returns: %TRUE to stop the signal emission, or %FALSE to let it
-       *  continue.
-       */
-      canvas_item_signals[SCROLL_EVENT] =
-	g_signal_new ("scroll_event",
-		      iface_type,
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GooCanvasItemIface,
-				       scroll_event),
-		      goo_canvas_boolean_handled_accumulator, NULL,
-		      goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
-		      G_TYPE_BOOLEAN, 2,
-		      GOO_TYPE_CANVAS_ITEM,
-		      GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_object ("parent",
-								_("Parent"),
-								_("The parent item"),
-								GOO_TYPE_CANVAS_ITEM,
-								G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_enum ("visibility",
-							      _("Visibility"),
-							      _("When the canvas item is visible"),
-							      GOO_TYPE_CANVAS_ITEM_VISIBILITY,
-							      GOO_CANVAS_ITEM_VISIBLE,
-							      G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_double ("visibility-threshold",
-								_("Visibility Threshold"),
-								_("The scale threshold at which the item becomes visible"),
-								0.0,
-								G_MAXDOUBLE,
-								0.0,
-								G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_boxed ("transform",
-							       _("Transform"),
-							       _("The transformation matrix of the item"),
-							       GOO_TYPE_CAIRO_MATRIX,
-							       G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_flags ("pointer-events",
-							       _("Pointer Events"),
-							       _("Specifies when the item receives pointer events"),
-							       GOO_TYPE_CANVAS_POINTER_EVENTS,
-							       GOO_CANVAS_EVENTS_VISIBLE_PAINTED,
-							       G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_string ("title",
-								_("Title"),
-								_("A short context-rich description of the item for use by assistive technologies"),
-								NULL,
-								G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_string ("description",
-								_("Description"),
-								_("A description of the item for use by assistive technologies"),
-								NULL,
-								G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_boolean ("can-focus",
-								 _("Can Focus"),
-								 _("If the item can take the keyboard focus"),
-								 FALSE,
-								 G_PARAM_READWRITE));
-
-      g_object_interface_install_property (g_iface,
-					   g_param_spec_string ("tooltip",
-								_("Tooltip"),
-								_("The tooltip to display for the item"),
-								NULL,
-								G_PARAM_READWRITE));
-
-      _goo_canvas_style_init ();
-
-      initialized = TRUE;
-    }
+
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+
+  _goo_canvas_item_child_property_pool = g_param_spec_pool_new (TRUE);
+
+  cpn_context.quark_notify_queue = g_quark_from_static_string ("GooCanvasItem-child-property-notify-queue");
+  cpn_context.dispatcher = child_property_notify_dispatcher;
+  _goo_canvas_item_child_property_notify_context = &cpn_context;
+
+  /* Mouse events. */
+
+  /**
+   * GooCanvasItem::enter-notify-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data. The x & y fields contain the mouse position
+   *  in the item's coordinate space. The x_root & y_root fields contain
+   *  the same coordinates converted to the canvas coordinate space.
+   *
+   * Emitted when the mouse enters an item.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[ENTER_NOTIFY_EVENT] =
+    g_signal_new ("enter_notify_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   enter_notify_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::leave-notify-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data. The x & y fields contain the mouse position
+   *  in the item's coordinate space. The x_root & y_root fields contain
+   *  the same coordinates converted to the canvas coordinate space.
+   *
+   * Emitted when the mouse leaves an item.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[LEAVE_NOTIFY_EVENT] =
+    g_signal_new ("leave_notify_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   leave_notify_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::motion-notify-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data. The x & y fields contain the mouse position
+   *  in the item's coordinate space. The x_root & y_root fields contain
+   *  the same coordinates converted to the canvas coordinate space.
+   *
+   * Emitted when the mouse moves within an item.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[MOTION_NOTIFY_EVENT] =
+    g_signal_new ("motion_notify_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   motion_notify_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::button-press-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data. The x & y fields contain the mouse position
+   *  in the item's coordinate space. The x_root & y_root fields contain
+   *  the same coordinates converted to the canvas coordinate space.
+   *
+   * Emitted when a mouse button is pressed in an item.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[BUTTON_PRESS_EVENT] =
+    g_signal_new ("button_press_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   button_press_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::button-release-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data. The x & y fields contain the mouse position
+   *  in the item's coordinate space. The x_root & y_root fields contain
+   *  the same coordinates converted to the canvas coordinate space.
+   *
+   * Emitted when a mouse button is released in an item.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[BUTTON_RELEASE_EVENT] =
+    g_signal_new ("button_release_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   button_release_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+
+  /* Keyboard events. */
+
+  /**
+   * GooCanvasItem::focus-in-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data.
+   *
+   * Emitted when the item receives the keyboard focus.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[FOCUS_IN_EVENT] =
+    g_signal_new ("focus_in_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   focus_in_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::focus-out-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data.
+   *
+   * Emitted when the item loses the keyboard focus.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[FOCUS_OUT_EVENT] =
+    g_signal_new ("focus_out_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   focus_out_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::key-press-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data.
+   *
+   * Emitted when a key is pressed and the item has the keyboard
+   * focus.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[KEY_PRESS_EVENT] =
+    g_signal_new ("key_press_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   key_press_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::key-release-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data.
+   *
+   * Emitted when a key is released and the item has the keyboard
+   * focus.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[KEY_RELEASE_EVENT] =
+    g_signal_new ("key_release_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   key_release_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::query-tooltip:
+   * @item: the item which received the signal.
+   * @x: the x coordinate of the mouse.
+   * @y: the y coordinate of the mouse.
+   * @keyboard_mode: %TRUE if the tooltip was triggered using the keyboard.
+   * @tooltip: a #GtkTooltip.
+   *
+   * Emitted when the mouse has paused over the item for a certain amount
+   * of time, or the tooltip was requested via the keyboard.
+   *
+   * Note that if @keyboard_mode is %TRUE, the values of @x and @y are
+   * undefined and should not be used.
+   *
+   * If the item wants to display a tooltip it should update @tooltip
+   * and return %TRUE.
+   *
+   * Returns: %TRUE if the item has set a tooltip to show.
+   */
+  canvas_item_signals[QUERY_TOOLTIP] =
+    g_signal_new ("query-tooltip",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass, query_tooltip),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__DOUBLE_DOUBLE_BOOLEAN_OBJECT,
+		  G_TYPE_BOOLEAN, 4,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_DOUBLE,
+		  G_TYPE_BOOLEAN,
+		  GTK_TYPE_TOOLTIP);
+
+  /**
+   * GooCanvasItem::grab-broken-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data.
+   *
+   * Emitted when the item's keyboard or pointer grab was lost
+   * unexpectedly.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[GRAB_BROKEN_EVENT] =
+    g_signal_new ("grab_broken_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   grab_broken_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GooCanvasItem::child-notify
+   * @item: the item that received the signal.
+   * @pspec: the #GParamSpec of the changed child property.
+   *
+   * Emitted for each child property that has changed.
+   * The signal's detail holds the property name. 
+   */
+  canvas_item_signals[CHILD_NOTIFY] =
+    g_signal_new ("child_notify",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
+		  G_STRUCT_OFFSET (GooCanvasItemClass, child_notify),
+		  NULL, NULL,
+		  g_cclosure_marshal_VOID__PARAM,
+		  G_TYPE_NONE, 1,
+		  G_TYPE_PARAM);
+
+  /**
+   * GooCanvasItem::animation-finished
+   * @item: the item that received the signal.
+   * @stopped: if the animation was explicitly stopped.
+   *
+   * Emitted when the item animation has finished.
+   */
+  canvas_item_signals[ANIMATION_FINISHED] =
+    g_signal_new ("animation-finished",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass, animation_finished),
+		  NULL, NULL,
+		  g_cclosure_marshal_VOID__BOOLEAN,
+		  G_TYPE_NONE, 1,
+		  G_TYPE_BOOLEAN);
+
+  /**
+   * GooCanvasItem::scroll-event
+   * @item: the item that received the signal.
+   * @target_item: the target of the event.
+   * @event: the event data. The x & y fields contain the mouse position
+   *  in the item's coordinate space. The x_root & y_root fields contain
+   *  the same coordinates converted to the canvas coordinate space.
+   *
+   * Emitted when a button in the 4 to 7 range is pressed. Wheel mice are
+   * usually configured to generate button press events for buttons 4 and 5
+   * when the wheel is turned in an item.
+   *
+   * Returns: %TRUE to stop the signal emission, or %FALSE to let it
+   *  continue.
+   */
+  canvas_item_signals[SCROLL_EVENT] =
+    g_signal_new ("scroll_event",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GooCanvasItemClass,
+				   scroll_event),
+		  goo_canvas_boolean_handled_accumulator, NULL,
+		  goo_canvas_marshal_BOOLEAN__OBJECT_BOXED,
+		  G_TYPE_BOOLEAN, 2,
+		  GOO_TYPE_CANVAS_ITEM,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  _goo_canvas_style_init ();
+}
+
+
+static void
+goo_canvas_item_init (GooCanvasItem *canvas_item)
+{
+
 }
 
 
@@ -541,15 +452,15 @@ goo_canvas_item_base_init (gpointer g_iface)
 GooCanvas*
 goo_canvas_item_get_canvas (GooCanvasItem *item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->get_canvas)
+  if (item_class->get_canvas)
     {
-      return iface->get_canvas (item);
+      return item_class->get_canvas (item);
     }
   else
     {
-      GooCanvasItem *parent = iface->get_parent (item);
+      GooCanvasItem *parent = item_class->get_parent (item);
 
       if (parent)
 	return goo_canvas_item_get_canvas (parent);
@@ -572,10 +483,10 @@ void
 goo_canvas_item_set_canvas     (GooCanvasItem   *item,
 				GooCanvas       *canvas)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->set_canvas)
-    iface->set_canvas (item, canvas);
+  if (item_class->set_canvas)
+    item_class->set_canvas (item, canvas);
 }
 
 
@@ -593,12 +504,12 @@ goo_canvas_item_add_child      (GooCanvasItem       *item,
 				GooCanvasItem       *child,
 				gint                 position)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  g_return_if_fail (iface->add_child != NULL);
+  g_return_if_fail (item_class->add_child != NULL);
   g_return_if_fail (item != child);
 
-  iface->add_child (item, child, position);
+  item_class->add_child (item, child, position);
 }
 
 
@@ -615,11 +526,11 @@ goo_canvas_item_move_child     (GooCanvasItem       *item,
 				gint                 old_position,
 				gint                 new_position)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  g_return_if_fail (iface->move_child != NULL);
+  g_return_if_fail (item_class->move_child != NULL);
 
-  iface->move_child (item, old_position, new_position);
+  item_class->move_child (item, old_position, new_position);
 }
 
 
@@ -634,11 +545,11 @@ void
 goo_canvas_item_remove_child   (GooCanvasItem       *item,
 				gint                 child_num)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  g_return_if_fail (iface->remove_child != NULL);
+  g_return_if_fail (item_class->remove_child != NULL);
 
-  iface->remove_child (item, child_num);
+  item_class->remove_child (item, child_num);
 }
 
 
@@ -681,9 +592,9 @@ goo_canvas_item_find_child     (GooCanvasItem *item,
 gboolean
 goo_canvas_item_is_container (GooCanvasItem       *item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  return iface->get_n_children ? TRUE : FALSE;
+  return item_class->get_n_children ? TRUE : FALSE;
 }
 
 
@@ -698,9 +609,9 @@ goo_canvas_item_is_container (GooCanvasItem       *item)
 gint
 goo_canvas_item_get_n_children (GooCanvasItem       *item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  return iface->get_n_children ? iface->get_n_children (item) : 0;
+  return item_class->get_n_children ? item_class->get_n_children (item) : 0;
 }
 
 
@@ -718,9 +629,9 @@ GooCanvasItem*
 goo_canvas_item_get_child (GooCanvasItem       *item,
 			   gint                 child_num)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  return iface->get_child ? iface->get_child (item, child_num) : NULL;
+  return item_class->get_child ? item_class->get_child (item, child_num) : NULL;
 }
 
 
@@ -737,7 +648,7 @@ goo_canvas_item_get_parent  (GooCanvasItem *item)
 {
   g_return_val_if_fail (GOO_IS_CANVAS_ITEM (item), NULL);
 
-  return GOO_CANVAS_ITEM_GET_IFACE (item)->get_parent (item);
+  return GOO_CANVAS_ITEM_GET_CLASS (item)->get_parent (item);
 }
 
 
@@ -760,7 +671,7 @@ void
 goo_canvas_item_set_parent (GooCanvasItem *item,
 			    GooCanvasItem *parent)
 {
-  GOO_CANVAS_ITEM_GET_IFACE (item)->set_parent (item, parent);
+  GOO_CANVAS_ITEM_GET_CLASS (item)->set_parent (item, parent);
 }
 
 
@@ -776,10 +687,10 @@ goo_canvas_item_set_parent (GooCanvasItem *item,
 gboolean
 goo_canvas_item_get_is_static	(GooCanvasItem		*item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->get_is_static)
-    return iface->get_is_static (item);
+  if (item_class->get_is_static)
+    return item_class->get_is_static (item);
   return FALSE;
 }
 
@@ -800,10 +711,10 @@ void
 goo_canvas_item_set_is_static	(GooCanvasItem		*item,
 				 gboolean		 is_static)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->set_is_static)
-    iface->set_is_static (item, is_static);
+  if (item_class->set_is_static)
+    item_class->set_is_static (item, is_static);
 }
 
 
@@ -933,9 +844,9 @@ gboolean
 goo_canvas_item_get_transform  (GooCanvasItem   *item,
 				cairo_matrix_t  *transform)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  return iface->get_transform ? iface->get_transform (item, transform) : FALSE;
+  return item_class->get_transform ? item_class->get_transform (item, transform) : FALSE;
 }
 
 
@@ -956,14 +867,14 @@ goo_canvas_item_get_transform_for_child  (GooCanvasItem  *item,
 					  GooCanvasItem  *child,
 					  cairo_matrix_t *transform)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (child && iface->get_transform_for_child)
-    return iface->get_transform_for_child (item, child, transform);
+  if (child && item_class->get_transform_for_child)
+    return item_class->get_transform_for_child (item, child, transform);
 
   /* We fallback to the standard get_transform method. */
-  if (iface->get_transform)
-    return iface->get_transform (item, transform);
+  if (item_class->get_transform)
+    return item_class->get_transform (item, transform);
 
   return FALSE;
 }
@@ -981,7 +892,7 @@ void
 goo_canvas_item_set_transform  (GooCanvasItem        *item,
 				const cairo_matrix_t *transform)
 {
-  GOO_CANVAS_ITEM_GET_IFACE (item)->set_transform (item, transform);
+  GOO_CANVAS_ITEM_GET_CLASS (item)->set_transform (item, transform);
 }
 
 
@@ -1008,13 +919,13 @@ goo_canvas_item_get_simple_transform (GooCanvasItem   *item,
 				      gdouble         *scale,
 				      gdouble         *rotation)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t matrix = { 1, 0, 0, 1, 0, 0 };
   double x1 = 1.0, y1 = 0.0, radians;
   gboolean has_transform = FALSE;
 
-  if (iface->get_transform)
-    has_transform = iface->get_transform (item, &matrix);
+  if (item_class->get_transform)
+    has_transform = item_class->get_transform (item, &matrix);
 
   if (!has_transform)
     {
@@ -1057,13 +968,13 @@ goo_canvas_item_set_simple_transform (GooCanvasItem   *item,
 				      gdouble          scale,
 				      gdouble          rotation)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t new_matrix = { 1, 0, 0, 1, 0, 0 };
 
   cairo_matrix_translate (&new_matrix, x, y);
   cairo_matrix_scale (&new_matrix, scale, scale);
   cairo_matrix_rotate (&new_matrix, rotation * (M_PI  / 180));
-  iface->set_transform (item, &new_matrix);
+  item_class->set_transform (item, &new_matrix);
 }
 
 
@@ -1080,12 +991,12 @@ goo_canvas_item_translate      (GooCanvasItem *item,
 				gdouble        tx,
 				gdouble        ty)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t new_matrix = { 1, 0, 0, 1, 0, 0 };
 
-  iface->get_transform (item, &new_matrix);
+  item_class->get_transform (item, &new_matrix);
   cairo_matrix_translate (&new_matrix, tx, ty);
-  iface->set_transform (item, &new_matrix);
+  item_class->set_transform (item, &new_matrix);
 }
 
 
@@ -1102,12 +1013,12 @@ goo_canvas_item_scale          (GooCanvasItem *item,
 				gdouble        sx,
 				gdouble        sy)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t new_matrix = { 1, 0, 0, 1, 0, 0 };
 
-  iface->get_transform (item, &new_matrix);
+  item_class->get_transform (item, &new_matrix);
   cairo_matrix_scale (&new_matrix, sx, sy);
-  iface->set_transform (item, &new_matrix);
+  item_class->set_transform (item, &new_matrix);
 }
 
 
@@ -1127,15 +1038,15 @@ goo_canvas_item_rotate         (GooCanvasItem *item,
 				gdouble        cx,
 				gdouble        cy)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t new_matrix = { 1, 0, 0, 1, 0, 0 };
   double radians = degrees * (M_PI / 180);
 
-  iface->get_transform (item, &new_matrix);
+  item_class->get_transform (item, &new_matrix);
   cairo_matrix_translate (&new_matrix, cx, cy);
   cairo_matrix_rotate (&new_matrix, radians);
   cairo_matrix_translate (&new_matrix, -cx, -cy);
-  iface->set_transform (item, &new_matrix);
+  item_class->set_transform (item, &new_matrix);
 }
 
 
@@ -1155,16 +1066,16 @@ goo_canvas_item_skew_x         (GooCanvasItem *item,
 				gdouble        cx,
 				gdouble        cy)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t tmp, new_matrix = { 1, 0, 0, 1, 0, 0 };
   double radians = degrees * (M_PI / 180);
 
-  iface->get_transform (item, &new_matrix);
+  item_class->get_transform (item, &new_matrix);
   cairo_matrix_translate (&new_matrix, cx, cy);
   cairo_matrix_init (&tmp, 1, 0, tan (radians), 1, 0, 0);
   cairo_matrix_multiply (&new_matrix, &tmp, &new_matrix);
   cairo_matrix_translate (&new_matrix, -cx, -cy);
-  iface->set_transform (item, &new_matrix);
+  item_class->set_transform (item, &new_matrix);
 }
 
 
@@ -1184,16 +1095,16 @@ goo_canvas_item_skew_y         (GooCanvasItem *item,
 				gdouble        cx,
 				gdouble        cy)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   cairo_matrix_t tmp, new_matrix = { 1, 0, 0, 1, 0, 0 };
   double radians = degrees * (M_PI / 180);
 
-  iface->get_transform (item, &new_matrix);
+  item_class->get_transform (item, &new_matrix);
   cairo_matrix_translate (&new_matrix, cx, cy);
   cairo_matrix_init (&tmp, 1, tan (radians), 0, 1, 0, 0);
   cairo_matrix_multiply (&new_matrix, &tmp, &new_matrix);
   cairo_matrix_translate (&new_matrix, -cx, -cy);
-  iface->set_transform (item, &new_matrix);
+  item_class->set_transform (item, &new_matrix);
 }
 
 
@@ -1209,9 +1120,9 @@ goo_canvas_item_skew_y         (GooCanvasItem *item,
 GooCanvasStyle*
 goo_canvas_item_get_style      (GooCanvasItem   *item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  return iface->get_style ? iface->get_style (item) : NULL;
+  return item_class->get_style ? item_class->get_style (item) : NULL;
 }
 
 
@@ -1226,10 +1137,10 @@ void
 goo_canvas_item_set_style      (GooCanvasItem   *item,
 				GooCanvasStyle  *style)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->set_style)
-    iface->set_style (item, style);
+  if (item_class->set_style)
+    item_class->set_style (item, style);
 }
 
 
@@ -1266,7 +1177,7 @@ goo_canvas_item_animate_cb (GooCanvasItemAnimation *anim)
 {
   GooCanvasItem *item = anim->item;
   GooCanvasAnimateType type = anim->type;
-  GooCanvasItemIface *iface = NULL;
+  GooCanvasItemClass *item_class = NULL;
   cairo_matrix_t new_matrix;
   gboolean keep_source = TRUE;
   gdouble scale;
@@ -1274,7 +1185,7 @@ goo_canvas_item_animate_cb (GooCanvasItemAnimation *anim)
 
   GDK_THREADS_ENTER ();
 
-  iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
   if (++anim->step > anim->total_steps)
     {
@@ -1282,7 +1193,7 @@ goo_canvas_item_animate_cb (GooCanvasItemAnimation *anim)
 	{
 	case GOO_CANVAS_ANIMATE_RESET:
 	  /* Reset the transform to the initial value. */
-	  iface->set_transform (item, &anim->start);
+	  item_class->set_transform (item, &anim->start);
 
 	  /* Fall through.. */
 	case GOO_CANVAS_ANIMATE_FREEZE:
@@ -1330,7 +1241,7 @@ goo_canvas_item_animate_cb (GooCanvasItemAnimation *anim)
 	  cairo_matrix_rotate (&new_matrix, anim->radians_step * step);
 	}
 
-      iface->set_transform (item, &new_matrix);
+      item_class->set_transform (item, &new_matrix);
     }
 
   GDK_THREADS_LEAVE ();
@@ -1354,9 +1265,9 @@ _goo_canvas_item_animate_internal (GooCanvasItem       *item,
   GObject *object;
   cairo_matrix_t matrix = { 1, 0, 0, 1, 0, 0 };
   GooCanvasItemAnimation *anim;
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  iface->get_transform (item, &matrix);
+  item_class->get_transform (item, &matrix);
   object = (GObject*) item;
 
   anim = g_new (GooCanvasItemAnimation, 1);
@@ -1478,12 +1389,12 @@ goo_canvas_item_stop_animation (GooCanvasItem *item)
 void
 goo_canvas_item_request_update  (GooCanvasItem *item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->request_update)
-    iface->request_update (item);
+  if (item_class->request_update)
+    item_class->request_update (item);
   else
-    goo_canvas_item_request_update (iface->get_parent (item));
+    goo_canvas_item_request_update (item_class->get_parent (item));
 }
 
 
@@ -1501,9 +1412,9 @@ void
 goo_canvas_item_get_bounds  (GooCanvasItem   *item,
 			     GooCanvasBounds *bounds)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  iface->get_bounds (item, bounds);
+  item_class->get_bounds (item, bounds);
 }
 
 
@@ -1536,10 +1447,10 @@ goo_canvas_item_get_items_at (GooCanvasItem  *item,
 			      gboolean        parent_is_visible,
 			      GList          *found_items)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->get_items_at)
-    return iface->get_items_at (item, x, y, cr, is_pointer_event,
+  if (item_class->get_items_at)
+    return item_class->get_items_at (item, x, y, cr, is_pointer_event,
 				parent_is_visible, found_items);
   else
     return found_items;
@@ -1563,11 +1474,11 @@ goo_canvas_item_get_items_at (GooCanvasItem  *item,
 gboolean
 goo_canvas_item_is_visible  (GooCanvasItem   *item)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
   GooCanvasItem *parent;
 
-  if (iface->is_visible)
-    return iface->is_visible (item);
+  if (item_class->is_visible)
+    return item_class->is_visible (item);
 
   /* If the item doesn't implement the is_visible method we assume it is
      visible and check its ancestors. */
@@ -1618,9 +1529,9 @@ goo_canvas_item_update      (GooCanvasItem   *item,
 			     cairo_t         *cr,
 			     GooCanvasBounds *bounds)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  iface->update (item, entire_tree, cr, bounds);
+  item_class->update (item, entire_tree, cr, bounds);
 }
 
 
@@ -1646,9 +1557,9 @@ goo_canvas_item_paint (GooCanvasItem         *item,
 		       const GooCanvasBounds *bounds,
 		       gdouble                scale)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  iface->paint (item, cr, bounds, scale);
+  item_class->paint (item, cr, bounds, scale);
 }
 
 
@@ -1671,9 +1582,9 @@ goo_canvas_item_get_requested_area (GooCanvasItem    *item,
 				    cairo_t          *cr,
 				    GooCanvasBounds  *requested_area)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  return iface->get_requested_area (item, cr, requested_area);
+  return item_class->get_requested_area (item, cr, requested_area);
 }
 
 
@@ -1699,10 +1610,10 @@ goo_canvas_item_get_requested_height (GooCanvasItem       *item,
 				      cairo_t		  *cr,
 				      gdouble              width)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  if (iface->get_requested_height)
-    return iface->get_requested_height (item, cr, width);
+  if (item_class->get_requested_height)
+    return item_class->get_requested_height (item, cr, width);
   else
     return -1;
 }
@@ -1742,9 +1653,9 @@ goo_canvas_item_allocate_area      (GooCanvasItem         *item,
 				    gdouble                x_offset,
 				    gdouble                y_offset)
 {
-  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
 
-  iface->allocate_area (item, cr, requested_area, allocated_area,
+  item_class->allocate_area (item, cr, requested_area, allocated_area,
 			x_offset, y_offset);
 }
 
@@ -1758,15 +1669,11 @@ item_get_child_property (GObject      *object,
 			 GParamSpec   *pspec,
 			 GValue       *value)
 {
-  GObjectClass *class;
-  GooCanvasItemIface *iface;
-
-  class = g_type_class_peek (pspec->owner_type);
+  GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (object);
 
-  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM);
-  iface->get_child_property ((GooCanvasItem*) object,
-			     (GooCanvasItem*) child,
-			     pspec->param_id, value, pspec);
+  item_class->get_child_property ((GooCanvasItem*) object,
+				  (GooCanvasItem*) child,
+				  pspec->param_id, value, pspec);
 }
 
 
@@ -1912,13 +1819,11 @@ canvas_item_set_child_property (GObject            *object,
     }
   else
     {
-      GObjectClass *class = g_type_class_peek (pspec->owner_type);
-      GooCanvasItemIface *iface;
+      GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (object);
 
-      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM);
-      iface->set_child_property ((GooCanvasItem*) object,
-				 (GooCanvasItem*) child,
-				 pspec->param_id, &tmp_value, pspec);
+      item_class->set_child_property ((GooCanvasItem*) object,
+				      (GooCanvasItem*) child,
+				      pspec->param_id, &tmp_value, pspec);
 
       g_object_notify_queue_add (G_OBJECT (child), nqueue, pspec);
     }
diff --git a/src/goocanvasitem.h b/src/goocanvasitem.h
index 658904f..25cabdd 100644
--- a/src/goocanvasitem.h
+++ b/src/goocanvasitem.h
@@ -1,8 +1,8 @@
 /*
- * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-2010 Damon Chaplin.
  * Released under the GNU LGPL license. See COPYING for details.
  *
- * goocanvasitem.h - interface for canvas items & groups.
+ * goocanvasitem.h - base class for canvas items.
  */
 #ifndef __GOO_CANVAS_ITEM_H__
 #define __GOO_CANVAS_ITEM_H__
@@ -55,10 +55,15 @@ GType goo_canvas_bounds_get_type (void) G_GNUC_CONST;
 
 #define GOO_TYPE_CANVAS_ITEM            (goo_canvas_item_get_type ())
 #define GOO_CANVAS_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ITEM, GooCanvasItem))
+#define GOO_CANVAS_ITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ITEM, GooCanvasItemClass))
 #define GOO_IS_CANVAS_ITEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_ITEM))
-#define GOO_CANVAS_ITEM_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GOO_TYPE_CANVAS_ITEM, GooCanvasItemIface))
+#define GOO_IS_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_ITEM))
+#define GOO_CANVAS_ITEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_ITEM, GooCanvasItemClass))
 
 
+typedef struct _GooCanvasItem       GooCanvasItem;
+typedef struct _GooCanvasItemClass  GooCanvasItemClass;
+
 /* Workaround for circular dependencies. Include this file first. */
 typedef struct _GooCanvas           GooCanvas;
 
@@ -66,17 +71,16 @@ typedef struct _GooCanvas           GooCanvas;
 /**
  * GooCanvasItem
  *
- * #GooCanvasItem is a typedef used for objects that implement the
- * #GooCanvasItem interface.
- *
- * (There is no actual #GooCanvasItem struct, since it is only an interface.
- * But using '#GooCanvasItem' is more helpful than using '#GObject'.)
+ * The #GooCanvasItem-struct struct contains private data only.
  */
-typedef struct _GooCanvasItem       GooCanvasItem;
+struct _GooCanvasItem
+{
+  GObject parent_object;
+};
 
 
 /**
- * GooCanvasItemIface
+ * GooCanvasItemClass
  * @get_canvas: returns the canvas the item is in.
  * @set_canvas: sets the canvas the item is in.
  * @get_n_children: returns the number of children of the item.
@@ -129,8 +133,7 @@ typedef struct _GooCanvasItem       GooCanvasItem;
  * @scroll_event: signal emitted when the mouse wheel is activated within
  * the item.
  *
- * #GooCanvasItemIFace holds the virtual methods that make up the
- * #GooCanvasItem interface.
+ * #GooCanvasItemClass holds the virtual methods needed for canvas items.
  *
  * Simple canvas items only need to implement the get_parent(), set_parent(),
  * get_bounds(), get_items_at(), update() and paint() methods (and also
@@ -148,12 +151,10 @@ typedef struct _GooCanvasItem       GooCanvasItem;
  * may implement get_child_property(), set_child_property() and
  * get_transform_for_child().
  */
-typedef struct _GooCanvasItemIface  GooCanvasItemIface;
-
-struct _GooCanvasItemIface
+struct _GooCanvasItemClass
 {
   /*< private >*/
-  GTypeInterface base_iface;
+  GObjectClass parent_class;
 
   /*< public >*/
   /* Virtual methods that group items must implement. */
@@ -229,6 +230,7 @@ struct _GooCanvasItemIface
   void			(* set_style)			(GooCanvasItem		*item,
 							 GooCanvasStyle		*style);
   gboolean		(* is_visible)			(GooCanvasItem		*item);
+  gboolean		(* get_can_focus)		(GooCanvasItem		*item);
   gdouble               (* get_requested_height)	(GooCanvasItem		*item,
 							 cairo_t		*cr,
 							 gdouble		 width);
diff --git a/src/goocanvasitemsimple.c b/src/goocanvasitemsimple.c
index 2376dd3..8e48ead 100644
--- a/src/goocanvasitemsimple.c
+++ b/src/goocanvasitemsimple.c
@@ -85,263 +85,9 @@ enum {
 
 static gboolean accessibility_enabled = FALSE;
 
-static void canvas_item_interface_init          (GooCanvasItemIface   *iface);
-static void goo_canvas_item_simple_dispose      (GObject              *object);
-static void goo_canvas_item_simple_get_property (GObject              *object,
-						 guint                 prop_id,
-						 GValue               *value,
-						 GParamSpec           *pspec);
-static void goo_canvas_item_simple_set_property (GObject              *object,
-						 guint                 prop_id,
-						 const GValue         *value,
-						 GParamSpec           *pspec);
-
-static void     goo_canvas_item_simple_default_create_path (GooCanvasItemSimple   *simple,
-							    cairo_t               *cr);
-static void     goo_canvas_item_simple_default_update      (GooCanvasItemSimple   *simple,
-							    cairo_t               *cr);
-static void     goo_canvas_item_simple_default_paint       (GooCanvasItemSimple   *simple,
-							    cairo_t               *cr,
-							    const GooCanvasBounds *bounds);
-static gboolean goo_canvas_item_simple_default_is_item_at  (GooCanvasItemSimple   *simple,
-							    double                 x,
-							    double                 y,
-							    cairo_t               *cr,
-							    gboolean               is_pointer_event);
-
-
-G_DEFINE_TYPE_WITH_CODE (GooCanvasItemSimple, goo_canvas_item_simple,
-			 G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						canvas_item_interface_init))
 
-
-static void
-goo_canvas_item_simple_install_common_properties (GObjectClass *gobject_class)
-{
-  /* Basic drawing properties. */
-  g_object_class_install_property (gobject_class, PROP_STROKE_PATTERN,
-                                   g_param_spec_boxed ("stroke-pattern",
-						       _("Stroke Pattern"),
-						       _("The pattern to use to paint the perimeter of the item, or NULL disable painting"),
-						       GOO_TYPE_CAIRO_PATTERN,
-						       G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_FILL_PATTERN,
-                                   g_param_spec_boxed ("fill-pattern",
-						       _("Fill Pattern"),
-						       _("The pattern to use to paint the interior of the item, or NULL to disable painting"),
-						       GOO_TYPE_CAIRO_PATTERN,
-						       G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_FILL_RULE,
-				   g_param_spec_enum ("fill-rule",
-						      _("Fill Rule"),
-						      _("The fill rule used to determine which parts of the item are filled"),
-						      GOO_TYPE_CAIRO_FILL_RULE,
-						      CAIRO_FILL_RULE_WINDING,
-						      G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_OPERATOR,
-				   g_param_spec_enum ("operator",
-						      _("Operator"),
-						      _("The compositing operator to use"),
-						      GOO_TYPE_CAIRO_OPERATOR,
-						      CAIRO_OPERATOR_OVER,
-						      G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_ANTIALIAS,
-				   g_param_spec_enum ("antialias",
-						      _("Antialias"),
-						      _("The antialiasing mode to use"),
-						      GOO_TYPE_CAIRO_ANTIALIAS,
-						      CAIRO_ANTIALIAS_GRAY,
-						      G_PARAM_READWRITE));
-
-  /* Line style & width properties. */
-  g_object_class_install_property (gobject_class, PROP_LINE_WIDTH,
-				   g_param_spec_double ("line-width",
-							_("Line Width"),
-							_("The line width to use for the item's perimeter"),
-							0.0, G_MAXDOUBLE, 2.0,
-							G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_LINE_CAP,
-				   g_param_spec_enum ("line-cap",
-						      _("Line Cap"),
-						      _("The line cap style to use"),
-						      GOO_TYPE_CAIRO_LINE_CAP,
-						      CAIRO_LINE_CAP_BUTT,
-						      G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_LINE_JOIN,
-				   g_param_spec_enum ("line-join",
-						      _("Line Join"),
-						      _("The line join style to use"),
-						      GOO_TYPE_CAIRO_LINE_JOIN,
-						      CAIRO_LINE_JOIN_MITER,
-						      G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_LINE_JOIN_MITER_LIMIT,
-				   g_param_spec_double ("line-join-miter-limit",
-							_("Miter Limit"),
-							_("The smallest angle to use with miter joins, in degrees. Bevel joins will be used below this limit"),
-							0.0, G_MAXDOUBLE, 10.0,
-							G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_LINE_DASH,
-				   g_param_spec_boxed ("line-dash",
-						       _("Line Dash"),
-						       _("The dash pattern to use"),
-						       GOO_TYPE_CANVAS_LINE_DASH,
-						       G_PARAM_READWRITE));
-
-  /* Font properties. */
-  g_object_class_install_property (gobject_class, PROP_FONT,
-				   g_param_spec_string ("font",
-							_("Font"),
-							_("The base font to use for the text"),
-							NULL,
-							G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_FONT_DESC,
-				   g_param_spec_boxed ("font-desc",
-						       _("Font Description"),
-						       _("The attributes specifying which font to use"),
-						       PANGO_TYPE_FONT_DESCRIPTION,
-						       G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_HINT_METRICS,
-				   g_param_spec_enum ("hint-metrics",
-						      _("Hint Metrics"),
-						      _("The hinting to be used for font metrics"),
-						      GOO_TYPE_CAIRO_HINT_METRICS,
-						      CAIRO_HINT_METRICS_OFF,
-						      G_PARAM_READWRITE));
-
-  /* Convenience properties - writable only. */
-  g_object_class_install_property (gobject_class, PROP_STROKE_COLOR,
-				   g_param_spec_string ("stroke-color",
-							_("Stroke Color"),
-							_("The color to use for the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
-							NULL,
-							G_PARAM_WRITABLE));
-
-  g_object_class_install_property (gobject_class, PROP_STROKE_COLOR_RGBA,
-				   g_param_spec_uint ("stroke-color-rgba",
-						      _("Stroke Color RGBA"),
-						      _("The color to use for the item's perimeter, specified as a 32-bit integer value. To disable painting set the 'stroke-pattern' property to NULL"),
-						      0, G_MAXUINT, 0,
-						      G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_STROKE_PIXBUF,
-                                   g_param_spec_object ("stroke-pixbuf",
-							_("Stroke Pixbuf"),
-							_("The pixbuf to use to draw the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
-                                                        GDK_TYPE_PIXBUF,
-                                                        G_PARAM_WRITABLE));
-
-  g_object_class_install_property (gobject_class, PROP_FILL_COLOR,
-				   g_param_spec_string ("fill-color",
-							_("Fill Color"),
-							_("The color to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
-							NULL,
-							G_PARAM_WRITABLE));
-
-  g_object_class_install_property (gobject_class, PROP_FILL_COLOR_RGBA,
-				   g_param_spec_uint ("fill-color-rgba",
-						      _("Fill Color RGBA"),
-						      _("The color to use to paint the interior of the item, specified as a 32-bit integer value. To disable painting set the 'fill-pattern' property to NULL"),
-						      0, G_MAXUINT, 0,
-						      G_PARAM_READWRITE));
-
-  g_object_class_install_property (gobject_class, PROP_FILL_PIXBUF,
-                                   g_param_spec_object ("fill-pixbuf",
-							_("Fill Pixbuf"),
-							_("The pixbuf to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
-                                                        GDK_TYPE_PIXBUF,
-                                                        G_PARAM_WRITABLE));
-
-  /* Other properties. */
-  g_object_class_override_property (gobject_class, PROP_PARENT,
-				    "parent");
-
-  g_object_class_override_property (gobject_class, PROP_VISIBILITY,
-				    "visibility");
-
-  g_object_class_override_property (gobject_class, PROP_VISIBILITY_THRESHOLD,
-				    "visibility-threshold");
-
-  g_object_class_override_property (gobject_class, PROP_TRANSFORM,
-				    "transform");
-
-  g_object_class_override_property (gobject_class, PROP_POINTER_EVENTS,
-				    "pointer-events");
-
-  g_object_class_override_property (gobject_class, PROP_TITLE,
-				    "title");
-
-  g_object_class_override_property (gobject_class, PROP_DESCRIPTION,
-				    "description");
-
-  g_object_class_override_property (gobject_class, PROP_CAN_FOCUS,
-				    "can-focus");
-
-  g_object_class_override_property (gobject_class, PROP_TOOLTIP,
-				    "tooltip");
-
-  /**
-   * GooCanvasItemSimple:clip-path
-   *
-   * The sequence of commands describing the clip path of the item, specified
-   * as a string using the same syntax
-   * as in the <ulink url="http://www.w3.org/Graphics/SVG/";>Scalable Vector
-   * Graphics (SVG)</ulink> path element.
-   */
-  g_object_class_install_property (gobject_class, PROP_CLIP_PATH,
-				   g_param_spec_string ("clip-path",
-							_("Clip Path"),
-							_("The sequence of path commands specifying the clip path"),
-							NULL,
-							G_PARAM_WRITABLE));
-
-  g_object_class_install_property (gobject_class, PROP_CLIP_FILL_RULE,
-				   g_param_spec_enum ("clip-fill-rule",
-						      _("Clip Fill Rule"),
-						      _("The fill rule used to determine which parts of the item are clipped"),
-						      GOO_TYPE_CAIRO_FILL_RULE,
-						      CAIRO_FILL_RULE_WINDING,
-						      G_PARAM_READWRITE));
-
-}
-
-
-static void
-goo_canvas_item_simple_class_init (GooCanvasItemSimpleClass *klass)
-{
-  GObjectClass *gobject_class = (GObjectClass*) klass;
-
-  gobject_class->dispose  = goo_canvas_item_simple_dispose;
-
-  gobject_class->get_property = goo_canvas_item_simple_get_property;
-  gobject_class->set_property = goo_canvas_item_simple_set_property;
-
-  /* Register our accessible factory, but only if accessibility is enabled. */
-  if (!ATK_IS_NO_OP_OBJECT_FACTORY (atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET)))
-    {
-      accessibility_enabled = TRUE;
-      atk_registry_set_factory_type (atk_get_default_registry (),
-				     GOO_TYPE_CANVAS_ITEM_SIMPLE,
-				     goo_canvas_item_accessible_factory_get_type ());
-    }
-
-  goo_canvas_item_simple_install_common_properties (gobject_class);
-
-  klass->simple_create_path = goo_canvas_item_simple_default_create_path;
-  klass->simple_update      = goo_canvas_item_simple_default_update;
-  klass->simple_paint       = goo_canvas_item_simple_default_paint;
-  klass->simple_is_item_at  = goo_canvas_item_simple_default_is_item_at;
-}
+G_DEFINE_TYPE (GooCanvasItemSimple, goo_canvas_item_simple,
+	       GOO_TYPE_CANVAS_ITEM)
 
 
 static void
@@ -970,6 +716,15 @@ goo_canvas_item_simple_is_visible  (GooCanvasItem   *item)
 
 
 static gboolean
+goo_canvas_item_simple_get_can_focus  (GooCanvasItem   *item)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+
+  return simple->can_focus;
+}
+
+
+static gboolean
 goo_canvas_item_simple_get_is_static  (GooCanvasItem   *item)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
@@ -1296,33 +1051,6 @@ goo_canvas_item_simple_query_tooltip (GooCanvasItem  *item,
 }
 
 
-static void
-canvas_item_interface_init (GooCanvasItemIface *iface)
-{
-  iface->get_canvas         = goo_canvas_item_simple_get_canvas;
-  iface->set_canvas         = goo_canvas_item_simple_set_canvas;
-
-  iface->get_parent	    = goo_canvas_item_simple_get_parent;
-  iface->set_parent	    = goo_canvas_item_simple_set_parent;
-  iface->get_bounds         = goo_canvas_item_simple_get_bounds;
-  iface->get_items_at	    = goo_canvas_item_simple_get_items_at;
-  iface->update             = goo_canvas_item_simple_update;
-  iface->get_requested_area = goo_canvas_item_simple_get_requested_area;
-  iface->allocate_area      = goo_canvas_item_simple_allocate_area;
-  iface->paint              = goo_canvas_item_simple_paint;
-
-  iface->get_transform      = goo_canvas_item_simple_get_transform;
-  iface->set_transform      = goo_canvas_item_simple_set_transform;
-  iface->get_style          = goo_canvas_item_simple_get_style;
-  iface->set_style          = goo_canvas_item_simple_set_style;
-  iface->is_visible         = goo_canvas_item_simple_is_visible;
-  iface->get_is_static	    = goo_canvas_item_simple_get_is_static;
-  iface->set_is_static	    = goo_canvas_item_simple_set_is_static;
-
-  iface->query_tooltip	    = goo_canvas_item_simple_query_tooltip;
-}
-
-
 /**
  * goo_canvas_item_simple_paint_path:
  * @item: a #GooCanvasItemSimple.
@@ -1616,3 +1344,297 @@ goo_canvas_item_simple_get_line_width (GooCanvasItemSimple   *simple)
   else
     return 2.0;
 }
+
+
+static void
+goo_canvas_item_simple_class_init (GooCanvasItemSimpleClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+  GooCanvasItemClass *item_class = (GooCanvasItemClass*) klass;
+
+  gobject_class->dispose  = goo_canvas_item_simple_dispose;
+
+  gobject_class->get_property = goo_canvas_item_simple_get_property;
+  gobject_class->set_property = goo_canvas_item_simple_set_property;
+
+  item_class->get_canvas         = goo_canvas_item_simple_get_canvas;
+  item_class->set_canvas         = goo_canvas_item_simple_set_canvas;
+
+  item_class->get_parent	 = goo_canvas_item_simple_get_parent;
+  item_class->set_parent	 = goo_canvas_item_simple_set_parent;
+  item_class->get_bounds         = goo_canvas_item_simple_get_bounds;
+  item_class->get_items_at	 = goo_canvas_item_simple_get_items_at;
+  item_class->update             = goo_canvas_item_simple_update;
+  item_class->get_requested_area = goo_canvas_item_simple_get_requested_area;
+  item_class->allocate_area      = goo_canvas_item_simple_allocate_area;
+  item_class->paint              = goo_canvas_item_simple_paint;
+
+  item_class->get_transform      = goo_canvas_item_simple_get_transform;
+  item_class->set_transform      = goo_canvas_item_simple_set_transform;
+  item_class->get_style          = goo_canvas_item_simple_get_style;
+  item_class->set_style          = goo_canvas_item_simple_set_style;
+  item_class->is_visible         = goo_canvas_item_simple_is_visible;
+  item_class->get_can_focus	 = goo_canvas_item_simple_get_can_focus;
+  item_class->get_is_static	 = goo_canvas_item_simple_get_is_static;
+  item_class->set_is_static	 = goo_canvas_item_simple_set_is_static;
+
+  item_class->query_tooltip	 = goo_canvas_item_simple_query_tooltip;
+
+  klass->simple_create_path = goo_canvas_item_simple_default_create_path;
+  klass->simple_update      = goo_canvas_item_simple_default_update;
+  klass->simple_paint       = goo_canvas_item_simple_default_paint;
+  klass->simple_is_item_at  = goo_canvas_item_simple_default_is_item_at;
+
+  /* Register our accessible factory, but only if accessibility is enabled. */
+  if (!ATK_IS_NO_OP_OBJECT_FACTORY (atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET)))
+    {
+      accessibility_enabled = TRUE;
+      atk_registry_set_factory_type (atk_get_default_registry (),
+				     GOO_TYPE_CANVAS_ITEM_SIMPLE,
+				     goo_canvas_item_accessible_factory_get_type ());
+    }
+
+  /* Basic drawing properties. */
+  g_object_class_install_property (gobject_class, PROP_STROKE_PATTERN,
+                                   g_param_spec_boxed ("stroke-pattern",
+						       _("Stroke Pattern"),
+						       _("The pattern to use to paint the perimeter of the item, or NULL disable painting"),
+						       GOO_TYPE_CAIRO_PATTERN,
+						       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_FILL_PATTERN,
+                                   g_param_spec_boxed ("fill-pattern",
+						       _("Fill Pattern"),
+						       _("The pattern to use to paint the interior of the item, or NULL to disable painting"),
+						       GOO_TYPE_CAIRO_PATTERN,
+						       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_FILL_RULE,
+				   g_param_spec_enum ("fill-rule",
+						      _("Fill Rule"),
+						      _("The fill rule used to determine which parts of the item are filled"),
+						      GOO_TYPE_CAIRO_FILL_RULE,
+						      CAIRO_FILL_RULE_WINDING,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_OPERATOR,
+				   g_param_spec_enum ("operator",
+						      _("Operator"),
+						      _("The compositing operator to use"),
+						      GOO_TYPE_CAIRO_OPERATOR,
+						      CAIRO_OPERATOR_OVER,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_ANTIALIAS,
+				   g_param_spec_enum ("antialias",
+						      _("Antialias"),
+						      _("The antialiasing mode to use"),
+						      GOO_TYPE_CAIRO_ANTIALIAS,
+						      CAIRO_ANTIALIAS_GRAY,
+						      G_PARAM_READWRITE));
+
+  /* Line style & width properties. */
+  g_object_class_install_property (gobject_class, PROP_LINE_WIDTH,
+				   g_param_spec_double ("line-width",
+							_("Line Width"),
+							_("The line width to use for the item's perimeter"),
+							0.0, G_MAXDOUBLE, 2.0,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_LINE_CAP,
+				   g_param_spec_enum ("line-cap",
+						      _("Line Cap"),
+						      _("The line cap style to use"),
+						      GOO_TYPE_CAIRO_LINE_CAP,
+						      CAIRO_LINE_CAP_BUTT,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_LINE_JOIN,
+				   g_param_spec_enum ("line-join",
+						      _("Line Join"),
+						      _("The line join style to use"),
+						      GOO_TYPE_CAIRO_LINE_JOIN,
+						      CAIRO_LINE_JOIN_MITER,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_LINE_JOIN_MITER_LIMIT,
+				   g_param_spec_double ("line-join-miter-limit",
+							_("Miter Limit"),
+							_("The smallest angle to use with miter joins, in degrees. Bevel joins will be used below this limit"),
+							0.0, G_MAXDOUBLE, 10.0,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_LINE_DASH,
+				   g_param_spec_boxed ("line-dash",
+						       _("Line Dash"),
+						       _("The dash pattern to use"),
+						       GOO_TYPE_CANVAS_LINE_DASH,
+						       G_PARAM_READWRITE));
+
+  /* Font properties. */
+  g_object_class_install_property (gobject_class, PROP_FONT,
+				   g_param_spec_string ("font",
+							_("Font"),
+							_("The base font to use for the text"),
+							NULL,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_FONT_DESC,
+				   g_param_spec_boxed ("font-desc",
+						       _("Font Description"),
+						       _("The attributes specifying which font to use"),
+						       PANGO_TYPE_FONT_DESCRIPTION,
+						       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_HINT_METRICS,
+				   g_param_spec_enum ("hint-metrics",
+						      _("Hint Metrics"),
+						      _("The hinting to be used for font metrics"),
+						      GOO_TYPE_CAIRO_HINT_METRICS,
+						      CAIRO_HINT_METRICS_OFF,
+						      G_PARAM_READWRITE));
+
+  /* Convenience properties - writable only. */
+  g_object_class_install_property (gobject_class, PROP_STROKE_COLOR,
+				   g_param_spec_string ("stroke-color",
+							_("Stroke Color"),
+							_("The color to use for the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
+							NULL,
+							G_PARAM_WRITABLE));
+
+  g_object_class_install_property (gobject_class, PROP_STROKE_COLOR_RGBA,
+				   g_param_spec_uint ("stroke-color-rgba",
+						      _("Stroke Color RGBA"),
+						      _("The color to use for the item's perimeter, specified as a 32-bit integer value. To disable painting set the 'stroke-pattern' property to NULL"),
+						      0, G_MAXUINT, 0,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_STROKE_PIXBUF,
+                                   g_param_spec_object ("stroke-pixbuf",
+							_("Stroke Pixbuf"),
+							_("The pixbuf to use to draw the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
+                                                        GDK_TYPE_PIXBUF,
+                                                        G_PARAM_WRITABLE));
+
+  g_object_class_install_property (gobject_class, PROP_FILL_COLOR,
+				   g_param_spec_string ("fill-color",
+							_("Fill Color"),
+							_("The color to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
+							NULL,
+							G_PARAM_WRITABLE));
+
+  g_object_class_install_property (gobject_class, PROP_FILL_COLOR_RGBA,
+				   g_param_spec_uint ("fill-color-rgba",
+						      _("Fill Color RGBA"),
+						      _("The color to use to paint the interior of the item, specified as a 32-bit integer value. To disable painting set the 'fill-pattern' property to NULL"),
+						      0, G_MAXUINT, 0,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_FILL_PIXBUF,
+                                   g_param_spec_object ("fill-pixbuf",
+							_("Fill Pixbuf"),
+							_("The pixbuf to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
+                                                        GDK_TYPE_PIXBUF,
+                                                        G_PARAM_WRITABLE));
+
+  /* Other properties. */
+  g_object_class_install_property (gobject_class,
+				   PROP_PARENT,
+				   g_param_spec_object ("parent",
+							_("Parent"),
+							_("The parent item"),
+							GOO_TYPE_CANVAS_ITEM,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_VISIBILITY,
+				   g_param_spec_enum ("visibility",
+						      _("Visibility"),
+						      _("When the canvas item is visible"),
+						      GOO_TYPE_CANVAS_ITEM_VISIBILITY,
+						      GOO_CANVAS_ITEM_VISIBLE,
+						      G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_VISIBILITY_THRESHOLD,
+				   g_param_spec_double ("visibility-threshold",
+							_("Visibility Threshold"),
+							_("The scale threshold at which the item becomes visible"),
+							0.0,
+							G_MAXDOUBLE,
+							0.0,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_TRANSFORM,
+				   g_param_spec_boxed ("transform",
+						       _("Transform"),
+						       _("The transformation matrix of the item"),
+						       GOO_TYPE_CAIRO_MATRIX,
+						       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_POINTER_EVENTS,
+				   g_param_spec_flags ("pointer-events",
+						       _("Pointer Events"),
+						       _("Specifies when the item receives pointer events"),
+						       GOO_TYPE_CANVAS_POINTER_EVENTS,
+						       GOO_CANVAS_EVENTS_VISIBLE_PAINTED,
+						       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_TITLE,
+				   g_param_spec_string ("title",
+							_("Title"),
+							_("A short context-rich description of the item for use by assistive technologies"),
+							NULL,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_DESCRIPTION,
+				   g_param_spec_string ("description",
+							_("Description"),
+							_("A description of the item for use by assistive technologies"),
+							NULL,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_CAN_FOCUS,
+				   g_param_spec_boolean ("can-focus",
+							 _("Can Focus"),
+							 _("If the item can take the keyboard focus"),
+							 FALSE,
+							 G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_TOOLTIP,
+				   g_param_spec_string ("tooltip",
+							_("Tooltip"),
+							_("The tooltip to display for the item"),
+							NULL,
+							G_PARAM_READWRITE));
+
+
+  /**
+   * GooCanvasItemSimple:clip-path
+   *
+   * The sequence of commands describing the clip path of the item, specified
+   * as a string using the same syntax
+   * as in the <ulink url="http://www.w3.org/Graphics/SVG/";>Scalable Vector
+   * Graphics (SVG)</ulink> path element.
+   */
+  g_object_class_install_property (gobject_class, PROP_CLIP_PATH,
+				   g_param_spec_string ("clip-path",
+							_("Clip Path"),
+							_("The sequence of path commands specifying the clip path"),
+							NULL,
+							G_PARAM_WRITABLE));
+
+  g_object_class_install_property (gobject_class, PROP_CLIP_FILL_RULE,
+				   g_param_spec_enum ("clip-fill-rule",
+						      _("Clip Fill Rule"),
+						      _("The fill rule used to determine which parts of the item are clipped"),
+						      GOO_TYPE_CAIRO_FILL_RULE,
+						      CAIRO_FILL_RULE_WINDING,
+						      G_PARAM_READWRITE));
+}
diff --git a/src/goocanvasitemsimple.h b/src/goocanvasitemsimple.h
index 9955785..21f351f 100644
--- a/src/goocanvasitemsimple.h
+++ b/src/goocanvasitemsimple.h
@@ -57,7 +57,7 @@ typedef struct _GooCanvasItemSimpleClass  GooCanvasItemSimpleClass;
 struct _GooCanvasItemSimple
 {
   /* <private> */
-  GObject parent_object;
+  GooCanvasItem parent_object;
 
   /* <public> */
   GooCanvas *canvas;
@@ -104,7 +104,7 @@ struct _GooCanvasItemSimple
 struct _GooCanvasItemSimpleClass
 {
   /*< private >*/
-  GObjectClass parent_class;
+  GooCanvasItemClass parent_class;
 
   /*< public >*/
   void		 (* simple_create_path)	(GooCanvasItemSimple   *simple,
diff --git a/src/goocanvastable.c b/src/goocanvastable.c
index 4137b88..a2b2ccb 100644
--- a/src/goocanvastable.c
+++ b/src/goocanvastable.c
@@ -198,26 +198,13 @@ struct _GooCanvasTableLayoutData
   gdouble last_width;
 };
 
-static GooCanvasItemIface *goo_canvas_table_parent_iface;
-
-static void item_interface_init           (GooCanvasItemIface *iface);
-static void goo_canvas_table_finalize     (GObject            *object);
-static void goo_canvas_table_get_property (GObject            *object,
-					   guint               param_id,
-					   GValue             *value,
-					   GParamSpec         *pspec);
-static void goo_canvas_table_set_property (GObject            *object,
-					   guint               param_id,
-					   const GValue       *value,
-					   GParamSpec         *pspec);
 
 static void goo_canvas_table_init_layout_data (GooCanvasTable *table);
 static void goo_canvas_table_free_layout_data (GooCanvasTable *table);
 
-G_DEFINE_TYPE_WITH_CODE (GooCanvasTable, goo_canvas_table,
-			 GOO_TYPE_CANVAS_GROUP,
-			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						item_interface_init))
+
+G_DEFINE_TYPE (GooCanvasTable, goo_canvas_table, GOO_TYPE_CANVAS_GROUP)
+
 
 typedef void (*InstallChildPropertyFunc) (GObjectClass*, guint, GParamSpec*);
 
@@ -391,21 +378,6 @@ goo_canvas_table_install_common_properties (GObjectClass *gobject_class,
 
 
 static void
-goo_canvas_table_class_init (GooCanvasTableClass *klass)
-{
-  GObjectClass *gobject_class = (GObjectClass*) klass;
-
-  goo_canvas_table_parent_iface = g_type_interface_peek (goo_canvas_table_parent_class, GOO_TYPE_CANVAS_ITEM);
-
-  gobject_class->finalize = goo_canvas_table_finalize;
-  gobject_class->get_property = goo_canvas_table_get_property;
-  gobject_class->set_property = goo_canvas_table_set_property;
-
-  goo_canvas_table_install_common_properties (gobject_class, goo_canvas_item_class_install_child_property);
-}
-
-
-static void
 goo_canvas_table_init (GooCanvasTable *table)
 {
   gint d;
@@ -774,7 +746,7 @@ goo_canvas_table_add_child     (GooCanvasItem  *item,
   goo_canvas_table_add_child_internal (table, position);
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->add_child (item, child, position);
+  GOO_CANVAS_ITEM_CLASS (goo_canvas_table_parent_class)->add_child (item, child, position);
 }
 
 
@@ -827,7 +799,7 @@ goo_canvas_table_move_child    (GooCanvasItem  *item,
 					new_position);
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->move_child (item, old_position, new_position);
+  GOO_CANVAS_ITEM_CLASS (goo_canvas_table_parent_class)->move_child (item, old_position, new_position);
 }
 
 
@@ -843,7 +815,7 @@ goo_canvas_table_remove_child  (GooCanvasItem  *item,
   g_array_remove_index (table->children, child_num);
 
   /* Let the parent GooCanvasGroup code do the rest. */
-  goo_canvas_table_parent_iface->remove_child (item, child_num);
+  GOO_CANVAS_ITEM_CLASS (goo_canvas_table_parent_class)->remove_child (item, child_num);
 }
 
 
@@ -2558,19 +2530,30 @@ goo_canvas_table_get_transform_for_child  (GooCanvasItem  *item,
 
 
 static void
-item_interface_init (GooCanvasItemIface *iface)
+goo_canvas_table_class_init (GooCanvasTableClass *klass)
 {
-  iface->add_child               = goo_canvas_table_add_child;
-  iface->move_child              = goo_canvas_table_move_child;
-  iface->remove_child            = goo_canvas_table_remove_child;
-  iface->get_child_property      = goo_canvas_table_get_child_property;
-  iface->set_child_property      = goo_canvas_table_set_child_property;
-  iface->get_transform_for_child = goo_canvas_table_get_transform_for_child;
-
-  iface->update                  = goo_canvas_table_update;
-  iface->get_requested_area      = goo_canvas_table_get_requested_area;
-  iface->get_requested_height    = goo_canvas_table_get_requested_height;
-  iface->allocate_area           = goo_canvas_table_allocate_area;
-  iface->paint                   = goo_canvas_table_paint;
-  iface->get_items_at	         = goo_canvas_table_get_items_at;
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+  GooCanvasItemClass *item_class = (GooCanvasItemClass*) klass;
+
+  gobject_class->finalize = goo_canvas_table_finalize;
+  gobject_class->get_property = goo_canvas_table_get_property;
+  gobject_class->set_property = goo_canvas_table_set_property;
+
+  item_class->add_child               = goo_canvas_table_add_child;
+  item_class->move_child              = goo_canvas_table_move_child;
+  item_class->remove_child            = goo_canvas_table_remove_child;
+  item_class->get_child_property      = goo_canvas_table_get_child_property;
+  item_class->set_child_property      = goo_canvas_table_set_child_property;
+  item_class->get_transform_for_child = goo_canvas_table_get_transform_for_child;
+
+  item_class->update                  = goo_canvas_table_update;
+  item_class->get_requested_area      = goo_canvas_table_get_requested_area;
+  item_class->get_requested_height    = goo_canvas_table_get_requested_height;
+  item_class->allocate_area           = goo_canvas_table_allocate_area;
+  item_class->paint                   = goo_canvas_table_paint;
+  item_class->get_items_at	      = goo_canvas_table_get_items_at;
+
+  goo_canvas_table_install_common_properties (gobject_class, goo_canvas_item_class_install_child_property);
 }
+
+
diff --git a/src/goocanvastext.c b/src/goocanvastext.c
index d3c98d1..a8c69a9 100644
--- a/src/goocanvastext.c
+++ b/src/goocanvastext.c
@@ -59,14 +59,8 @@ goo_canvas_text_create_layout (GooCanvasText           *text,
 			       gdouble	               *origin_x_return,
 			       gdouble	               *origin_y_return);
 
-static void goo_canvas_text_finalize     (GObject            *object);
-static void canvas_item_interface_init   (GooCanvasItemIface *iface);
 
-
-G_DEFINE_TYPE_WITH_CODE (GooCanvasText, goo_canvas_text,
-			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
-			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						canvas_item_interface_init))
+G_DEFINE_TYPE (GooCanvasText, goo_canvas_text, GOO_TYPE_CANVAS_ITEM_SIMPLE)
 
 
 static void
@@ -665,16 +659,10 @@ goo_canvas_text_get_natural_extents (GooCanvasText  *text,
 
 
 static void
-canvas_item_interface_init (GooCanvasItemIface *iface)
-{
-  iface->get_requested_height = goo_canvas_text_get_requested_height;
-}
-
-
-static void
 goo_canvas_text_class_init (GooCanvasTextClass *klass)
 {
   GObjectClass *gobject_class = (GObjectClass*) klass;
+  GooCanvasItemClass *item_class = (GooCanvasItemClass*) klass;
   GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
 
   gobject_class->finalize = goo_canvas_text_finalize;
@@ -682,6 +670,8 @@ goo_canvas_text_class_init (GooCanvasTextClass *klass)
   gobject_class->get_property = goo_canvas_text_get_property;
   gobject_class->set_property = goo_canvas_text_set_property;
 
+  item_class->get_requested_height = goo_canvas_text_get_requested_height;
+
   simple_class->simple_update        = goo_canvas_text_update;
   simple_class->simple_paint         = goo_canvas_text_paint;
   simple_class->simple_is_item_at    = goo_canvas_text_is_item_at;
diff --git a/src/goocanvasutils.c b/src/goocanvasutils.c
index bc658ed..a2a64a2 100644
--- a/src/goocanvasutils.c
+++ b/src/goocanvasutils.c
@@ -479,7 +479,7 @@ goo_canvas_query_child_properties (gpointer  class,
   if (!G_TYPE_IS_CLASSED (G_TYPE_FROM_CLASS (class)))
     return NULL;
 
-  if (g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM))
+  if (GOO_IS_CANVAS_ITEM_CLASS (class))
     return goo_canvas_item_class_list_child_properties (class,
 							n_properties);
 
diff --git a/src/goocanvaswidget.c b/src/goocanvaswidget.c
index 397a6cf..1e9c296 100644
--- a/src/goocanvaswidget.c
+++ b/src/goocanvaswidget.c
@@ -50,21 +50,7 @@ enum {
 };
 
 
-static void canvas_item_interface_init      (GooCanvasItemIface  *iface);
-static void goo_canvas_widget_dispose       (GObject             *object);
-static void goo_canvas_widget_get_property  (GObject             *object,
-					     guint                param_id,
-					     GValue              *value,
-					     GParamSpec          *pspec);
-static void goo_canvas_widget_set_property  (GObject             *object,
-					     guint                param_id,
-					     const GValue        *value,
-					     GParamSpec          *pspec);
-
-G_DEFINE_TYPE_WITH_CODE (GooCanvasWidget, goo_canvas_widget,
-			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
-			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						canvas_item_interface_init))
+G_DEFINE_TYPE (GooCanvasWidget, goo_canvas_widget, GOO_TYPE_CANVAS_ITEM_SIMPLE)
 
 
 static void
@@ -510,18 +496,10 @@ goo_canvas_widget_is_item_at (GooCanvasItemSimple *simple,
 
 
 static void
-canvas_item_interface_init (GooCanvasItemIface *iface)
-{
-  iface->set_canvas     = goo_canvas_widget_set_canvas;
-  iface->set_parent	= goo_canvas_widget_set_parent;
-  iface->allocate_area  = goo_canvas_widget_allocate_area;
-}
-
-
-static void
 goo_canvas_widget_class_init (GooCanvasWidgetClass *klass)
 {
   GObjectClass *gobject_class = (GObjectClass*) klass;
+  GooCanvasItemClass *item_class = (GooCanvasItemClass*) klass;
   GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
 
   gobject_class->dispose = goo_canvas_widget_dispose;
@@ -529,6 +507,10 @@ goo_canvas_widget_class_init (GooCanvasWidgetClass *klass)
   gobject_class->get_property = goo_canvas_widget_get_property;
   gobject_class->set_property = goo_canvas_widget_set_property;
 
+  item_class->set_canvas      = goo_canvas_widget_set_canvas;
+  item_class->set_parent      = goo_canvas_widget_set_parent;
+  item_class->allocate_area   = goo_canvas_widget_allocate_area;
+
   simple_class->simple_update        = goo_canvas_widget_update;
   simple_class->simple_paint         = goo_canvas_widget_paint;
   simple_class->simple_is_item_at    = goo_canvas_widget_is_item_at;



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