[cairo-commit] goocanvas/src Makefile.am, 1.10, 1.11 goocanvas.h, 1.2, 1.3 goocanvasatk.c, 1.6, 1.7 goocanvasatk.h, 1.1, 1.2 goocanvasellipse.c, 1.6, 1.7 goocanvasellipse.h, 1.2, 1.3 goocanvasgroup.c, 1.13, 1.14 goocanvasgroup.h, 1.8, 1.9 goocanvasimage.c, 1.7, 1.8 goocanvasimage.h, 1.2, 1.3 goocanvasimageview.c, 1.16, NONE goocanvasimageview.h, 1.4, NONE goocanvasitem.c, 1.10, 1.11 goocanvasitem.h, 1.7, 1.8 goocanvasitemsimple.c, 1.14, 1.15 goocanvasitemsimple.h, 1.10, 1.11 goocanvasitemview.c, 1.14, NONE goocanvasitemview.h, 1.12, NONE goocanvasitemviewsimple.c, 1.13, NONE goocanvasitemviewsimple.h, 1.5, NONE goocanvasmodel.c, 1.3, NONE goocanvasmodel.h, 1.2, NONE goocanvasmodelsimple.c, 1.5, NONE goocanvasmodelsimple.h, 1.2, NONE goocanvaspath.c, 1.7, 1.8 goocanvaspath.h, 1.5, 1.6 goocanvaspathview.c, 1.11, NONE goocanvaspathview.h, 1.4, NONE goocanvaspolyline.c, 1.6, 1.7 goocanvaspolyline.h, 1.4, 1.5 goocanvaspolylineview.c, 1.19, NONE goocanvaspolylineview.h, 1.5, NONE goocanvasrect.c, 1.6, 1.7 goocanvasrect.h, 1.2, 1.3 goocanvasrectview.c, 1.12, NONE goocanvasrectview.h, 1.4, NONE goocanvastext.c, 1.6, 1.7 goocanvastext.h, 1.3, 1.4 goocanvastextview.c, 1.19, NONE goocanvastextview.h, 1.5, NONE goocanvasview.c, 1.32, NONE goocanvasview.h, 1.11, NONE

Damon Chaplin commit at pdx.freedesktop.org
Wed Nov 29 10:40:57 PST 2006


Committed by: damon

Update of /cvs/cairo/goocanvas/src
In directory kemper:/tmp/cvs-serv14136/src

Modified Files:
	Makefile.am goocanvas.h goocanvasatk.c goocanvasatk.h 
	goocanvasellipse.c goocanvasellipse.h goocanvasgroup.c 
	goocanvasgroup.h goocanvasimage.c goocanvasimage.h 
	goocanvasitem.c goocanvasitem.h goocanvasitemsimple.c 
	goocanvasitemsimple.h goocanvaspath.c goocanvaspath.h 
	goocanvaspolyline.c goocanvaspolyline.h goocanvasrect.c 
	goocanvasrect.h goocanvastext.c goocanvastext.h 
Removed Files:
	goocanvasimageview.c goocanvasimageview.h goocanvasitemview.c 
	goocanvasitemview.h goocanvasitemviewsimple.c 
	goocanvasitemviewsimple.h goocanvasmodel.c goocanvasmodel.h 
	goocanvasmodelsimple.c goocanvasmodelsimple.h 
	goocanvaspathview.c goocanvaspathview.h 
	goocanvaspolylineview.c goocanvaspolylineview.h 
	goocanvasrectview.c goocanvasrectview.h goocanvastextview.c 
	goocanvastextview.h goocanvasview.c goocanvasview.h 
Log Message:
new optional model rewrite


Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/goocanvas/src/Makefile.am,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- Makefile.am	29 Nov 2006 16:35:38 -0000	1.10
+++ Makefile.am	29 Nov 2006 18:40:53 -0000	1.11
@@ -15,69 +15,52 @@
 
 libgoocanvasincludedir = $(includedir)/goocanvas-1.0
 
-libgoocanvas_public_headers =			\
-	goocanvasellipse.h			\
-	goocanvasellipseview.h			\
-	goocanvasgroup.h			\
-	goocanvasgroupview.h			\
-	goocanvasimage.h			\
-	goocanvasimageview.h			\
-	goocanvasitem.h				\
-	goocanvasitemsimple.h			\
-	goocanvasitemview.h			\
-	goocanvasitemviewsimple.h		\
-	goocanvasmodel.h			\
-	goocanvasmodelsimple.h			\
-	goocanvaspolyline.h			\
-	goocanvaspolylineview.h			\
-	goocanvaspath.h				\
-	goocanvaspathview.h			\
-	goocanvasrect.h				\
-	goocanvasrectview.h			\
-	goocanvastext.h				\
-	goocanvastextview.h			\
-	goocanvasutils.h			\
-	goocanvasview.h				\
+libgoocanvas_public_headers =		\
+	goocanvasellipse.h		\
+	goocanvasgroup.h		\
+	goocanvasimage.h		\
+	goocanvasitem.h			\
+	goocanvasitemmodel.h		\
+	goocanvasitemsimple.h		\
+	goocanvaspolyline.h		\
+	goocanvaspath.h			\
+	goocanvasrect.h			\
+	goocanvasstyle.h		\
+	goocanvastext.h			\
+	goocanvasutils.h		\
+	goocanvaswidget.h		\
 	goocanvas.h
 
-libgoocanvas_la_SOURCES =			\
-	goocanvasmarshal.list			\
-	goocanvasatk.h				\
-	goocanvasatk.c				\
-	goocanvasellipse.c			\
-	goocanvasellipseview.c			\
-	goocanvasenumtypes.c			\
-	goocanvasgroup.c			\
-	goocanvasgroupview.c			\
-	goocanvasimage.c			\
-	goocanvasimageview.c			\
-	goocanvasitem.c				\
-	goocanvasitemsimple.c			\
-	goocanvasitemview.c			\
-	goocanvasitemviewsimple.c		\
-	goocanvasmodel.c			\
-	goocanvasmodelsimple.c			\
-	goocanvaspolyline.c			\
-	goocanvaspolylineview.c			\
-	goocanvaspath.c				\
-	goocanvaspathview.c			\
-	goocanvasprivate.h			\
-	goocanvasrect.c				\
-	goocanvasrectview.c			\
-	goocanvastext.c				\
-	goocanvastextview.c			\
-	goocanvasutils.c			\
-	goocanvasview.c 
+libgoocanvas_la_SOURCES =		\
+	goocanvasmarshal.list		\
+	goocanvasatk.h			\
+	goocanvasatk.c			\
+	goocanvasellipse.c		\
+	goocanvasenumtypes.c		\
+	goocanvasgroup.c		\
+	goocanvasimage.c		\
+	goocanvasitem.c			\
+	goocanvasitemmodel.c		\
+	goocanvasitemsimple.c		\
+	goocanvaspolyline.c		\
+	goocanvaspath.c			\
+	goocanvasprivate.h		\
+	goocanvasrect.c			\
+	goocanvasstyle.c		\
+	goocanvastext.c			\
+	goocanvasutils.c		\
+	goocanvaswidget.c		\
+	goocanvas.c 
 
-libgoocanvas_built_headers =			\
-	goocanvasenumtypes.h			\
+libgoocanvas_built_headers =		\
+	goocanvasenumtypes.h		\
 	goocanvasmarshal.h
 
-libgoocanvas_built_sources =			\
+libgoocanvas_built_sources =		\
 	goocanvasenumtypes.c
 
-libgoocanvasinclude_HEADERS =			\
-	$(libgoocanvas_public_headers)		\
+libgoocanvasinclude_HEADERS =		\
+	$(libgoocanvas_public_headers)	\
 	$(libgoocanvas_built_headers)
 
 
@@ -118,3 +101,6 @@
 non-intermediate: goocanvasmarshal.c
 
 CLEANFILES = $(libgoocanvas_built_headers) $(libgoocanvas_built_sources)
+
+# Add this to the dist for use on Windows where glib-genmarshal may not work.
+EXTRA_DIST = goocanvasmarshal.c

Index: goocanvas.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvas.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- goocanvas.h	12 Oct 2006 12:53:47 -0000	1.2
+++ goocanvas.h	29 Nov 2006 18:40:53 -0000	1.3
@@ -1,33 +1,254 @@
 /*
- * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005 Damon Chaplin.
  * Released under the GNU LGPL license. See COPYING for details.
  *
- * goocanvas.h - includes all canvas header files.
+ * goocanvas.h - the main canvas widget.
  */
 #ifndef __GOO_CANVAS_H__
 #define __GOO_CANVAS_H__
 
-#include <goocanvasellipse.h>
-#include <goocanvasellipseview.h>
+#include <gtk/gtk.h>
 #include <goocanvasenumtypes.h>
+#include <goocanvasellipse.h>
 #include <goocanvasgroup.h>
-#include <goocanvasgroupview.h>
 #include <goocanvasimage.h>
-#include <goocanvasimageview.h>
-#include <goocanvasitem.h>
-#include <goocanvasitemsimple.h>
-#include <goocanvasitemview.h>
-#include <goocanvasmodel.h>
-#include <goocanvasmodelsimple.h>
-#include <goocanvaspolyline.h>
-#include <goocanvaspolylineview.h>
 #include <goocanvaspath.h>
-#include <goocanvaspathview.h>
+#include <goocanvaspolyline.h>
 #include <goocanvasrect.h>
-#include <goocanvasrectview.h>
 #include <goocanvastext.h>
-#include <goocanvastextview.h>
-#include <goocanvasutils.h>
-#include <goocanvasview.h>
+#include <goocanvaswidget.h>
+
+G_BEGIN_DECLS
+
+
+#define GOO_TYPE_CANVAS            (goo_canvas_get_type ())
+#define GOO_CANVAS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS, GooCanvas))
+#define GOO_CANVAS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS, GooCanvasClass))
+#define GOO_IS_CANVAS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS))
+#define GOO_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS))
+#define GOO_CANVAS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS, GooCanvasClass))
+
+
+typedef struct _GooCanvasClass  GooCanvasClass;
+
+/**
+ * GooCanvas
+ *
+ * The #GooCanvas-struct struct contains private data only.
+ */
+struct _GooCanvas
+{
+  GtkContainer container;
+
+  /* The model for the root item, in model/view mode. */
+  GooCanvasItemModel *root_item_model;
+
+  /* The root canvas item. */
+  GooCanvasItem *root_item;
+
+  /* The bounds of the canvas, in canvas units (not pixels). */
+  GooCanvasBounds bounds;
+
+  /* The scale/zoom factor of the canvas, in pixels per device unit. */
+  gdouble scale;
+
+  /* Where the canvas is anchored (where it is displayed when it is smaller
+     than the entire window). */
+  GtkAnchorType anchor;
+
+  /* Idle handler ID, for processing updates. */
+  guint idle_id;
+
+  /* This is TRUE if some item in the canvas needs an update. */
+  guint need_update : 1;
+
+  /* The item that the mouse is over. */
+  GooCanvasItem *pointer_item;
+
+  /* The item that has the pointer grab, or NULL. */
+  GooCanvasItem *pointer_grab_item;
+
+  /* This is the item that the grab was started from. When the grab ends
+     we synthesize enter/leave notify events from this item. */
+  GooCanvasItem *pointer_grab_initial_item;
+
+  /* This is the mouse button that started an implicit pointer grab.
+     When the same button is released the implicit grab ends. */
+  guint pointer_grab_button;
+
+  /* The item that has the keyboard focus, or NULL. */
+  GooCanvasItem *focused_item;
+
+  /* The item that has the keyboard grab, or NULL. */
+  GooCanvasItem *keyboard_grab_item;
+
+  /* The synthesized event used for sending enter-notify and leave-notify
+     events to items. */
+  GdkEventCrossing crossing_event;
+
+  /* The main canvas window, which gets scrolled around. */
+  GdkWindow *canvas_window;
+
+  /* The offsets of the canvas within the canvas window, in pixels. These are
+     used when the canvas is smaller than the window size and the anchor is not
+     NORTH_WEST. */
+  gint canvas_x_offset;
+  gint canvas_y_offset;
+
+  /* The adjustments used for scrolling. */
+  GtkAdjustment *hadjustment;
+  GtkAdjustment *vadjustment;
+
+  /* Freezes any movement of the canvas window, until thawed. This is used
+     when we need to set both adjustments and don't want it to scroll twice. */
+  gint freeze_count;
+
+  /* A window temporarily mapped above the canvas to stop X from scrolling
+     the contents unnecessarily (i.e. when we zoom in/out). */
+  GdkWindow *tmp_window;
+
+  /* A hash table mapping canvas item models to canvas items. */
+  GHashTable *model_to_item;
+
+  /* The units of the canvas, which applies to all item coords. */
+  GtkUnit units;
+
+  /* The horizontal and vertical resolution of the display, in dots per inch.
+     This is only needed when units other than pixels are used. */
+  gdouble resolution_x, resolution_y;
+
+  /* The multiplers to convert from device units to pixels, taking into account
+     the canvas scale, the units setting and the display resolution. */
+  gdouble scale_x, scale_y;
+
+  /* The list of child widgets (using GooCanvasWidget items). */
+  GList *widget_items;
+};
+
+struct _GooCanvasClass
+{
+  GtkContainerClass parent_class;
+
+  void		 (* set_scroll_adjustments) (GooCanvas          *canvas,
+					     GtkAdjustment      *hadjustment,
+					     GtkAdjustment      *vadjustment);
+
+  /* Virtual methods. */
+  GooCanvasItem* (* create_item)	    (GooCanvas          *canvas,
+					     GooCanvasItemModel *model);
+
+  /* Signals. */
+  void           (* item_created)	    (GooCanvas          *canvas,
+					     GooCanvasItem      *item,
+					     GooCanvasItemModel *model);
+};
+
+
+GType           goo_canvas_get_type	    (void) G_GNUC_CONST;
+GtkWidget*      goo_canvas_new		    (void);
+
+GooCanvasItem*  goo_canvas_get_root_item    (GooCanvas		*canvas);
+void            goo_canvas_set_root_item    (GooCanvas		*canvas,
+					     GooCanvasItem      *item);
+
+GooCanvasItemModel* goo_canvas_get_root_item_model (GooCanvas	       *canvas);
+void                goo_canvas_set_root_item_model (GooCanvas	       *canvas,
+						    GooCanvasItemModel *model);
+
+GooCanvasItem*  goo_canvas_get_item	    (GooCanvas		*canvas,
+					     GooCanvasItemModel *model);
+GooCanvasItem*  goo_canvas_get_item_at	    (GooCanvas		*canvas,
+					     gdouble             x,
+					     gdouble             y,
+					     gboolean            is_pointer_event);
+
+gdouble         goo_canvas_get_scale	    (GooCanvas		*canvas);
+void            goo_canvas_set_scale	    (GooCanvas		*canvas,
+					     gdouble             pixels_per_unit);
+
+void            goo_canvas_get_bounds	    (GooCanvas		*canvas,
+					     gdouble            *left,
+					     gdouble            *top,
+					     gdouble            *right,
+					     gdouble            *bottom);
+void            goo_canvas_set_bounds	    (GooCanvas		*canvas,
+					     gdouble             left,
+					     gdouble             top,
+					     gdouble             right,
+					     gdouble             bottom);
+
+void            goo_canvas_scroll_to	    (GooCanvas		*canvas,
+					     gdouble             left,
+					     gdouble             top);
+
+void            goo_canvas_grab_focus	    (GooCanvas		*canvas,
+					     GooCanvasItem	*item);
+
+void            goo_canvas_render	    (GooCanvas		*canvas,
+					     cairo_t            *cr,
+					     GooCanvasBounds    *bounds,
+					     gdouble             scale);
+
+/*
+ * Coordinate conversion.
+ */
+void		goo_canvas_convert_to_pixels	   (GooCanvas       *canvas,
+						    gdouble         *x,
+						    gdouble         *y);
+void		goo_canvas_convert_from_pixels	   (GooCanvas       *canvas,
+						    gdouble         *x,
+						    gdouble         *y);
+
+void		goo_canvas_convert_to_item_space   (GooCanvas	    *canvas,
+						    GooCanvasItem   *item,
+						    gdouble         *x,
+						    gdouble         *y);
+void		goo_canvas_convert_from_item_space (GooCanvas       *canvas,
+						    GooCanvasItem   *item,
+						    gdouble         *x,
+						    gdouble         *y);
+
+
+/*
+ * Pointer/keyboard grabbing & ungrabbing.
+ */
+GdkGrabStatus	goo_canvas_pointer_grab	    (GooCanvas		*canvas,
+					     GooCanvasItem	*item,
+					     GdkEventMask        event_mask,
+					     GdkCursor		*cursor,
+					     guint32             time);
+void		goo_canvas_pointer_ungrab   (GooCanvas		*canvas,
+					     GooCanvasItem	*item,
+					     guint32             time);
+GdkGrabStatus	goo_canvas_keyboard_grab    (GooCanvas		*canvas,
+					     GooCanvasItem	*item,
+					     gboolean            owner_events,
+					     guint32             time);
+void		goo_canvas_keyboard_ungrab  (GooCanvas		*canvas,
+					     GooCanvasItem	*item,
+					     guint32             time);
+
+
+/*
+ * Internal functions, mainly for canvas subclasses and item implementations.
+ */
+GooCanvasItem*	goo_canvas_create_item	    (GooCanvas          *canvas,
+					     GooCanvasItemModel *model);
+void		goo_canvas_unregister_item  (GooCanvas		*canvas,
+					     GooCanvasItemModel *model);
+void		goo_canvas_update	    (GooCanvas		*canvas);
+void		goo_canvas_request_update   (GooCanvas		*canvas);
+void		goo_canvas_request_redraw   (GooCanvas		*canvas,
+					     GooCanvasBounds	*bounds);
+gdouble         goo_canvas_get_default_line_width (GooCanvas    *canvas);
+
+
+void            goo_canvas_register_widget_item   (GooCanvas          *canvas,
+						   GooCanvasWidget    *witem);
+void            goo_canvas_unregister_widget_item (GooCanvas          *canvas,
+						   GooCanvasWidget    *witem);
+
+
+G_END_DECLS
 
 #endif /* __GOO_CANVAS_H__ */

Index: goocanvasatk.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasatk.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvasatk.c	19 Jul 2006 15:49:47 -0000	1.6
+++ goocanvasatk.c	29 Nov 2006 18:40:53 -0000	1.7
@@ -14,51 +14,51 @@
 
 
 /*
- * GooCanvasItemViewAccessible.
+ * GooCanvasItemAccessible.
  */
 
-typedef AtkGObjectAccessible      GooCanvasItemViewAccessible;
-typedef AtkGObjectAccessibleClass GooCanvasItemViewAccessibleClass;
+typedef AtkGObjectAccessible      GooCanvasItemAccessible;
+typedef AtkGObjectAccessibleClass GooCanvasItemAccessibleClass;
 
-#define GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), goo_canvas_item_view_accessible_get_type ()))
+#define GOO_IS_CANVAS_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), goo_canvas_item_accessible_get_type ()))
 
-static void goo_canvas_item_view_accessible_component_interface_init (AtkComponentIface *iface);
-static gint goo_canvas_item_view_accessible_get_index_in_parent (AtkObject *accessible);
+static void goo_canvas_item_accessible_component_interface_init (AtkComponentIface *iface);
+static gint goo_canvas_item_accessible_get_index_in_parent (AtkObject *accessible);
 
-G_DEFINE_TYPE_WITH_CODE (GooCanvasItemViewAccessible,
-			 goo_canvas_item_view_accessible,
+G_DEFINE_TYPE_WITH_CODE (GooCanvasItemAccessible,
+			 goo_canvas_item_accessible,
 			 ATK_TYPE_GOBJECT_ACCESSIBLE,
-			 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, goo_canvas_item_view_accessible_component_interface_init))
+			 G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, goo_canvas_item_accessible_component_interface_init))
 
 
-/* Returns the extents of the item view, in pixels relative to the main
+/* Returns the extents of the item, in pixels relative to the main
    canvas window. */
 static void
-goo_canvas_item_view_accessible_get_item_extents (GooCanvasItemView *view,
-						  GdkRectangle      *rect)
+goo_canvas_item_accessible_get_item_extents (GooCanvasItem *item,
+					     GdkRectangle  *rect)
 {
-  GooCanvasView *canvas_view;
+  GooCanvas *canvas;
   GooCanvasBounds bounds;
 
-  canvas_view = goo_canvas_item_view_get_canvas_view (view);
-  if (!canvas_view)
+  canvas = goo_canvas_item_get_canvas (item);
+  if (!canvas)
     {
       rect->x = rect->y = rect->width = rect->height = 0;
       return;
     }
 
   /* Get the bounds in device units. */
-  goo_canvas_item_view_get_bounds (view, &bounds);
+  goo_canvas_item_get_bounds (item, &bounds);
 
   /* Convert to pixels within the entire canvas. */
-  goo_canvas_view_convert_to_pixels (canvas_view, &bounds.x1, &bounds.y1);
-  goo_canvas_view_convert_to_pixels (canvas_view, &bounds.x2, &bounds.y2);
+  goo_canvas_convert_to_pixels (canvas, &bounds.x1, &bounds.y1);
+  goo_canvas_convert_to_pixels (canvas, &bounds.x2, &bounds.y2);
 
   /* Convert to pixels within the visible window. */
-  bounds.x1 -= canvas_view->hadjustment->value;
-  bounds.y1 -= canvas_view->vadjustment->value;
-  bounds.x2 -= canvas_view->hadjustment->value;
-  bounds.y2 -= canvas_view->vadjustment->value;
+  bounds.x1 -= canvas->hadjustment->value;
+  bounds.y1 -= canvas->vadjustment->value;
+  bounds.x2 -= canvas->hadjustment->value;
+  bounds.y2 -= canvas->vadjustment->value;
 
   /* Round up or down to integers. */
   rect->x = floor (bounds.x1);
@@ -71,12 +71,12 @@
 /* This returns TRUE if the given rectangle intersects the canvas window.
    The rectangle should be in pixels relative to the main canvas window. */
 static gboolean
-goo_canvas_item_view_accessible_is_item_in_window (GooCanvasItemView *view,
-						   GdkRectangle      *rect)
+goo_canvas_item_accessible_is_item_in_window (GooCanvasItem *item,
+					      GdkRectangle  *rect)
 {
   GtkWidget *widget;
 
-  widget = (GtkWidget*) goo_canvas_item_view_get_canvas_view (view);
+  widget = (GtkWidget*) goo_canvas_item_get_canvas (item);
   if (!widget)
     return FALSE;
 
@@ -89,33 +89,33 @@
 
 
 static gboolean
-goo_canvas_item_view_accessible_is_item_on_screen (GooCanvasItemView *view)
+goo_canvas_item_accessible_is_item_on_screen (GooCanvasItem *item)
 {
   GdkRectangle rect;
 
-  goo_canvas_item_view_accessible_get_item_extents (view, &rect);
-  return goo_canvas_item_view_accessible_is_item_in_window (view, &rect);
+  goo_canvas_item_accessible_get_item_extents (item, &rect);
+  return goo_canvas_item_accessible_is_item_in_window (item, &rect);
 }
 
 
 
 static void
-goo_canvas_item_view_accessible_get_extents (AtkComponent *component,
-					     gint         *x,
-					     gint         *y,
-					     gint         *width,
-					     gint         *height,
-					     AtkCoordType coord_type)
+goo_canvas_item_accessible_get_extents (AtkComponent *component,
+					gint         *x,
+					gint         *y,
+					gint         *width,
+					gint         *height,
+					AtkCoordType  coord_type)
 {
-  GooCanvasItemView *item_view;
-  GooCanvasView *canvas_view;
+  GooCanvasItem *item;
+  GooCanvas *canvas;
   GObject *object;
   gint window_x, window_y;
   gint toplevel_x, toplevel_y;
   GdkRectangle rect;
   GdkWindow *window;
 
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (component));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (component));
 
   *x = *y = G_MININT;
 
@@ -123,27 +123,27 @@
   if (!object)
     return;
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
+  item = GOO_CANVAS_ITEM (object);
 
-  canvas_view = goo_canvas_item_view_get_canvas_view (item_view);
-  if (!canvas_view || !GTK_WIDGET (canvas_view)->window)
+  canvas = goo_canvas_item_get_canvas (item);
+  if (!canvas || !GTK_WIDGET (canvas)->window)
     return;
 
-  goo_canvas_item_view_accessible_get_item_extents (item_view, &rect);
+  goo_canvas_item_accessible_get_item_extents (item, &rect);
   *width = rect.width;
   *height = rect.height;
 
-  if (!goo_canvas_item_view_accessible_is_item_in_window (item_view, &rect))
+  if (!goo_canvas_item_accessible_is_item_in_window (item, &rect))
     return;
 
-  gdk_window_get_origin (GTK_WIDGET (canvas_view)->window,
+  gdk_window_get_origin (GTK_WIDGET (canvas)->window,
 			 &window_x, &window_y);
   *x = rect.x + window_x;
   *y = rect.y + window_y;
 
   if (coord_type == ATK_XY_WINDOW)
     {
-      window = gdk_window_get_toplevel (GTK_WIDGET (canvas_view)->window);
+      window = gdk_window_get_toplevel (GTK_WIDGET (canvas)->window);
       gdk_window_get_origin (window, &toplevel_x, &toplevel_y);
       *x -= toplevel_x;
       *y -= toplevel_y;
@@ -152,23 +152,23 @@
 
 
 static gint
-goo_canvas_item_view_accessible_get_mdi_zorder (AtkComponent *component)
+goo_canvas_item_accessible_get_mdi_zorder (AtkComponent *component)
 {
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (component), -1);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (component), -1);
 
-  return goo_canvas_item_view_accessible_get_index_in_parent (ATK_OBJECT (component));
+  return goo_canvas_item_accessible_get_index_in_parent (ATK_OBJECT (component));
 }
 
 
 static guint
-goo_canvas_item_view_accessible_add_focus_handler (AtkComponent    *component,
-						   AtkFocusHandler  handler)
+goo_canvas_item_accessible_add_focus_handler (AtkComponent    *component,
+					      AtkFocusHandler  handler)
 {
   GSignalMatchType match_type;
   GClosure *closure;
   guint signal_id;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (component), 0);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (component), 0);
 
   match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
   signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
@@ -185,38 +185,38 @@
 
 
 static void
-goo_canvas_item_view_accessible_remove_focus_handler (AtkComponent *component,
-						      guint         handler_id)
+goo_canvas_item_accessible_remove_focus_handler (AtkComponent *component,
+						 guint         handler_id)
 {
-  g_return_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (component));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (component));
 
   g_signal_handler_disconnect (ATK_OBJECT (component), handler_id);
 }
 
 
 static gboolean
-goo_canvas_item_view_accessible_grab_focus (AtkComponent    *component)
+goo_canvas_item_accessible_grab_focus (AtkComponent    *component)
 {
-  GooCanvasItemView *item_view;
-  GooCanvasView *canvas_view;
+  GooCanvasItem *item;
+  GooCanvas *canvas;
   GtkWidget *toplevel;
   GObject *object;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (component), FALSE);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (component), FALSE);
 
   object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component));
   if (!object)
     return FALSE;
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
+  item = GOO_CANVAS_ITEM (object);
 
-  canvas_view = goo_canvas_item_view_get_canvas_view (item_view);
-  if (!canvas_view)
+  canvas = goo_canvas_item_get_canvas (item);
+  if (!canvas)
     return FALSE;
 
-  goo_canvas_view_grab_focus (canvas_view, item_view);
+  goo_canvas_grab_focus (canvas, item);
 
-  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (canvas_view));
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (canvas));
   if (GTK_WIDGET_TOPLEVEL (toplevel))
     gtk_window_present (GTK_WINDOW (toplevel));
 
@@ -225,22 +225,24 @@
 
 
 static void
-goo_canvas_item_view_accessible_component_interface_init (AtkComponentIface *iface)
+goo_canvas_item_accessible_component_interface_init (AtkComponentIface *iface)
 {
-  iface->get_extents          = goo_canvas_item_view_accessible_get_extents;
-  iface->get_mdi_zorder       = goo_canvas_item_view_accessible_get_mdi_zorder;
-  iface->add_focus_handler    = goo_canvas_item_view_accessible_add_focus_handler;
-  iface->remove_focus_handler = goo_canvas_item_view_accessible_remove_focus_handler;
-  iface->grab_focus           = goo_canvas_item_view_accessible_grab_focus;
+  iface->get_extents          = goo_canvas_item_accessible_get_extents;
+  iface->get_mdi_zorder       = goo_canvas_item_accessible_get_mdi_zorder;
+  iface->add_focus_handler    = goo_canvas_item_accessible_add_focus_handler;
+  iface->remove_focus_handler = goo_canvas_item_accessible_remove_focus_handler;
+  iface->grab_focus           = goo_canvas_item_accessible_grab_focus;
 }
 
 
 static void
-goo_canvas_item_view_accessible_initialize (AtkObject *object,
-					    gpointer   data)
+goo_canvas_item_accessible_initialize (AtkObject *object,
+				       gpointer   data)
 {
-  if (ATK_OBJECT_CLASS (goo_canvas_item_view_accessible_parent_class)->initialize)
-    ATK_OBJECT_CLASS (goo_canvas_item_view_accessible_parent_class)->initialize (object, data);
+  if (ATK_OBJECT_CLASS (goo_canvas_item_accessible_parent_class)->initialize)
+    ATK_OBJECT_CLASS (goo_canvas_item_accessible_parent_class)->initialize (object, data);
+
+  object->role = ATK_ROLE_UNKNOWN;
 
   /* FIXME: Maybe this should be ATK_LAYER_CANVAS. */
   g_object_set_data (G_OBJECT (object), "atk-component-layer",
@@ -249,13 +251,13 @@
 
 
 static AtkObject*
-goo_canvas_item_view_accessible_get_parent (AtkObject *accessible)
+goo_canvas_item_accessible_get_parent (AtkObject *accessible)
 {
-  GooCanvasItemView *item_view, *parent_view;
-  GooCanvasView *canvas_view;
+  GooCanvasItem *item, *parent;
+  GooCanvas *canvas;
   GObject *object;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (accessible), NULL);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), NULL);
 
   if (accessible->accessible_parent)
     return accessible->accessible_parent;
@@ -264,28 +266,28 @@
   if (object == NULL)
     return NULL;
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
-  parent_view = goo_canvas_item_view_get_parent_view (item_view);
+  item = GOO_CANVAS_ITEM (object);
+  parent = goo_canvas_item_get_parent (item);
 
-  if (parent_view)
-    return atk_gobject_accessible_for_object (G_OBJECT (parent_view));
+  if (parent)
+    return atk_gobject_accessible_for_object (G_OBJECT (parent));
 
-  canvas_view = goo_canvas_item_view_get_canvas_view (item_view);
-  if (canvas_view)
-    return gtk_widget_get_accessible (GTK_WIDGET (canvas_view));
+  canvas = goo_canvas_item_get_canvas (item);
+  if (canvas)
+    return gtk_widget_get_accessible (GTK_WIDGET (canvas));
 
   return NULL;
 }
 
 
 static gint
-goo_canvas_item_view_accessible_get_index_in_parent (AtkObject *accessible)
+goo_canvas_item_accessible_get_index_in_parent (AtkObject *accessible)
 {
-  GooCanvasItemView *item_view, *parent_view;
-  GooCanvasView *canvas_view;
+  GooCanvasItem *item, *parent;
+  GooCanvas *canvas;
   GObject *object;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (accessible), -1);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), -1);
 
   if (accessible->accessible_parent)
     {
@@ -312,14 +314,14 @@
   if (object == NULL)
     return -1;
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
-  parent_view = goo_canvas_item_view_get_parent_view (item_view);
+  item = GOO_CANVAS_ITEM (object);
+  parent = goo_canvas_item_get_parent (item);
 
-  if (parent_view)
-    return goo_canvas_item_view_find_child (parent_view, item_view);
+  if (parent)
+    return goo_canvas_item_find_child (parent, item);
 
-  canvas_view = goo_canvas_item_view_get_canvas_view (item_view);
-  if (canvas_view)
+  canvas = goo_canvas_item_get_canvas (item);
+  if (canvas)
     return 0;
 
   return -1;
@@ -327,44 +329,44 @@
 
 
 static gint
-goo_canvas_item_view_accessible_get_n_children (AtkObject *accessible)
+goo_canvas_item_accessible_get_n_children (AtkObject *accessible)
 {
-  GooCanvasItemView *item_view;
+  GooCanvasItem *item;
   GObject *object;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (accessible), -1);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), 0);
 
   object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
   if (object == NULL)
-    return -1;
+    return 0;
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
+  item = GOO_CANVAS_ITEM (object);
 
-  return goo_canvas_item_view_get_n_children (item_view);
+  return goo_canvas_item_get_n_children (item);
 }
 
 
 static AtkObject*
-goo_canvas_item_view_accessible_ref_child (AtkObject *accessible,
-					   gint       child_num)
+goo_canvas_item_accessible_ref_child (AtkObject *accessible,
+				      gint       child_num)
 {
-  GooCanvasItemView *item_view, *child_view;
+  GooCanvasItem *item, *child;
   AtkObject *atk_object;
   GObject *object;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (accessible), NULL);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), NULL);
 
   object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
   if (object == NULL)
     return NULL;
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
+  item = GOO_CANVAS_ITEM (object);
 
-  child_view = goo_canvas_item_view_get_child (item_view, child_num);
-  if (!child_view)
+  child = goo_canvas_item_get_child (item, child_num);
+  if (!child)
     return NULL;
 
-  atk_object = atk_gobject_accessible_for_object (G_OBJECT (child_view));
+  atk_object = atk_gobject_accessible_for_object (G_OBJECT (child));
   g_object_ref (atk_object);
 
   return atk_object;
@@ -372,17 +374,17 @@
 
 
 static AtkStateSet*
-goo_canvas_item_view_accessible_ref_state_set (AtkObject *accessible)
+goo_canvas_item_accessible_ref_state_set (AtkObject *accessible)
 {
-  GooCanvasItemView *item_view;
-  GooCanvasView *canvas_view;
+  GooCanvasItem *item;
+  GooCanvas *canvas;
   AtkStateSet *state_set;
   GObject *object;
   gboolean can_focus = FALSE;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW_ACCESSIBLE (accessible), NULL);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_ACCESSIBLE (accessible), NULL);
 
-  state_set = ATK_OBJECT_CLASS (goo_canvas_item_view_accessible_parent_class)->ref_state_set (accessible);
+  state_set = ATK_OBJECT_CLASS (goo_canvas_item_accessible_parent_class)->ref_state_set (accessible);
 
   object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
   if (!object)
@@ -391,28 +393,28 @@
       return state_set;
     }
 
-  item_view = GOO_CANVAS_ITEM_VIEW (object);
+  item = GOO_CANVAS_ITEM (object);
 
-  canvas_view = goo_canvas_item_view_get_canvas_view (item_view);
-  if (!canvas_view)
+  canvas = goo_canvas_item_get_canvas (item);
+  if (!canvas)
     return state_set;
 
-  if (goo_canvas_item_view_is_visible (item_view))
+  if (goo_canvas_item_is_visible (item))
     {
       atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
 
-      if (goo_canvas_item_view_accessible_is_item_on_screen (item_view))
+      if (goo_canvas_item_accessible_is_item_on_screen (item))
 	atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
     }
 
-  g_object_get (item_view, "can-focus", &can_focus, NULL);
+  g_object_get (item, "can-focus", &can_focus, NULL);
 
-  if (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (canvas_view)) && can_focus)
+  if (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (canvas)) && can_focus)
     {
       atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
 
-      if (GTK_WIDGET_HAS_FOCUS (canvas_view)
-	  && canvas_view->focused_item_view == item_view)
+      if (GTK_WIDGET_HAS_FOCUS (canvas)
+	  && canvas->focused_item == item)
 	atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
     }
 
@@ -421,34 +423,33 @@
 
 
 static void
-goo_canvas_item_view_accessible_class_init (GooCanvasItemViewAccessibleClass *klass)
+goo_canvas_item_accessible_class_init (GooCanvasItemAccessibleClass *klass)
 {
   AtkObjectClass *aklass = (AtkObjectClass*) klass;
 
-  aklass->initialize          = goo_canvas_item_view_accessible_initialize;
-  aklass->get_parent          = goo_canvas_item_view_accessible_get_parent;
-  aklass->get_index_in_parent = goo_canvas_item_view_accessible_get_index_in_parent;
-  aklass->get_n_children      = goo_canvas_item_view_accessible_get_n_children;
-  aklass->ref_child           = goo_canvas_item_view_accessible_ref_child;
-  aklass->ref_state_set       = goo_canvas_item_view_accessible_ref_state_set;
+  aklass->initialize          = goo_canvas_item_accessible_initialize;
+  aklass->get_parent          = goo_canvas_item_accessible_get_parent;
+  aklass->get_index_in_parent = goo_canvas_item_accessible_get_index_in_parent;
+  aklass->get_n_children      = goo_canvas_item_accessible_get_n_children;
+  aklass->ref_child           = goo_canvas_item_accessible_ref_child;
+  aklass->ref_state_set       = goo_canvas_item_accessible_ref_state_set;
 }
 
 
 static void
-goo_canvas_item_view_accessible_init (GooCanvasItemViewAccessible *accessible)
+goo_canvas_item_accessible_init (GooCanvasItemAccessible *accessible)
 {
 }
 
 
 static AtkObject *
-goo_canvas_item_view_accessible_new (GObject *object)
+goo_canvas_item_accessible_new (GObject *object)
 {
   AtkObject *accessible;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_ITEM_VIEW (object), NULL);
+  g_return_val_if_fail (GOO_IS_CANVAS_ITEM (object), NULL);
 
-  accessible = g_object_new (goo_canvas_item_view_accessible_get_type (),
-			     NULL);
+  accessible = g_object_new (goo_canvas_item_accessible_get_type (), NULL);
   atk_object_initialize (accessible, object);
 
   return accessible;
@@ -456,40 +457,167 @@
 
 
 /*
- * GooCanvasItemViewAccessibleFactory.
+ * GooCanvasItemAccessibleFactory.
  */
 
-typedef AtkObjectFactory      GooCanvasItemViewAccessibleFactory;
-typedef AtkObjectFactoryClass GooCanvasItemViewAccessibleFactoryClass;
+typedef AtkObjectFactory      GooCanvasItemAccessibleFactory;
+typedef AtkObjectFactoryClass GooCanvasItemAccessibleFactoryClass;
 
-G_DEFINE_TYPE (GooCanvasItemViewAccessibleFactory,
-	       goo_canvas_item_view_accessible_factory,
+G_DEFINE_TYPE (GooCanvasItemAccessibleFactory,
+	       goo_canvas_item_accessible_factory,
 	       ATK_TYPE_OBJECT_FACTORY)
 
 static void
-goo_canvas_item_view_accessible_factory_class_init (GooCanvasItemViewAccessibleFactoryClass *klass)
+goo_canvas_item_accessible_factory_class_init (GooCanvasItemAccessibleFactoryClass *klass)
 {
-  klass->create_accessible   = goo_canvas_item_view_accessible_new;
-  klass->get_accessible_type = goo_canvas_item_view_accessible_get_type;
+  klass->create_accessible   = goo_canvas_item_accessible_new;
+  klass->get_accessible_type = goo_canvas_item_accessible_get_type;
 }
 
 static void
-goo_canvas_item_view_accessible_factory_init (GooCanvasItemViewAccessibleFactory *factory)
+goo_canvas_item_accessible_factory_init (GooCanvasItemAccessibleFactory *factory)
 {
 }
 
 
 
 /*
- * GooCanvasViewAccessible.
+ * GooCanvasWidgetAccessible.
+ */
+
+typedef AtkGObjectAccessible      GooCanvasWidgetAccessible;
+typedef AtkGObjectAccessibleClass GooCanvasWidgetAccessibleClass;
+
+#define GOO_IS_CANVAS_WIDGET_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), goo_canvas_widget_accessible_get_type ()))
+
+G_DEFINE_TYPE (GooCanvasWidgetAccessible, goo_canvas_widget_accessible,
+	       GOO_TYPE_CANVAS_ITEM)
+
+
+static void
+goo_canvas_widget_accessible_initialize (AtkObject *object,
+					 gpointer   data)
+{
+  if (ATK_OBJECT_CLASS (goo_canvas_widget_accessible_parent_class)->initialize)
+    ATK_OBJECT_CLASS (goo_canvas_widget_accessible_parent_class)->initialize (object, data);
+
+  object->role = ATK_ROLE_PANEL;
+}
+
+
+static gint 
+goo_canvas_widget_accessible_get_n_children (AtkObject *accessible)
+{
+  GooCanvasWidget *witem;
+  GObject *object;
+
+  g_return_val_if_fail (GOO_IS_CANVAS_WIDGET_ACCESSIBLE (accessible), 0);
+
+  object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
+  if (object == NULL)
+    return 0;
+
+  witem = GOO_CANVAS_WIDGET (object);
+
+  return witem->widget ? 1 : 0;
+}
+
+static AtkObject *
+goo_canvas_widget_accessible_ref_child (AtkObject *accessible,
+					gint       child_num)
+{
+  GooCanvasWidget *witem;
+  AtkObject *atk_object;
+  GObject *object;
+
+  g_return_val_if_fail (GOO_IS_CANVAS_WIDGET_ACCESSIBLE (accessible), NULL);
+
+  if (child_num != 0)
+    return NULL;
+
+  object = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
+  if (object == NULL)
+    return NULL;
+
+  g_return_val_if_fail (GOO_IS_CANVAS_WIDGET (object), NULL);
+
+  witem = GOO_CANVAS_WIDGET (object);
+
+  if (!witem->widget)
+    return NULL;
+
+  atk_object = gtk_widget_get_accessible (witem->widget);
+  g_object_ref (atk_object);
+
+  return atk_object;
+}
+
+
+static void
+goo_canvas_widget_accessible_class_init (GooCanvasWidgetAccessibleClass *klass)
+{
+  AtkObjectClass *aklass = (AtkObjectClass*) klass;
+
+  aklass->initialize     = goo_canvas_widget_accessible_initialize;
+  aklass->get_n_children = goo_canvas_widget_accessible_get_n_children;
+  aklass->ref_child      = goo_canvas_widget_accessible_ref_child;
+}
+
+
+static void
+goo_canvas_widget_accessible_init (GooCanvasWidgetAccessible *accessible)
+{
+}
+
+
+AtkObject*
+goo_canvas_widget_accessible_new (GObject *object)
+{
+  AtkObject *accessible;
+
+  g_return_val_if_fail (GOO_IS_CANVAS_WIDGET (object), NULL);
+
+  accessible = g_object_new (goo_canvas_widget_accessible_get_type (), NULL);
+  atk_object_initialize (accessible, object);
+
+  return accessible;
+}
+
+
+/*
+ * GooCanvasWidgetAccessibleFactory.
+ */
+
+typedef AtkObjectFactory      GooCanvasWidgetAccessibleFactory;
+typedef AtkObjectFactoryClass GooCanvasWidgetAccessibleFactoryClass;
+
+G_DEFINE_TYPE (GooCanvasWidgetAccessibleFactory,
+	       goo_canvas_widget_accessible_factory,
+	       ATK_TYPE_OBJECT_FACTORY)
+
+static void
+goo_canvas_widget_accessible_factory_class_init (GooCanvasWidgetAccessibleFactoryClass *klass)
+{
+  klass->create_accessible   = goo_canvas_widget_accessible_new;
+  klass->get_accessible_type = goo_canvas_widget_accessible_get_type;
+}
+
+static void
+goo_canvas_widget_accessible_factory_init (GooCanvasWidgetAccessibleFactory *factory)
+{
+}
+
+
+/*
+ * GooCanvasAccessible.
  */
 
 static gpointer accessible_parent_class = NULL;
 
 
 static void
-goo_canvas_view_accessible_initialize (AtkObject *object, 
-				       gpointer   data)
+goo_canvas_accessible_initialize (AtkObject *object, 
+				  gpointer   data)
 {
   if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize) 
     ATK_OBJECT_CLASS (accessible_parent_class)->initialize (object, data);
@@ -500,13 +628,10 @@
 
 
 static gint
-goo_canvas_view_accessible_get_n_children (AtkObject *object)
+goo_canvas_accessible_get_n_children (AtkObject *object)
 {
   GtkAccessible *accessible;
   GtkWidget *widget;
-  GooCanvasView *canvas_view;
-  GooCanvasModel *model;
-  GooCanvasItem *root;
 
   accessible = GTK_ACCESSIBLE (object);
   widget = accessible->widget;
@@ -515,29 +640,20 @@
   if (widget == NULL)
     return 0;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_VIEW (widget), 0);
-
-  canvas_view = GOO_CANVAS_VIEW (widget);
-
-  model = goo_canvas_view_get_model (canvas_view);
-  if (!model)
-    return 0;
+  g_return_val_if_fail (GOO_IS_CANVAS (widget), 0);
 
-  root = goo_canvas_model_get_root_item (model);
-  if (!root)
-    return 0;
+  if (goo_canvas_get_root_item (GOO_CANVAS (widget)))
+    return 1;
 
-  return 1;
+  return 0;
 }
 
 static AtkObject*
-goo_canvas_view_accessible_ref_child (AtkObject *object,
-				      gint       child_num)
+goo_canvas_accessible_ref_child (AtkObject *object,
+				 gint       child_num)
 {
   GtkAccessible *accessible;
   GtkWidget *widget;
-  GooCanvasView *canvas_view;
-  GooCanvasModel *model;
   GooCanvasItem *root;
   AtkObject *atk_object;
 
@@ -552,12 +668,7 @@
   if (widget == NULL)
     return NULL;
 
-  canvas_view = GOO_CANVAS_VIEW (widget);
-  model = goo_canvas_view_get_model (canvas_view);
-  if (!model)
-    return NULL;
-
-  root = goo_canvas_model_get_root_item (model);
+  root = goo_canvas_get_root_item (GOO_CANVAS (widget));
   if (!root)
     return NULL;
 
@@ -570,18 +681,18 @@
 
 
 static void
-goo_canvas_view_accessible_class_init (AtkObjectClass *klass)
+goo_canvas_accessible_class_init (AtkObjectClass *klass)
 {
   accessible_parent_class = g_type_class_peek_parent (klass);
 
-  klass->initialize     = goo_canvas_view_accessible_initialize;
-  klass->get_n_children = goo_canvas_view_accessible_get_n_children;
-  klass->ref_child      = goo_canvas_view_accessible_ref_child;
+  klass->initialize     = goo_canvas_accessible_initialize;
+  klass->get_n_children = goo_canvas_accessible_get_n_children;
+  klass->ref_child      = goo_canvas_accessible_ref_child;
 }
 
 
 static GType
-goo_canvas_view_accessible_get_type (void)
+goo_canvas_accessible_get_type (void)
 {
   static GType g_define_type_id = 0;
 
@@ -604,11 +715,11 @@
 	return G_TYPE_INVALID;
 
       g_type_query (parent_atk_type, &query);
-      tinfo.class_init = (GClassInitFunc) goo_canvas_view_accessible_class_init;
+      tinfo.class_init = (GClassInitFunc) goo_canvas_accessible_class_init;
       tinfo.class_size = query.class_size;
       tinfo.instance_size = query.instance_size;
       g_define_type_id = g_type_register_static (parent_atk_type,
-						 "GooCanvasViewAccessible",
+						 "GooCanvasAccessible",
 						 &tinfo, 0);
     }
 
@@ -617,13 +728,13 @@
 
 
 static AtkObject *
-goo_canvas_view_accessible_new (GObject *object)
+goo_canvas_accessible_new (GObject *object)
 {
   AtkObject *accessible;
 
-  g_return_val_if_fail (GOO_IS_CANVAS_VIEW (object), NULL);
+  g_return_val_if_fail (GOO_IS_CANVAS (object), NULL);
 
-  accessible = g_object_new (goo_canvas_view_accessible_get_type (), NULL);
+  accessible = g_object_new (goo_canvas_accessible_get_type (), NULL);
   atk_object_initialize (accessible, object);
 
   return accessible;
@@ -631,24 +742,24 @@
 
 
 /*
- * GooCanvasViewAccessibleFactory.
+ * GooCanvasAccessibleFactory.
  */
 
-typedef AtkObjectFactory      GooCanvasViewAccessibleFactory;
-typedef AtkObjectFactoryClass GooCanvasViewAccessibleFactoryClass;
+typedef AtkObjectFactory      GooCanvasAccessibleFactory;
+typedef AtkObjectFactoryClass GooCanvasAccessibleFactoryClass;
 
-G_DEFINE_TYPE (GooCanvasViewAccessibleFactory,
-	       goo_canvas_view_accessible_factory,
+G_DEFINE_TYPE (GooCanvasAccessibleFactory,
+	       goo_canvas_accessible_factory,
 	       ATK_TYPE_OBJECT_FACTORY)
 
 static void
-goo_canvas_view_accessible_factory_class_init (GooCanvasViewAccessibleFactoryClass *klass)
+goo_canvas_accessible_factory_class_init (GooCanvasAccessibleFactoryClass *klass)
 {
-  klass->create_accessible   = goo_canvas_view_accessible_new;
-  klass->get_accessible_type = goo_canvas_view_accessible_get_type;
+  klass->create_accessible   = goo_canvas_accessible_new;
+  klass->get_accessible_type = goo_canvas_accessible_get_type;
 }
 
 static void
-goo_canvas_view_accessible_factory_init (GooCanvasViewAccessibleFactory *factory)
+goo_canvas_accessible_factory_init (GooCanvasAccessibleFactory *factory)
 {
 }

Index: goocanvasatk.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasatk.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- goocanvasatk.h	18 Apr 2006 15:43:07 -0000	1.1
+++ goocanvasatk.h	29 Nov 2006 18:40:53 -0000	1.2
@@ -12,8 +12,9 @@
 
 G_BEGIN_DECLS
 
-GType    goo_canvas_view_accessible_factory_get_type  (void) G_GNUC_CONST;
-GType    goo_canvas_item_view_accessible_factory_get_type  (void) G_GNUC_CONST;
+GType    goo_canvas_accessible_factory_get_type  (void) G_GNUC_CONST;
+GType    goo_canvas_item_accessible_factory_get_type  (void) G_GNUC_CONST;
+GType    goo_canvas_widget_accessible_factory_get_type  (void) G_GNUC_CONST;
 
 
 G_END_DECLS

Index: goocanvasellipse.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasellipse.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvasellipse.c	24 Aug 2006 08:06:23 -0000	1.6
+++ goocanvasellipse.c	29 Nov 2006 18:40:53 -0000	1.7
@@ -25,15 +25,14 @@
  * g_object_get() and g_object_set().
  *
  * To respond to events such as mouse clicks on the ellipse you must connect
- * to the signal handlers of the corresponding #GooCanvasEllipseView objects.
- * (See goo_canvas_view_get_item_view() and #GooCanvasView::item-view-created.)
+ * to the signal handlers of the corresponding #GooCanvasEllipse objects.
+ * (See goo_canvas_get_item_view() and #GooCanvas::item-view-created.)
  */
 #include <config.h>
 #include <math.h>
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 #include "goocanvasellipse.h"
-#include "goocanvasellipseview.h"
 
 
 enum {
@@ -46,30 +45,28 @@
 };
 
 
-static void item_interface_init (GooCanvasItemIface *iface);
-static void goo_canvas_ellipse_get_property (GObject            *object,
-					     guint               param_id,
-					     GValue             *value,
-					     GParamSpec         *pspec);
-static void goo_canvas_ellipse_set_property (GObject            *object,
-					     guint               param_id,
-					     const GValue       *value,
-					     GParamSpec         *pspec);
+static void canvas_item_interface_init      (GooCanvasItemIface  *iface);
+static void goo_canvas_ellipse_finalize     (GObject             *object);
+static void goo_canvas_ellipse_get_property (GObject             *object,
+					     guint                param_id,
+					     GValue              *value,
+					     GParamSpec          *pspec);
+static void goo_canvas_ellipse_set_property (GObject             *object,
+					     guint                param_id,
+					     const GValue        *value,
+					     GParamSpec          *pspec);
+static void goo_canvas_ellipse_create_path  (GooCanvasItemSimple *simple,
+					     cairo_t             *cr);
 
 G_DEFINE_TYPE_WITH_CODE (GooCanvasEllipse, goo_canvas_ellipse,
 			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						item_interface_init))
+						canvas_item_interface_init))
 
 
 static void
-goo_canvas_ellipse_class_init (GooCanvasEllipseClass *klass)
+goo_canvas_ellipse_install_common_properties (GObjectClass *gobject_class)
 {
-  GObjectClass *gobject_class = (GObjectClass*) klass;
-
-  gobject_class->get_property = goo_canvas_ellipse_get_property;
-  gobject_class->set_property = goo_canvas_ellipse_set_property;
-
   g_object_class_install_property (gobject_class, PROP_CENTER_X,
 				   g_param_spec_double ("center-x",
 							_("Center X"),
@@ -103,9 +100,26 @@
 
 
 static void
-goo_canvas_ellipse_init (GooCanvasEllipse *ellipse)
+goo_canvas_ellipse_class_init (GooCanvasEllipseClass *klass)
 {
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+  GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
+
+  gobject_class->finalize     = goo_canvas_ellipse_finalize;
+
+  gobject_class->get_property = goo_canvas_ellipse_get_property;
+  gobject_class->set_property = goo_canvas_ellipse_set_property;
+
+  simple_class->create_path = goo_canvas_ellipse_create_path;
 
+  goo_canvas_ellipse_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_ellipse_init (GooCanvasEllipse *ellipse)
+{
+  ellipse->ellipse_data = g_slice_new0 (GooCanvasEllipseData);
 }
 
 
@@ -118,9 +132,7 @@
  * @center_y: the y coordinate of the center of the ellipse.
  * @radius_x: the horizontal radius of the ellipse.
  * @radius_y: the vertical radius of the ellipse.
- * @first_property: the name of the first property to set, or %NULL.
- * @...: the remaining property names and values to set, terminated with a
- *  %NULL.
+ * @...: optional pairs of property names and values, and a terminating %NULL.
  * 
  * Creates a new ellipse item.
  *
@@ -146,24 +158,28 @@
 			gdouble        center_y,
 			gdouble        radius_x,
 			gdouble        radius_y,
-			const gchar   *first_property,
 			...)
 {
   GooCanvasItem *item;
   GooCanvasEllipse *ellipse;
-  va_list args;
+  GooCanvasEllipseData *ellipse_data;
+  const char *first_property;
+  va_list var_args;
 
   item = g_object_new (GOO_TYPE_CANVAS_ELLIPSE, NULL);
-  ellipse = GOO_CANVAS_ELLIPSE (item);
+  ellipse = (GooCanvasEllipse*) item;
 
-  ellipse->center_x = center_x;
-  ellipse->center_y = center_y;
-  ellipse->radius_x = radius_x;
-  ellipse->radius_y = radius_y;
+  ellipse_data = ellipse->ellipse_data;
+  ellipse_data->center_x = center_x;
+  ellipse_data->center_y = center_y;
+  ellipse_data->radius_x = radius_x;
+  ellipse_data->radius_y = radius_y;
 
-  va_start (args, first_property);
-  g_object_set_valist (G_OBJECT (item), first_property, args);
-  va_end (args);
+  va_start (var_args, radius_y);
+  first_property = va_arg (var_args, char*);
+  if (first_property)
+    g_object_set_valist ((GObject*) item, first_property, var_args);
+  va_end (var_args);
 
   if (parent)
     {
@@ -176,26 +192,39 @@
 
 
 static void
-goo_canvas_ellipse_get_property (GObject              *object,
-				 guint                 prop_id,
-				 GValue               *value,
-				 GParamSpec           *pspec)
+goo_canvas_ellipse_finalize (GObject *object)
 {
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
   GooCanvasEllipse *ellipse = (GooCanvasEllipse*) object;
 
+  if (!simple->model)
+    g_slice_free (GooCanvasEllipseData, ellipse->ellipse_data);
+  ellipse->ellipse_data = NULL;
+
+  G_OBJECT_CLASS (goo_canvas_ellipse_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_ellipse_get_common_property (GObject              *object,
+					GooCanvasEllipseData *ellipse_data,
+					guint                 prop_id,
+					GValue               *value,
+					GParamSpec           *pspec)
+{
   switch (prop_id)
     {
     case PROP_CENTER_X:
-      g_value_set_double (value, ellipse->center_x);
+      g_value_set_double (value, ellipse_data->center_x);
       break;
     case PROP_CENTER_Y:
-      g_value_set_double (value, ellipse->center_y);
+      g_value_set_double (value, ellipse_data->center_y);
       break;
     case PROP_RADIUS_X:
-      g_value_set_double (value, ellipse->radius_x);
+      g_value_set_double (value, ellipse_data->radius_x);
       break;
     case PROP_RADIUS_Y:
-      g_value_set_double (value, ellipse->radius_y);
+      g_value_set_double (value, ellipse_data->radius_y);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -205,50 +234,245 @@
 
 
 static void
-goo_canvas_ellipse_set_property (GObject              *object,
+goo_canvas_ellipse_get_property (GObject              *object,
 				 guint                 prop_id,
-				 const GValue         *value,
+				 GValue               *value,
 				 GParamSpec           *pspec)
 {
   GooCanvasEllipse *ellipse = (GooCanvasEllipse*) object;
 
+  goo_canvas_ellipse_get_common_property (object, ellipse->ellipse_data,
+					  prop_id, value, pspec);
+}
+
+
+static void
+goo_canvas_ellipse_set_common_property (GObject              *object,
+					GooCanvasEllipseData *ellipse_data,
+					guint                 prop_id,
+					const GValue         *value,
+					GParamSpec           *pspec)
+{
   switch (prop_id)
     {
     case PROP_CENTER_X:
-      ellipse->center_x = g_value_get_double (value);
+      ellipse_data->center_x = g_value_get_double (value);
       break;
     case PROP_CENTER_Y:
-      ellipse->center_y = g_value_get_double (value);
+      ellipse_data->center_y = g_value_get_double (value);
       break;
     case PROP_RADIUS_X:
-      ellipse->radius_x = g_value_get_double (value);
+      ellipse_data->radius_x = g_value_get_double (value);
       break;
     case PROP_RADIUS_Y:
-      ellipse->radius_y = g_value_get_double (value);
+      ellipse_data->radius_y = g_value_get_double (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
+}
 
-  g_signal_emit_by_name (ellipse, "changed", TRUE);
+
+static void
+goo_canvas_ellipse_set_property (GObject              *object,
+				 guint                 prop_id,
+				 const GValue         *value,
+				 GParamSpec           *pspec)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+  GooCanvasEllipse *ellipse = (GooCanvasEllipse*) object;
+
+  if (simple->model)
+    {
+      g_warning ("Can't set property of a canvas item with a model - set the model property instead");
+      return;
+    }
+
+  goo_canvas_ellipse_set_common_property (object, ellipse->ellipse_data,
+					  prop_id, value, pspec);
+  goo_canvas_item_simple_changed (simple, TRUE);
 }
 
 
-static GooCanvasItemView*
-goo_canvas_ellipse_create_view (GooCanvasItem     *item,
-				GooCanvasView     *canvas_view,
-				GooCanvasItemView *parent_view)
+static void
+goo_canvas_ellipse_create_path (GooCanvasItemSimple *simple,
+				cairo_t             *cr)
 {
-  return goo_canvas_ellipse_view_new (canvas_view, parent_view,
-				      (GooCanvasEllipse*) item);
+  GooCanvasEllipse *ellipse = (GooCanvasEllipse*) simple;
+  GooCanvasEllipseData *ellipse_data = ellipse->ellipse_data;
+
+  cairo_new_path (cr);
+  cairo_save (cr);
+  cairo_translate (cr, ellipse_data->center_x, ellipse_data->center_y);
+  cairo_scale (cr, ellipse_data->radius_x, ellipse_data->radius_y);
+  cairo_arc (cr, 0.0, 0.0, 1.0, 0.0, 2.0 * M_PI);
+  cairo_restore (cr);
 }
 
 
+
 static void
-item_interface_init (GooCanvasItemIface *iface)
+goo_canvas_ellipse_set_model    (GooCanvasItem      *item,
+				 GooCanvasItemModel *model)
 {
-  iface->create_view = goo_canvas_ellipse_create_view;
+  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemIface *parent_iface = g_type_interface_peek_parent (iface);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasEllipse *ellipse = (GooCanvasEllipse*) item;
+  GooCanvasEllipseModel *emodel = (GooCanvasEllipseModel*) model;
+
+  /* If our ellipse_data was allocated, free it. */
+  if (!simple->model)
+    g_slice_free (GooCanvasEllipseData, ellipse->ellipse_data);
+
+  /* Now use the new model's ellipse_data instead. */
+  ellipse->ellipse_data = &emodel->ellipse_data;
+
+  /* Let the parent GooCanvasItemSimple code do the rest. */
+  parent_iface->set_model (item, model);
+}
+
+
+static void
+canvas_item_interface_init (GooCanvasItemIface *iface)
+{
+  iface->set_model      = goo_canvas_ellipse_set_model;
+}
+
+
+/*
+ * GooCanvasEllipseModel.
+ */
+
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void goo_canvas_ellipse_model_finalize     (GObject            *object);
+static void goo_canvas_ellipse_model_get_property (GObject            *object,
+						   guint               param_id,
+						   GValue             *value,
+						   GParamSpec         *pspec);
+static void goo_canvas_ellipse_model_set_property (GObject            *object,
+						   guint               param_id,
+						   const GValue       *value,
+						   GParamSpec         *pspec);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasEllipseModel, goo_canvas_ellipse_model,
+			 GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+						item_model_interface_init))
+
+
+static void
+goo_canvas_ellipse_model_class_init (GooCanvasEllipseModelClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+
+  gobject_class->finalize     = goo_canvas_ellipse_model_finalize;
+
+  gobject_class->get_property = goo_canvas_ellipse_model_get_property;
+  gobject_class->set_property = goo_canvas_ellipse_model_set_property;
+
+  goo_canvas_ellipse_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_ellipse_model_init (GooCanvasEllipseModel *emodel)
+{
+
+}
+
+
+GooCanvasItemModel*
+goo_canvas_ellipse_model_new (GooCanvasItemModel *parent,
+			      gdouble             center_x,
+			      gdouble             center_y,
+			      gdouble             radius_x,
+			      gdouble             radius_y,
+			      ...)
+{
+  GooCanvasItemModel *model;
+  GooCanvasEllipseModel *emodel;
+  GooCanvasEllipseData *ellipse_data;
+  const char *first_property;
+  va_list var_args;
+
+  model = g_object_new (GOO_TYPE_CANVAS_ELLIPSE_MODEL, NULL);
+  emodel = (GooCanvasEllipseModel*) model;
+
+  ellipse_data = &emodel->ellipse_data;
+  ellipse_data->center_x = center_x;
+  ellipse_data->center_y = center_y;
+  ellipse_data->radius_x = radius_x;
+  ellipse_data->radius_y = radius_y;
+
+  va_start (var_args, radius_y);
+  first_property = va_arg (var_args, char*);
+  if (first_property)
+    g_object_set_valist ((GObject*) model, first_property, var_args);
+  va_end (var_args);
+
+  if (parent)
+    {
+      goo_canvas_item_model_add_child (parent, model, -1);
+      g_object_unref (model);
+    }
+
+  return model;
+}
+
+
+static void
+goo_canvas_ellipse_model_finalize (GObject *object)
+{
+  /*GooCanvasEllipseModel *emodel = (GooCanvasEllipseModel*) object;*/
+
+  G_OBJECT_CLASS (goo_canvas_ellipse_model_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_ellipse_model_get_property (GObject              *object,
+				       guint                 prop_id,
+				       GValue               *value,
+				       GParamSpec           *pspec)
+{
+  GooCanvasEllipseModel *emodel = (GooCanvasEllipseModel*) object;
+
+  goo_canvas_ellipse_get_common_property (object, &emodel->ellipse_data,
+					  prop_id, value, pspec);
+}
+
+
+static void
+goo_canvas_ellipse_model_set_property (GObject              *object,
+				       guint                 prop_id,
+				       const GValue         *value,
+				       GParamSpec           *pspec)
+{
+  GooCanvasEllipseModel *emodel = (GooCanvasEllipseModel*) object;
+
+  goo_canvas_ellipse_set_common_property (object, &emodel->ellipse_data,
+					  prop_id, value, pspec);
+  g_signal_emit_by_name (emodel, "changed", TRUE);
 }
 
 
+static GooCanvasItem*
+goo_canvas_ellipse_model_create_item (GooCanvasItemModel *model,
+				      GooCanvas          *canvas)
+{
+  GooCanvasItem *item;
+
+  item = g_object_new (GOO_TYPE_CANVAS_ELLIPSE, NULL);
+  goo_canvas_item_set_model (item, model);
+
+  return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+  iface->create_item    = goo_canvas_ellipse_model_create_item;
+}

Index: goocanvasellipse.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasellipse.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- goocanvasellipse.h	13 Apr 2006 16:06:04 -0000	1.2
+++ goocanvasellipse.h	29 Nov 2006 18:40:53 -0000	1.3
@@ -13,6 +13,14 @@
 G_BEGIN_DECLS
 
 
+/* This is the data used by both model and view classes. */
+typedef struct _GooCanvasEllipseData   GooCanvasEllipseData;
+struct _GooCanvasEllipseData
+{
+  gdouble center_x, center_y, radius_x, radius_y;
+};
+
+
 #define GOO_TYPE_CANVAS_ELLIPSE            (goo_canvas_ellipse_get_type ())
 #define GOO_CANVAS_ELLIPSE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ELLIPSE, GooCanvasEllipse))
 #define GOO_CANVAS_ELLIPSE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ELLIPSE, GooCanvasEllipseClass))
@@ -31,9 +39,9 @@
  */
 struct _GooCanvasEllipse
 {
-  GooCanvasItemSimple parent;
+  GooCanvasItemSimple parent_object;
 
-  gdouble center_x, center_y, radius_x, radius_y;
+  GooCanvasEllipseData *ellipse_data;
 };
 
 struct _GooCanvasEllipseClass
@@ -42,15 +50,54 @@
 };
 
 
-GType           goo_canvas_ellipse_get_type         (void) G_GNUC_CONST;
-GooCanvasItem*  goo_canvas_ellipse_new              (GooCanvasItem *parent,
-						     gdouble        center_x,
-						     gdouble        center_y,
-						     gdouble        radius_x,
-						     gdouble        radius_y,
-						     const gchar   *first_property,
-						     ...);
+GType               goo_canvas_ellipse_get_type  (void) G_GNUC_CONST;
 
+GooCanvasItem*      goo_canvas_ellipse_new	 (GooCanvasItem      *parent,
+						  gdouble             center_x,
+						  gdouble             center_y,
+						  gdouble             radius_x,
+						  gdouble             radius_y,
+						  ...);
+
+
+
+#define GOO_TYPE_CANVAS_ELLIPSE_MODEL            (goo_canvas_ellipse_model_get_type ())
+#define GOO_CANVAS_ELLIPSE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ELLIPSE_MODEL, GooCanvasEllipseModel))
+#define GOO_CANVAS_ELLIPSE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ELLIPSE_MODEL, GooCanvasEllipseModelClass))
+#define GOO_IS_CANVAS_ELLIPSE_MODEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_ELLIPSE_MODEL))
+#define GOO_IS_CANVAS_ELLIPSE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_ELLIPSE_MODEL))
+#define GOO_CANVAS_ELLIPSE_MODEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_ELLIPSE_MODEL, GooCanvasEllipseModelClass))
+
+
+typedef struct _GooCanvasEllipseModel       GooCanvasEllipseModel;
+typedef struct _GooCanvasEllipseModelClass  GooCanvasEllipseModelClass;
+
+/**
+ * GooCanvasEllipseModel
+ *
+ * The #GooCanvasEllipseModel-struct struct contains private data only.
+ */
+struct _GooCanvasEllipseModel
+{
+  GooCanvasItemModelSimple parent_object;
+
+  GooCanvasEllipseData ellipse_data;
+};
+
+struct _GooCanvasEllipseModelClass
+{
+  GooCanvasItemModelSimpleClass parent_class;
+};
+
+
+GType               goo_canvas_ellipse_model_get_type  (void) G_GNUC_CONST;
+
+GooCanvasItemModel* goo_canvas_ellipse_model_new (GooCanvasItemModel *parent,
+						  gdouble             center_x,
+						  gdouble             center_y,
+						  gdouble             radius_x,
+						  gdouble             radius_y,
+						  ...);
 
 G_END_DECLS
 

Index: goocanvasgroup.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasgroup.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- goocanvasgroup.c	24 Aug 2006 08:06:23 -0000	1.13
+++ goocanvasgroup.c	29 Nov 2006 18:40:53 -0000	1.14
@@ -26,42 +26,24 @@
  *
  * To respond to events such as mouse clicks on the group you must connect
  * to the signal handlers of the corresponding #GooCanvasGroupView objects.
- * (See goo_canvas_view_get_item_view() and #GooCanvasView::item-view-created.)
+ * (See goo_canvas_get_item_view() and #GooCanvas::item-created.)
  */
 #include <config.h>
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 #include "goocanvasprivate.h"
 #include "goocanvasgroup.h"
-#include "goocanvasgroupview.h"
+#include "goocanvasitemmodel.h"
+#include "goocanvas.h"
 #include "goocanvasmarshal.h"
+#include "goocanvasatk.h"
 
 
-enum {
-  PROP_0,
-
-  PROP_TRANSFORM,
-  PROP_VISIBILITY,
-  PROP_VISIBILITY_THRESHOLD,
-  PROP_POINTER_EVENTS,
-  PROP_TITLE,
-  PROP_DESCRIPTION
-};
-
-
-static void goo_canvas_group_finalize  (GObject *object);
-static void canvas_item_interface_init (GooCanvasItemIface *iface);
-static void goo_canvas_group_get_property (GObject            *object,
-					   guint               prop_id,
-					   GValue             *value,
-					   GParamSpec         *pspec);
-static void goo_canvas_group_set_property (GObject            *object,
-					   guint               prop_id,
-					   const GValue       *value,
-					   GParamSpec         *pspec);
+static void goo_canvas_group_finalize     (GObject            *object);
+static void canvas_item_interface_init    (GooCanvasItemIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (GooCanvasGroup, goo_canvas_group,
-			 G_TYPE_OBJECT,
+			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
 						canvas_item_interface_init))
 
@@ -73,26 +55,13 @@
 
   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;
-
-  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");
+  /* 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)))
+    {
+      atk_registry_set_factory_type (atk_get_default_registry (),
+				     GOO_TYPE_CANVAS_GROUP,
+				     goo_canvas_item_accessible_factory_get_type ());
+    }
 }
 
 
@@ -100,8 +69,6 @@
 goo_canvas_group_init (GooCanvasGroup *group)
 {
   group->items = g_ptr_array_sized_new (8);
-  cairo_matrix_init_identity (&group->transform);
-  group->pointer_events = GOO_CANVAS_EVENTS_VISIBLE_PAINTED;
 }
 
 
@@ -110,51 +77,40 @@
  * @parent: the parent item, or %NULL. If a parent is specified, it will assume
  *  ownership of the item, and the item will automatically be freed when it is
  *  removed from the parent. Otherwise call g_object_unref() to free it.
+ * @...: optional pairs of property names and values, and a terminating %NULL.
  * 
  * Creates a new group item.
  * 
  * Return value: a new group item.
  **/
 GooCanvasItem*
-goo_canvas_group_new (GooCanvasItem *parent)
+goo_canvas_group_new (GooCanvasItem *parent,
+		      ...)
 {
   GooCanvasItem *item;
   GooCanvasGroup *group;
+  va_list var_args;
+  const char *first_property;
 
   item = g_object_new (GOO_TYPE_CANVAS_GROUP, NULL);
-  group = GOO_CANVAS_GROUP (item);
+  group = (GooCanvasGroup*) item;
+
+  va_start (var_args, parent);
+  first_property = va_arg (var_args, char*);
+  if (first_property)
+    g_object_set_valist (G_OBJECT (item), first_property, var_args);
+  va_end (var_args);
 
   if (parent)
     {
       goo_canvas_item_add_child (parent, item, -1);
       g_object_unref (item);
-
-      group->model = goo_canvas_item_get_model (parent);
     }
 
   return item;
 }
 
 
-/**
- * goo_canvas_group_set_model:
- * @group: a #GooCanvasGroup.
- * @model: the #GooCanvasModel of the group.
- * 
- * Sets the model of the group.
- *
- * This is only intended to be used by implementors of #GooCanvasModel, to set
- * the model of the root group.
- **/
-void
-goo_canvas_group_set_model   (GooCanvasGroup *group,
-			      GooCanvasModel *model)
-{
-  /* Note that we don't ref the model, to avoid reference cycles. */
-  group->model = model;
-}
-
-
 static void
 goo_canvas_group_finalize (GObject *object)
 {
@@ -165,6 +121,7 @@
   for (i = 0; i < group->items->len; i++)
     {
       GooCanvasItem *item = group->items->pdata[i];
+      goo_canvas_item_set_parent (item, NULL);
       g_object_unref (item);
     }
 
@@ -175,230 +132,587 @@
 
 
 static void
-goo_canvas_group_add_child     (GooCanvasItem  *group_item,
-				GooCanvasItem  *item,
+goo_canvas_group_add_child     (GooCanvasItem  *item,
+				GooCanvasItem  *child,
 				gint            position)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (group_item);
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
 
-  g_object_ref (item);
+  g_object_ref (child);
 
   if (position >= 0)
     {
-      goo_canvas_util_ptr_array_insert (group->items, item, position);
+      goo_canvas_util_ptr_array_insert (group->items, child, position);
     }
   else
     {
       position = group->items->len;
-      g_ptr_array_add (group->items, item);
+      g_ptr_array_add (group->items, child);
     }
 
-  goo_canvas_item_set_parent (item, group_item);
+  goo_canvas_item_set_parent (child, item);
 
-  g_signal_emit_by_name (group, "child-added", position);
+  goo_canvas_item_request_update (item);
 }
 
 
 static void
-goo_canvas_group_move_child    (GooCanvasItem  *group_item,
+goo_canvas_group_move_child    (GooCanvasItem  *item,
 				gint	        old_position,
 				gint            new_position)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (group_item);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasItem *child;
+  GooCanvasBounds bounds;
+
+  /* Request a redraw of the item's bounds. */
+  child = group->items->pdata[old_position];
+  if (simple->canvas)
+    {
+      goo_canvas_item_get_bounds (child, &bounds);
+      goo_canvas_request_redraw (simple->canvas, &bounds);
+    }
 
   goo_canvas_util_ptr_array_move (group->items, old_position, new_position);
 
-  g_signal_emit_by_name (group, "child-moved", old_position, new_position);
+  goo_canvas_item_request_update (item);
 }
 
 
 static void
-goo_canvas_group_remove_child  (GooCanvasItem  *group_item,
+goo_canvas_group_remove_child  (GooCanvasItem  *item,
 				gint            child_num)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (group_item);
-  GooCanvasItem *item;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasItem *child;
+  GooCanvasBounds bounds;
 
-  item = group->items->pdata[child_num];
-  goo_canvas_item_set_parent (item, NULL);
-  g_object_unref (item);
+  /* Request a redraw of the item's bounds. */
+  child = group->items->pdata[child_num];
+  if (simple->canvas)
+    {
+      goo_canvas_item_get_bounds (child, &bounds);
+      goo_canvas_request_redraw (simple->canvas, &bounds);
+    }
+
+  goo_canvas_item_set_parent (child, NULL);
+  g_object_unref (child);
 
   g_ptr_array_remove_index (group->items, child_num);
 
-  g_signal_emit_by_name (group, "child-removed", child_num);
+  goo_canvas_item_request_update (item);
 }
 
 
 static gint
-goo_canvas_group_get_n_children (GooCanvasItem       *group_item)
+goo_canvas_group_get_n_children (GooCanvasItem  *item)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (group_item);
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
 
   return group->items->len;
 }
 
 
 static GooCanvasItem*
-goo_canvas_group_get_child   (GooCanvasItem       *group_item,
+goo_canvas_group_get_child   (GooCanvasItem       *item,
 			      gint                 child_num)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (group_item);
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
 
   return group->items->pdata[child_num];
 }
 
 
-static GooCanvasModel*
-goo_canvas_group_get_model (GooCanvasItem       *item)
+/* This is only used to set the canvas of the root group. It isn't normally
+   needed by apps. */
+static void
+goo_canvas_group_set_canvas  (GooCanvasItem *item,
+			      GooCanvas     *canvas)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (item);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  gint i;
 
-  if (!group->model && group->parent)
-    group->model = goo_canvas_item_get_model (group->parent);
+  simple->canvas = canvas;
 
-  return group->model;
+  /* Recursively set the canvas of all child items. */
+  for (i = 0; i < group->items->len; i++)
+    {
+      GooCanvasItem *item = group->items->pdata[i];
+      goo_canvas_item_set_canvas (item, canvas);
+    }
 }
 
 
-static GooCanvasItem*
-goo_canvas_group_get_parent (GooCanvasItem       *item)
+static void
+on_model_child_added (GooCanvasGroupModel *model,
+		      gint                 position,
+		      GooCanvasGroup      *group)
 {
-  return GOO_CANVAS_GROUP (item)->parent;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) group;
+  GooCanvasItem *item = (GooCanvasItem*) group;
+  GooCanvasItemModel *child_model;
+  GooCanvasItem *child;
+
+  /* Create a canvas item for the model. */
+  child_model = goo_canvas_item_model_get_child ((GooCanvasItemModel*) model,
+						 position);
+  child = goo_canvas_create_item (simple->canvas, child_model);
+  goo_canvas_group_add_child (item, child, position);
+  g_object_unref (child);
 }
 
 
 static void
-goo_canvas_group_set_parent (GooCanvasItem       *item,
-			     GooCanvasItem       *parent)
+on_model_child_moved (GooCanvasGroupModel *model,
+		      gint                 old_position,
+		      gint                 new_position,
+		      GooCanvasGroup      *group)
 {
-  GOO_CANVAS_GROUP (item)->parent = parent;
-  if (!parent)
-    GOO_CANVAS_GROUP (item)->model = NULL;
+  goo_canvas_group_move_child ((GooCanvasItem*) group, old_position,
+			       new_position);
 }
 
 
-static cairo_matrix_t*
-goo_canvas_group_get_transform (GooCanvasItem       *item)
+static void
+on_model_child_removed (GooCanvasGroupModel *model,
+			gint                 child_num,
+			GooCanvasGroup      *group)
 {
-  return &GOO_CANVAS_GROUP (item)->transform;
+  goo_canvas_group_remove_child ((GooCanvasItem*) group, child_num);
 }
 
 
 static void
-goo_canvas_group_set_transform (GooCanvasItem *item,
-				cairo_matrix_t *transform)
+goo_canvas_group_set_model (GooCanvasItem       *item,
+			    GooCanvasItemModel  *model)
 {
-  GooCanvasGroup *group = GOO_CANVAS_GROUP (item);
+  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemIface *parent_iface = g_type_interface_peek_parent (iface);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  gint n_children, i;
 
-  if (transform)
-    group->transform = *transform;
-  else
-    cairo_matrix_init_identity (&group->transform);
+  /* Do the default GooCanvasItemSimple code first. */
+  parent_iface->set_model (item, model);
 
-  g_signal_emit_by_name (group, "changed", TRUE);
+  /* Now add our own handlers. */
+  g_signal_connect (model, "child-added",
+		    G_CALLBACK (on_model_child_added), group);
+  g_signal_connect (model, "child-moved",
+		    G_CALLBACK (on_model_child_moved), group);
+  g_signal_connect (model, "child-removed",
+		    G_CALLBACK (on_model_child_removed), group);
+
+  /* Recursively create child items for any children. */
+  n_children = goo_canvas_item_model_get_n_children (model);
+  for (i = 0; i < n_children; i++)
+    on_model_child_added ((GooCanvasGroupModel*) simple->model, i, group);
 }
 
 
-static GooCanvasItemView*
-goo_canvas_group_create_view (GooCanvasItem     *group_item,
-			      GooCanvasView     *canvas_view,
-			      GooCanvasItemView *parent_view)
+static void
+goo_canvas_group_request_update  (GooCanvasItem *item)
 {
-  return goo_canvas_group_view_new (canvas_view, parent_view, group_item);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+
+  if (!simple->need_update)
+    {
+      simple->need_update = TRUE;
+
+      if (simple->parent)
+	goo_canvas_item_request_update (simple->parent);
+      else if (simple->canvas)
+	goo_canvas_request_update (simple->canvas);
+    }
+}
+
+
+static void
+goo_canvas_group_update  (GooCanvasItem   *item,
+			  gboolean         entire_tree,
+			  cairo_t         *cr,
+			  GooCanvasBounds *bounds)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasBounds child_bounds;
+  gint i;
+
+  if (entire_tree || simple->need_update)
+    {
+      if (simple->need_entire_subtree_update)
+	entire_tree = TRUE;
+
+      simple->need_update = FALSE;
+      simple->need_entire_subtree_update = FALSE;
+
+      goo_canvas_item_simple_check_style (simple);
+
+      simple->bounds.x1 = simple->bounds.y1 = 0.0;
+      simple->bounds.x2 = simple->bounds.y2 = 0.0;
+
+      cairo_save (cr);
+      if (simple->simple_data->transform)
+	cairo_transform (cr, simple->simple_data->transform);
+
+      for (i = 0; i < group->items->len; i++)
+	{
+	  GooCanvasItem *child = group->items->pdata[i];
+
+	  goo_canvas_item_update (child, entire_tree, cr, &child_bounds);
+	  
+	  /* FIXME: Check for NULL bounds. Anywhere else? */
+	  if (i == 0)
+	    {
+	      simple->bounds.x1 = child_bounds.x1;
+	      simple->bounds.y1 = child_bounds.y1;
+	      simple->bounds.x2 = child_bounds.x2;
+	      simple->bounds.y2 = child_bounds.y2;
+	    }
+	  else
+	    {
+	      simple->bounds.x1 = MIN (simple->bounds.x1, child_bounds.x1);
+	      simple->bounds.y1 = MIN (simple->bounds.y1, child_bounds.y1);
+	      simple->bounds.x2 = MAX (simple->bounds.x2, child_bounds.x2);
+	      simple->bounds.y2 = MAX (simple->bounds.y2, child_bounds.y2);
+	    }
+	}
+      cairo_restore (cr);
+    }
+
+  *bounds = simple->bounds;
+}
+
+
+static GooCanvasItem*
+goo_canvas_group_get_item_at (GooCanvasItem  *item,
+			      gdouble         x,
+			      gdouble         y,
+			      cairo_t        *cr,
+			      gboolean        is_pointer_event,
+			      gboolean        parent_visible)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasBounds child_bounds;
+  GooCanvasItem *found_item = NULL;
+  gboolean visible = parent_visible;
+  int i;
+
+  if (simple->need_update)
+    goo_canvas_item_ensure_updated (item);
+
+  if (simple_data->visibility == GOO_CANVAS_ITEM_INVISIBLE
+      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
+	  && simple->canvas->scale < simple_data->visibility_threshold))
+    visible = FALSE;
+
+  /* Check if the group should receive events. */
+  if (is_pointer_event
+      && (simple_data->pointer_events == GOO_CANVAS_EVENTS_NONE
+	  || ((simple_data->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK)
+	      && !visible)))
+    return NULL;
+
+  /* Step down from the top item to the bottom in the stack/layer, and return
+     the first item found that contains the given point. */
+  cairo_save (cr);
+  if (simple_data->transform)
+    cairo_transform (cr, simple_data->transform);
+
+  for (i = group->items->len - 1; i >= 0; i--)
+    {
+      GooCanvasItem *child = group->items->pdata[i];
+      goo_canvas_item_get_bounds (child, &child_bounds);
+
+      /* Skip the item if the bounds don't contain the point. */
+      if (child_bounds.x1 > x || child_bounds.x2 < x
+	  || child_bounds.y1 > y || child_bounds.y2 < y)
+	continue;
+
+      found_item = goo_canvas_item_get_item_at (child, x, y, cr,
+						is_pointer_event, visible);
+      if (found_item)
+	break;
+    }
+  cairo_restore (cr);
+
+  return found_item;
+}
+
+
+static void
+goo_canvas_group_paint (GooCanvasItem     *item,
+			cairo_t           *cr,
+			GooCanvasBounds   *bounds,
+			gdouble            scale)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasGroup *group = (GooCanvasGroup*) item;
+  GooCanvasBounds child_bounds;
+  gint i;
+
+  /* Check if the item should be visible. */
+  if (simple_data->visibility == GOO_CANVAS_ITEM_INVISIBLE
+      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
+	  && simple->canvas->scale < simple_data->visibility_threshold))
+    return;
+
+  /* Paint all the items in the group. */
+  cairo_save (cr);
+  if (simple_data->transform)
+    cairo_transform (cr, simple_data->transform);
+
+  for (i = 0; i < group->items->len; i++)
+    {
+      GooCanvasItem *child = group->items->pdata[i];
+
+      goo_canvas_item_get_bounds (child, &child_bounds);
+
+      /* Skip the item if the bounds don't intersect the expose rectangle. */
+      if (child_bounds.x1 > bounds->x2 || child_bounds.x2 < bounds->x1
+	  || child_bounds.y1 > bounds->y2 || child_bounds.y2 < bounds->y1)
+	continue;
+
+      goo_canvas_item_paint (child, cr, bounds, scale);
+    }
+  cairo_restore (cr);
 }
 
 
 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_n_children = goo_canvas_group_get_n_children;
-  iface->get_child      = goo_canvas_group_get_child;
 
-  iface->get_model      = goo_canvas_group_get_model;
-  iface->get_parent     = goo_canvas_group_get_parent;
-  iface->set_parent     = goo_canvas_group_set_parent;
-  iface->get_transform  = goo_canvas_group_get_transform;
-  iface->set_transform  = goo_canvas_group_set_transform;
-  iface->create_view    = goo_canvas_group_create_view;
+  iface->get_item_at	= goo_canvas_group_get_item_at;
+  iface->update         = goo_canvas_group_update;
+  iface->paint          = goo_canvas_group_paint;
+
+  iface->set_model      = goo_canvas_group_set_model;
 }
 
 
+/**
+ * SECTION:goocanvasgroupmodel
+ * @Title: GooCanvasGroupModelModel
+ * @Short_Description: model for a group of items.
+ *
+ * #GooCanvasGroupModel represents a group of items. Groups can be nested to any
+ * depth, to create a hierarchy of items. Items are ordered within each group,
+ * with later items being displayed above earlier items.
+ *
+ * #GooCanvasGroupModel implements the #GooCanvasItem interface, so you can use the
+ * #GooCanvasItem functions such as goo_canvas_item_raise() and
+ * goo_canvas_item_rotate(), and the properties such as "visibility" and
+ * "pointer-events".
+ *
+ * To create a #GooCanvasGroupModel use goo_canvas_group_model_new().
+ *
+ * To get or set the properties of an existing #GooCanvasGroupModel, use
+ * g_object_get() and g_object_set().
+ *
+ * To respond to events such as mouse clicks on the group you must connect
+ * to the signal handlers of the corresponding #GooCanvasGroupModelView objects.
+ * (See goo_canvas_view_get_item_view() and #GooCanvasView::item-view-created.)
+ */
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void goo_canvas_group_model_finalize     (GObject            *object);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasGroupModel, goo_canvas_group_model,
+			 GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+						item_model_interface_init))
+
+
 static void
-goo_canvas_group_get_property (GObject              *object,
-			       guint                 prop_id,
-			       GValue               *value,
-			       GParamSpec           *pspec)
+goo_canvas_group_model_class_init (GooCanvasGroupModelClass *klass)
 {
-  GooCanvasGroup *group = (GooCanvasGroup*) object;
+  GObjectClass *gobject_class = (GObjectClass*) klass;
 
-  switch (prop_id)
-    {
-    case PROP_TRANSFORM:
-      g_value_set_boxed (value, &group->transform);
-      break;
-    case PROP_VISIBILITY:
-      g_value_set_enum (value, group->visibility);
-      break;
-    case PROP_VISIBILITY_THRESHOLD:
-      g_value_set_double (value, group->visibility_threshold);
-      break;
-    case PROP_POINTER_EVENTS:
-      g_value_set_flags (value, group->pointer_events);
-      break;
-    case PROP_TITLE:
-      g_value_set_string (value, group->title);
-      break;
-    case PROP_DESCRIPTION:
-      g_value_set_string (value, group->description);
-      break;
+  gobject_class->finalize = goo_canvas_group_model_finalize;
+}
 
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
+
+static void
+goo_canvas_group_model_init (GooCanvasGroupModel *gmodel)
+{
+  gmodel->children = g_ptr_array_sized_new (8);
+}
+
+
+/**
+ * goo_canvas_group_model_new:
+ * @parent: the parent item, or %NULL. If a parent is specified, it will assume
+ *  ownership of the item, and the item will automatically be freed when it is
+ *  removed from the parent. Otherwise call g_object_unref() to free it.
+ * @...: optional pairs of property names and values, and a terminating %NULL.
+ * 
+ * Creates a new group item.
+ * 
+ * Return value: a new group item.
+ **/
+GooCanvasItemModel*
+goo_canvas_group_model_new (GooCanvasItemModel *parent,
+			    ...)
+{
+  GooCanvasItemModel *item;
+  GooCanvasGroupModel *gmodel;
+  va_list var_args;
+  const char *first_property;
+
+  item = g_object_new (GOO_TYPE_CANVAS_GROUP_MODEL, NULL);
+  gmodel = (GooCanvasGroupModel*) item;
+
+  va_start (var_args, parent);
+  first_property = va_arg (var_args, char*);
+  if (first_property)
+    g_object_set_valist (G_OBJECT (item), first_property, var_args);
+  va_end (var_args);
+
+  if (parent)
+    {
+      goo_canvas_item_model_add_child (parent, item, -1);
+      g_object_unref (item);
     }
+
+  return item;
 }
 
 
 static void
-goo_canvas_group_set_property (GObject              *object,
-			       guint                 prop_id,
-			       const GValue         *value,
-			       GParamSpec           *pspec)
+goo_canvas_group_model_finalize (GObject *object)
 {
-  GooCanvasGroup *group = (GooCanvasGroup*) object;
-  cairo_matrix_t *transform;
+  GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) object;
+  gint i;
 
-  switch (prop_id)
+  /* Unref all the items in the group. */
+  for (i = 0; i < gmodel->children->len; i++)
     {
-    case PROP_TRANSFORM:
-      transform = g_value_get_boxed (value);
-      group->transform = *transform;
-      break;
-    case PROP_VISIBILITY:
-      group->visibility = g_value_get_enum (value);
-      break;
-    case PROP_VISIBILITY_THRESHOLD:
-      group->visibility_threshold = g_value_get_double (value);
-      break;
-    case PROP_POINTER_EVENTS:
-      group->pointer_events = g_value_get_flags (value);
-      break;
-    case PROP_TITLE:
-      g_free (group->title);
-      group->title = g_value_dup_string (value);
-      break;
-    case PROP_DESCRIPTION:
-      g_free (group->description);
-      group->description = g_value_dup_string (value);
-      break;
+      GooCanvasItemModel *child = gmodel->children->pdata[i];
+      goo_canvas_item_model_set_parent (child, NULL);
+      g_object_unref (child);
+    }
 
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
+  g_ptr_array_free (gmodel->children, TRUE);
+
+  G_OBJECT_CLASS (goo_canvas_group_model_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_group_model_add_child     (GooCanvasItemModel *model,
+				      GooCanvasItemModel *child,
+				      gint                position)
+{
+  GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
+
+  g_object_ref (child);
+
+  if (position >= 0)
+    {
+      goo_canvas_util_ptr_array_insert (gmodel->children, child, position);
+    }
+  else
+    {
+      position = gmodel->children->len;
+      g_ptr_array_add (gmodel->children, child);
     }
 
-  g_signal_emit_by_name (group, "changed", TRUE);
+  goo_canvas_item_model_set_parent (child, model);
+
+  g_signal_emit_by_name (gmodel, "child-added", position);
+}
+
+
+static void
+goo_canvas_group_model_move_child    (GooCanvasItemModel *model,
+				      gint	          old_position,
+				      gint                new_position)
+{
+  GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
+
+  goo_canvas_util_ptr_array_move (gmodel->children, old_position,
+				  new_position);
+
+  g_signal_emit_by_name (gmodel, "child-moved", old_position, new_position);
+}
+
+
+static void
+goo_canvas_group_model_remove_child  (GooCanvasItemModel *model,
+				      gint                child_num)
+{
+  GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
+  GooCanvasItemModel *child;
+
+  child = gmodel->children->pdata[child_num];
+  goo_canvas_item_model_set_parent (child, NULL);
+  g_object_unref (child);
+
+  g_ptr_array_remove_index (gmodel->children, child_num);
+
+  g_signal_emit_by_name (gmodel, "child-removed", child_num);
+}
+
+
+static gint
+goo_canvas_group_model_get_n_children (GooCanvasItemModel  *model)
+{
+  GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
+
+  return gmodel->children->len;
+}
+
+
+static GooCanvasItemModel*
+goo_canvas_group_model_get_child   (GooCanvasItemModel  *model,
+				    gint                 child_num)
+{
+  GooCanvasGroupModel *gmodel = (GooCanvasGroupModel*) model;
+
+  return gmodel->children->pdata[child_num];
 }
+
+
+static GooCanvasItem*
+goo_canvas_group_model_create_item (GooCanvasItemModel *model,
+				    GooCanvas          *canvas)
+{
+  GooCanvasItem *item;
+
+  item = goo_canvas_group_new (NULL, NULL);
+  /* Note that we set the canvas before the model, since we may need the
+     canvas to create any child items. */
+  goo_canvas_item_set_canvas (item, canvas);
+  goo_canvas_item_set_model (item, model);
+
+  return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+  iface->add_child      = goo_canvas_group_model_add_child;
+  iface->move_child     = goo_canvas_group_model_move_child;
+  iface->remove_child   = goo_canvas_group_model_remove_child;
+  iface->get_n_children = goo_canvas_group_model_get_n_children;
+  iface->get_child      = goo_canvas_group_model_get_child;
+
+  iface->create_item    = goo_canvas_group_model_create_item;
+}
+
+

Index: goocanvasgroup.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasgroup.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- goocanvasgroup.h	8 Aug 2006 21:58:13 -0000	1.8
+++ goocanvasgroup.h	29 Nov 2006 18:40:53 -0000	1.9
@@ -8,7 +8,7 @@
 #define __GOO_CANVAS_GROUP_H__
 
 #include <gtk/gtk.h>
-#include "goocanvasmodel.h"
+#include "goocanvasitemsimple.h"
 #include "goocanvasutils.h"
 
 G_BEGIN_DECLS
@@ -22,8 +22,11 @@
 #define GOO_CANVAS_GROUP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GROUP, GooCanvasGroupClass))
 
 
-typedef struct _GooCanvasGroup       GooCanvasGroup;
-typedef struct _GooCanvasGroupClass  GooCanvasGroupClass;
+typedef struct _GooCanvasGroup            GooCanvasGroup;
+typedef struct _GooCanvasGroupClass       GooCanvasGroupClass;
+
+typedef struct _GooCanvasGroupModel       GooCanvasGroupModel;
+typedef struct _GooCanvasGroupModelClass  GooCanvasGroupModelClass;
 
 /**
  * GooCanvasGroup
@@ -32,50 +35,58 @@
  */
 struct _GooCanvasGroup
 {
-  GObject object;
-
-  /* The canvas model. */
-  GooCanvasModel *model;
-
-  /* The parent item. */
-  GooCanvasItem *parent;
+  GooCanvasItemSimple parent_object;
 
   /* An array of pointers to GooCanvasItems. The first element is at the
      bottom of the display stack and the last element is at the top. */
   GPtrArray *items;
+};
 
-  /* The transformation matrix, or NULL. */
-  cairo_matrix_t transform;
+struct _GooCanvasGroupClass
+{
+  GooCanvasItemSimpleClass parent_class;
+};
 
-  /* If visibility is VISIBLE_ABOVE_THRESHOLD the item is visible if the canvas
-     scale setting is above this threshold (or equal to it). */
-  gdouble visibility_threshold;
 
-  /* The title and description of the item for accessibility. */
-  gchar *title;
-  gchar *description;
+GType          goo_canvas_group_get_type    (void) G_GNUC_CONST;
+GooCanvasItem* goo_canvas_group_new         (GooCanvasItem  *parent,
+					     ...);
 
-  /* Whether the item is visible, invisible, or visible above a given scale. */
-  GooCanvasItemVisibility visibility	: 2;
 
-  /* What events the group should receive. */
-  GooCanvasPointerEvents pointer_events : 4;
-};
 
-struct _GooCanvasGroupClass
+#define GOO_TYPE_CANVAS_GROUP_MODEL            (goo_canvas_group_model_get_type ())
+#define GOO_CANVAS_GROUP_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_GROUP_MODEL, GooCanvasGroupModel))
+#define GOO_CANVAS_GROUP_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_GROUP_MODEL, GooCanvasGroupModelClass))
+#define GOO_IS_CANVAS_GROUP_MODEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_GROUP_MODEL))
+#define GOO_IS_CANVAS_GROUP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_GROUP_MODEL))
+#define GOO_CANVAS_GROUP_MODEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GROUP_MODEL, GooCanvasGroupModelClass))
+
+
+
+/**
+ * GooCanvasGroupModel
+ *
+ * The #GooCanvasGroupModel-struct struct contains private data only.
+ */
+struct _GooCanvasGroupModel
 {
-  GObjectClass parent_class;
+  GooCanvasItemModelSimple parent_object;
+
+  /* An array of pointers to GooCanvasItemModels. The first element is at the
+     bottom of the display stack and the last element is at the top. */
+  GPtrArray *children;
 };
 
+struct _GooCanvasGroupModelClass
+{
+  GooCanvasItemModelSimpleClass parent_class;
+};
 
-GType          goo_canvas_group_get_type    (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_group_new         (GooCanvasItem  *parent);
 
+GType               goo_canvas_group_model_get_type (void) G_GNUC_CONST;
+GooCanvasItemModel* goo_canvas_group_model_new      (GooCanvasItemModel  *parent,
+						     ...);
 
-/* This is only intended to be used by implementors of GooCanvasModel, to set
-   the model of the root group. */
-void           goo_canvas_group_set_model   (GooCanvasGroup *group,
-					     GooCanvasModel *model);
 
 G_END_DECLS
 

Index: goocanvasimage.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasimage.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- goocanvasimage.c	24 Aug 2006 08:06:23 -0000	1.7
+++ goocanvasimage.c	29 Nov 2006 18:40:53 -0000	1.8
@@ -26,14 +26,14 @@
  *
  * To respond to events such as mouse clicks on the image you must connect
  * to the signal handlers of the corresponding #GooCanvasImageView objects.
- * (See goo_canvas_view_get_item_view() and #GooCanvasView::item-view-created.)
+ * (See goo_canvas_get_item_view() and #GooCanvasView::item-view-created.)
  */
 #include <config.h>
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 #include "goocanvasprivate.h"
 #include "goocanvasimage.h"
-#include "goocanvasimageview.h"
+#include "goocanvas.h"
 #include "goocanvasutils.h"
 
 
@@ -50,8 +50,8 @@
   PROP_PIXBUF
 };
 
-static void goo_canvas_image_finalize (GObject *object);
-static void item_interface_init (GooCanvasItemIface *iface);
+static void goo_canvas_image_finalize     (GObject            *object);
+static void canvas_item_interface_init    (GooCanvasItemIface *iface);
 static void goo_canvas_image_get_property (GObject            *object,
 					   guint               param_id,
 					   GValue             *value,
@@ -64,19 +64,12 @@
 G_DEFINE_TYPE_WITH_CODE (GooCanvasImage, goo_canvas_image,
 			 GOO_TYPE_CANVAS_ITEM_SIMPLE,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
-						item_interface_init))
+						canvas_item_interface_init))
 
 
 static void
-goo_canvas_image_class_init (GooCanvasImageClass *klass)
+goo_canvas_image_install_common_properties (GObjectClass *gobject_class)
 {
-  GObjectClass *gobject_class = (GObjectClass*) klass;
-
-  gobject_class->finalize = goo_canvas_image_finalize;
-
-  gobject_class->get_property = goo_canvas_image_get_property;
-  gobject_class->set_property = goo_canvas_image_set_property;
-
   g_object_class_install_property (gobject_class, PROP_PATTERN,
                                    g_param_spec_boxed ("pattern",
 						       _("Pattern"),
@@ -124,9 +117,23 @@
 
 
 static void
-goo_canvas_image_init (GooCanvasImage *canvas_image)
+goo_canvas_image_class_init (GooCanvasImageClass *klass)
 {
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+
+  gobject_class->finalize = goo_canvas_image_finalize;
 
+  gobject_class->get_property = goo_canvas_image_get_property;
+  gobject_class->set_property = goo_canvas_image_set_property;
+
+  goo_canvas_image_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_image_init (GooCanvasImage *image)
+{
+  image->image_data = g_slice_new0 (GooCanvasImageData);
 }
 
 
@@ -138,9 +145,7 @@
  * @pixbuf: the #GdkPixbuf containing the image data, or %NULL.
  * @x: the x coordinate of the image.
  * @y: the y coordinate of the image.
- * @first_property: the name of the first property to set, or %NULL.
- * @...: the remaining property names and values to set, terminated with a
- *  %NULL.
+ * @...: optional pairs of property names and values, and a terminating %NULL.
  * 
  * Creates a new image item.
  * 
@@ -161,30 +166,34 @@
 		      GdkPixbuf     *pixbuf,
 		      gdouble        x,
 		      gdouble        y,
-		      const gchar   *first_property,
 		      ...)
 {
   GooCanvasItem *item;
   GooCanvasImage *image;
-  va_list args;
+  GooCanvasImageData *image_data;
+  const char *first_property;
+  va_list var_args;
 
   item = g_object_new (GOO_TYPE_CANVAS_IMAGE, NULL);
-  image = GOO_CANVAS_IMAGE (item);
-
-  image->x = x;
-  image->y = y;
+  image = (GooCanvasImage*) item;
 
-  va_start (args, first_property);
-  g_object_set_valist (G_OBJECT (item), first_property, args);
-  va_end (args);
+  image_data = image->image_data;
+  image_data->x = x;
+  image_data->y = y;
 
   if (pixbuf)
     {
-      image->pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
-      image->width = gdk_pixbuf_get_width (pixbuf);
-      image->height = gdk_pixbuf_get_height (pixbuf);
+      image_data->pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
+      image_data->width = gdk_pixbuf_get_width (pixbuf);
+      image_data->height = gdk_pixbuf_get_height (pixbuf);
     }
 
+  va_start (var_args, y);
+  first_property = va_arg (var_args, char*);
+  if (first_property)
+    g_object_set_valist ((GObject*) item, first_property, var_args);
+  va_end (var_args);
+
   if (parent)
     {
       goo_canvas_item_add_child (parent, item, -1);
@@ -198,55 +207,43 @@
 static void
 goo_canvas_image_finalize (GObject *object)
 {
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
   GooCanvasImage *image = (GooCanvasImage*) object;
 
-  cairo_pattern_destroy (image->pattern);
+  if (!simple->model)
+    {
+      cairo_pattern_destroy (image->image_data->pattern);
+      g_slice_free (GooCanvasImageData, image->image_data);
+    }
+  image->image_data = NULL;
 
   G_OBJECT_CLASS (goo_canvas_image_parent_class)->finalize (object);
 }
 
 
-static GooCanvasItemView*
-goo_canvas_image_create_view (GooCanvasItem     *item,
-			      GooCanvasView     *canvas_view,
-			      GooCanvasItemView *parent_view)
-{
-  return goo_canvas_image_view_new (canvas_view, parent_view,
-				    (GooCanvasImage*) item);
-}
-
-
-static void
-item_interface_init (GooCanvasItemIface *iface)
-{
-  iface->create_view = goo_canvas_image_create_view;
-}
-
-
 static void
-goo_canvas_image_get_property (GObject              *object,
-			       guint                 prop_id,
-			       GValue               *value,
-			       GParamSpec           *pspec)
+goo_canvas_image_get_common_property (GObject              *object,
+				      GooCanvasImageData   *image_data,
+				      guint                 prop_id,
+				      GValue               *value,
+				      GParamSpec           *pspec)
 {
-  GooCanvasImage *image = (GooCanvasImage*) object;
-
   switch (prop_id)
     {
     case PROP_PATTERN:
-      g_value_set_boxed (value, image->pattern);
+      g_value_set_boxed (value, image_data->pattern);
       break;
     case PROP_X:
-      g_value_set_double (value, image->x);
+      g_value_set_double (value, image_data->x);
       break;
     case PROP_Y:
-      g_value_set_double (value, image->y);
+      g_value_set_double (value, image_data->y);
       break;
     case PROP_WIDTH:
-      g_value_set_double (value, image->width);
+      g_value_set_double (value, image_data->width);
       break;
     case PROP_HEIGHT:
-      g_value_set_double (value, image->height);
+      g_value_set_double (value, image_data->height);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -257,44 +254,388 @@
 
 
 static void
-goo_canvas_image_set_property (GObject              *object,
+goo_canvas_image_get_property (GObject              *object,
 			       guint                 prop_id,
-			       const GValue         *value,
+			       GValue               *value,
 			       GParamSpec           *pspec)
 {
   GooCanvasImage *image = (GooCanvasImage*) object;
+
+  goo_canvas_image_get_common_property (object, image->image_data, prop_id,
+					value, pspec);
+}
+
+
+static void
+goo_canvas_image_set_common_property (GObject              *object,
+				      GooCanvasImageData   *image_data,
+				      guint                 prop_id,
+				      const GValue         *value,
+				      GParamSpec           *pspec)
+{
   GdkPixbuf *pixbuf;
 
   switch (prop_id)
     {
     case PROP_PATTERN:
-      cairo_pattern_destroy (image->pattern);
-      image->pattern = g_value_get_boxed (value);
-      cairo_pattern_reference (image->pattern);
+      cairo_pattern_destroy (image_data->pattern);
+      image_data->pattern = g_value_get_boxed (value);
+      cairo_pattern_reference (image_data->pattern);
       break;
     case PROP_X:
-      image->x = g_value_get_double (value);
+      image_data->x = g_value_get_double (value);
       break;
     case PROP_Y:
-      image->y = g_value_get_double (value);
+      image_data->y = g_value_get_double (value);
       break;
     case PROP_WIDTH:
-      image->width = g_value_get_double (value);
+      image_data->width = g_value_get_double (value);
       break;
     case PROP_HEIGHT:
-      image->height = g_value_get_double (value);
+      image_data->height = g_value_get_double (value);
       break;
     case PROP_PIXBUF:
-      cairo_pattern_destroy (image->pattern);
+      cairo_pattern_destroy (image_data->pattern);
       pixbuf = g_value_get_object (value);
-      image->pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
-      image->width = gdk_pixbuf_get_width (pixbuf);
-      image->height = gdk_pixbuf_get_height (pixbuf);
+      image_data->pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
+      image_data->width = gdk_pixbuf_get_width (pixbuf);
+      image_data->height = gdk_pixbuf_get_height (pixbuf);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+}
 
-  g_signal_emit_by_name (image, "changed", TRUE);
+
+static void
+goo_canvas_image_set_property (GObject              *object,
+			       guint                 prop_id,
+			       const GValue         *value,
+			       GParamSpec           *pspec)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+  GooCanvasImage *image = (GooCanvasImage*) object;
+
+  if (simple->model)
+    {
+      g_warning ("Can't set property of a canvas item with a model - set the model property instead");
+      return;
+    }
+
+  goo_canvas_image_set_common_property (object, image->image_data, prop_id,
+					value, pspec);
+  goo_canvas_item_simple_changed (simple, TRUE);
 }
+
+
+static GooCanvasItem*
+goo_canvas_image_get_item_at (GooCanvasItem  *item,
+			      gdouble         x,
+			      gdouble         y,
+			      cairo_t        *cr,
+			      gboolean        is_pointer_event,
+			      gboolean        parent_visible)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasImage *image = (GooCanvasImage*) simple;
+  GooCanvasImageData *image_data = image->image_data;
+  GooCanvasItem *found_item = item;
+  double user_x = x, user_y = y;
+
+  if (simple->need_update)
+    goo_canvas_item_ensure_updated (item);
+
+  /* Check if the item should receive events. Note that we don't take
+     image transparency into account here at present. */
+  if (is_pointer_event)
+    {
+      if (simple_data->pointer_events == GOO_CANVAS_EVENTS_NONE)
+	return NULL;
+      if (simple_data->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK
+	  && (!parent_visible
+	      || simple_data->visibility == GOO_CANVAS_ITEM_INVISIBLE
+	      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
+		  && simple->canvas->scale < simple_data->visibility_threshold)))
+	return NULL;
+    }
+
+  cairo_save (cr);
+
+  if (simple_data->transform)
+    cairo_transform (cr, simple_data->transform);
+
+  cairo_device_to_user (cr, &user_x, &user_y);
+
+  if (user_x < image_data->x || (user_x > image_data->x + image_data->width)
+      || user_y < image_data->y || (user_y > image_data->y + image_data->height))
+    found_item = NULL;
+
+  cairo_restore (cr);
+
+  return found_item;
+}
+
+
+static void
+goo_canvas_image_update  (GooCanvasItem      *item,
+			  gboolean            entire_tree,
+			  cairo_t            *cr,
+			  GooCanvasBounds    *bounds)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasImage *image = (GooCanvasImage*) item;
+  GooCanvasImageData *image_data = image->image_data;
+
+  if (entire_tree || simple->need_update)
+    {
+      simple->need_update = FALSE;
+
+      goo_canvas_item_simple_check_style (simple);
+
+      cairo_save (cr);
+      if (simple_data->transform)
+	cairo_transform (cr, simple_data->transform);
+
+      /* Request a redraw of the existing bounds. */
+      goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+
+      /* Compute the new bounds. */
+      simple->bounds.x1 = image_data->x;
+      simple->bounds.y1 = image_data->y;
+      simple->bounds.x2 = image_data->x + image_data->width;
+      simple->bounds.y2 = image_data->y + image_data->height;
+
+      goo_canvas_item_simple_user_bounds_to_device (simple, cr,
+						    &simple->bounds);
+
+      /* Request a redraw of the new bounds. */
+      goo_canvas_request_redraw (simple->canvas, &simple->bounds);
+
+      cairo_restore (cr);
+    }
+
+  *bounds = simple->bounds;
+}
+
+
+static void
+goo_canvas_image_paint (GooCanvasItem     *item,
+			cairo_t           *cr,
+			GooCanvasBounds   *bounds,
+			gdouble            scale)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasImage *image = (GooCanvasImage*) simple;
+  GooCanvasImageData *image_data = image->image_data;
+  cairo_matrix_t matrix;
+
+  if (!image_data->pattern)
+    return;
+
+  /* Check if the item should be visible. */
+  if (simple_data->visibility == GOO_CANVAS_ITEM_INVISIBLE
+      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
+	  && scale < simple_data->visibility_threshold))
+    return;
+
+  cairo_save (cr);
+  if (simple_data->transform)
+    cairo_transform (cr, simple_data->transform);
+
+  goo_canvas_style_set_fill_options (simple_data->style, cr);
+  cairo_set_source (cr, image_data->pattern);
+  cairo_matrix_init_translate (&matrix, -image_data->x, -image_data->y);
+  cairo_pattern_set_matrix (image_data->pattern, &matrix);
+  cairo_rectangle (cr, image_data->x, image_data->y,
+		   image_data->width, image_data->height);
+  cairo_fill (cr);
+
+  /* Using cairo_paint() is much slower, so I guess we shouldn't. */
+  /*cairo_paint (cr);*/
+
+  cairo_restore (cr);
+}
+
+
+static void
+goo_canvas_image_set_model    (GooCanvasItem      *item,
+			       GooCanvasItemModel *model)
+{
+  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItemIface *parent_iface = g_type_interface_peek_parent (iface);
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasImage *image = (GooCanvasImage*) item;
+  GooCanvasImageModel *emodel = (GooCanvasImageModel*) model;
+
+  /* If our data was allocated, free it. */
+  if (!simple->model)
+    {
+      cairo_pattern_destroy (image->image_data->pattern);
+      g_slice_free (GooCanvasImageData, image->image_data);
+    }
+
+  /* Now use the new model's data instead. */
+  image->image_data = &emodel->image_data;
+
+  /* Let the parent GooCanvasItemSimple code do the rest. */
+  parent_iface->set_model (item, model);
+}
+
+
+static void
+canvas_item_interface_init (GooCanvasItemIface *iface)
+{
+  iface->get_item_at = goo_canvas_image_get_item_at;
+  iface->update      = goo_canvas_image_update;
+  iface->paint       = goo_canvas_image_paint;
+  iface->set_model   = goo_canvas_image_set_model;
+}
+
+
+
+/*
+ * GooCanvasImageModel.
+ */
+
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void goo_canvas_image_model_finalize     (GObject            *object);
+static void goo_canvas_image_model_get_property (GObject            *object,
+						 guint               param_id,
+						 GValue             *value,
+						 GParamSpec         *pspec);
+static void goo_canvas_image_model_set_property (GObject            *object,
+						 guint               param_id,
+						 const GValue       *value,
+						 GParamSpec         *pspec);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasImageModel, goo_canvas_image_model,
+			 GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+						item_model_interface_init))
+
+
+static void
+goo_canvas_image_model_class_init (GooCanvasImageModelClass *klass)
+{
+  GObjectClass *gobject_class = (GObjectClass*) klass;
+
+  gobject_class->finalize     = goo_canvas_image_model_finalize;
+
+  gobject_class->get_property = goo_canvas_image_model_get_property;
+  gobject_class->set_property = goo_canvas_image_model_set_property;
+
+  goo_canvas_image_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_image_model_init (GooCanvasImageModel *emodel)
+{
+
+}
+
+
+GooCanvasItemModel*
+goo_canvas_image_model_new (GooCanvasItemModel *parent,
+			    GdkPixbuf          *pixbuf,
+			    gdouble             x,
+			    gdouble             y,
+			    ...)
+{
+  GooCanvasItemModel *model;
+  GooCanvasImageModel *imodel;
+  GooCanvasImageData *image_data;
+  const char *first_property;
+  va_list var_args;
+
+  model = g_object_new (GOO_TYPE_CANVAS_IMAGE_MODEL, NULL);
+  imodel = (GooCanvasImageModel*) model;
+
+  image_data = &imodel->image_data;
+  image_data->x = x;
+  image_data->y = y;
+
+  if (pixbuf)
+    {
+      image_data->pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
+      image_data->width = gdk_pixbuf_get_width (pixbuf);
+      image_data->height = gdk_pixbuf_get_height (pixbuf);
+    }
+
+  va_start (var_args, y);
+  first_property = va_arg (var_args, char*);
+  if (first_property)
+    g_object_set_valist ((GObject*) model, first_property, var_args);
+  va_end (var_args);
+
+  if (parent)
+    {
+      goo_canvas_item_model_add_child (parent, model, -1);
+      g_object_unref (model);
+    }
+
+  return model;
+}
+
+
+static void
+goo_canvas_image_model_finalize (GObject *object)
+{
+  GooCanvasImageModel *imodel = (GooCanvasImageModel*) object;
+
+  cairo_pattern_destroy (imodel->image_data.pattern);
+
+  G_OBJECT_CLASS (goo_canvas_image_model_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_image_model_get_property (GObject              *object,
+				     guint                 prop_id,
+				     GValue               *value,
+				     GParamSpec           *pspec)
+{
+  GooCanvasImageModel *imodel = (GooCanvasImageModel*) object;
+
+  goo_canvas_image_get_common_property (object, &imodel->image_data, prop_id,
+					value, pspec);
+}
+
+
+static void
+goo_canvas_image_model_set_property (GObject              *object,
+				     guint                 prop_id,
+				     const GValue         *value,
+				     GParamSpec           *pspec)
+{
+  GooCanvasImageModel *imodel = (GooCanvasImageModel*) object;
+
+  goo_canvas_image_set_common_property (object, &imodel->image_data, prop_id,
+					value, pspec);
+  g_signal_emit_by_name (imodel, "changed", TRUE);
+}
+
+
+static GooCanvasItem*
+goo_canvas_image_model_create_item (GooCanvasItemModel *model,
+				    GooCanvas          *canvas)
+{
+  GooCanvasItem *item;
+
+  item = g_object_new (GOO_TYPE_CANVAS_IMAGE, NULL);
+  goo_canvas_item_set_model (item, model);
+
+  return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+  iface->create_item    = goo_canvas_image_model_create_item;
+}
+

Index: goocanvasimage.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasimage.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- goocanvasimage.h	13 Apr 2006 16:06:04 -0000	1.2
+++ goocanvasimage.h	29 Nov 2006 18:40:53 -0000	1.3
@@ -13,6 +13,16 @@
 G_BEGIN_DECLS
 
 
+/* This is the data used by both model and view classes. */
+typedef struct _GooCanvasImageData   GooCanvasImageData;
+struct _GooCanvasImageData
+{
+  cairo_pattern_t *pattern;
+
+  gdouble x, y, width, height;
+};
+
+
 #define GOO_TYPE_CANVAS_IMAGE            (goo_canvas_image_get_type ())
 #define GOO_CANVAS_IMAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_IMAGE, GooCanvasImage))
 #define GOO_CANVAS_IMAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_IMAGE, GooCanvasImageClass))
@@ -31,11 +41,9 @@
  */
 struct _GooCanvasImage
 {
-  GooCanvasItemSimple parent;
-
-  cairo_pattern_t *pattern;
+  GooCanvasItemSimple parent_object;
 
-  gdouble x, y, width, height;
+  GooCanvasImageData *image_data;
 };
 
 struct _GooCanvasImageClass
@@ -44,13 +52,52 @@
 };
 
 
-GType           goo_canvas_image_get_type          (void) G_GNUC_CONST;
-GooCanvasItem*  goo_canvas_image_new               (GooCanvasItem *parent,
-						    GdkPixbuf     *pixbuf,
-						    gdouble        x,
-						    gdouble        y,
-						    const gchar   *first_property,
-						    ...);
+GType               goo_canvas_image_get_type  (void) G_GNUC_CONST;
+
+GooCanvasItem*      goo_canvas_image_new       (GooCanvasItem      *parent,
+						GdkPixbuf          *pixbuf,
+						gdouble             x,
+						gdouble             y,
+						...);
+
+
+
+#define GOO_TYPE_CANVAS_IMAGE_MODEL            (goo_canvas_image_model_get_type ())
+#define GOO_CANVAS_IMAGE_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_IMAGE_MODEL, GooCanvasImageModel))
+#define GOO_CANVAS_IMAGE_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_IMAGE_MODEL, GooCanvasImageModelClass))
+#define GOO_IS_CANVAS_IMAGE_MODEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_IMAGE_MODEL))
+#define GOO_IS_CANVAS_IMAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_IMAGE_MODEL))
+#define GOO_CANVAS_IMAGE_MODEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_IMAGE_MODEL, GooCanvasImageModelClass))
+
+
+typedef struct _GooCanvasImageModel       GooCanvasImageModel;
+typedef struct _GooCanvasImageModelClass  GooCanvasImageModelClass;
+
+/**
+ * GooCanvasImageModel
+ *
+ * The #GooCanvasImageModel-struct struct contains private data only.
+ */
+struct _GooCanvasImageModel
+{
+  GooCanvasItemModelSimple parent_object;
+
+  GooCanvasImageData image_data;
+};
+
+struct _GooCanvasImageModelClass
+{
+  GooCanvasItemModelSimpleClass parent_class;
+};
+
+
+GType               goo_canvas_image_model_get_type  (void) G_GNUC_CONST;
+
+GooCanvasItemModel* goo_canvas_image_model_new (GooCanvasItemModel *parent,
+						GdkPixbuf          *pixbuf,
+						gdouble             x,
+						gdouble             y,
+						...);
 
 
 G_END_DECLS

--- goocanvasimageview.c DELETED ---

--- goocanvasimageview.h DELETED ---

Index: goocanvasitem.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- goocanvasitem.c	12 Oct 2006 12:53:47 -0000	1.10
+++ goocanvasitem.c	29 Nov 2006 18:40:53 -0000	1.11
@@ -16,21 +16,37 @@
 #include <config.h>
 #include <math.h>
 #include <glib/gi18n-lib.h>
+#include <gobject/gobjectnotifyqueue.c>
+#include <gobject/gvaluecollector.h>
 #include <gtk/gtk.h>
 #include "goocanvasprivate.h"
-#include <goocanvasenumtypes.h>
 #include "goocanvasitem.h"
+#include "goocanvas.h"
 #include "goocanvasutils.h"
[...1157 lines suppressed...]
+ *           freed with g_free().
+ *
+ * Returns all child properties of a canvas item class.
+ */
+GParamSpec**
+goo_canvas_item_class_list_child_properties (GObjectClass *iclass,
+					     guint        *n_properties)
+{
+  GParamSpec **pspecs;
+  guint n;
+
+  g_return_val_if_fail (G_IS_OBJECT_CLASS (iclass), NULL);
+
+  pspecs = g_param_spec_pool_list (_goo_canvas_item_child_property_pool,
+				   G_OBJECT_CLASS_TYPE (iclass), &n);
+  if (n_properties)
+    *n_properties = n;
+
+  return pspecs;
+}

Index: goocanvasitem.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- goocanvasitem.h	19 Jul 2006 13:52:33 -0000	1.7
+++ goocanvasitem.h	29 Nov 2006 18:40:53 -0000	1.8
@@ -8,6 +8,7 @@
 #define __GOO_CANVAS_ITEM_H__
 
 #include <gtk/gtk.h>
+#include "goocanvasstyle.h"
 
 G_BEGIN_DECLS
 
@@ -57,9 +58,8 @@
 
 
 /* Workaround for circular dependencies. Include this file first. */
-typedef struct _GooCanvasModel      GooCanvasModel;
-typedef struct _GooCanvasView       GooCanvasView;
-typedef struct _GooCanvasItemView   GooCanvasItemView;
+typedef struct _GooCanvas           GooCanvas;
+typedef struct _GooCanvasItemModel  GooCanvasItemModel;
 
 
 /**
@@ -89,117 +89,233 @@
 
   /*< public >*/
   /* Virtual methods that group items must implement. */
-  GooCanvasModel*      (* get_model)	   (GooCanvasItem       *item);
-  gint		       (* get_n_children)  (GooCanvasItem       *group);
-  GooCanvasItem*       (* get_child)	   (GooCanvasItem       *group,
+  GooCanvas*           (* get_canvas)	   (GooCanvasItem       *item);
+  void                 (* set_canvas)	   (GooCanvasItem       *item,
+					    GooCanvas           *canvas);
+  gint		       (* get_n_children)  (GooCanvasItem       *item);
+  GooCanvasItem*       (* get_child)	   (GooCanvasItem       *item,
 					    gint                 child_num);
+  void                 (* request_update)  (GooCanvasItem       *item);
 
   /* Virtual methods that group items may implement. */
-  void                 (* add_child)       (GooCanvasItem       *group,
+  void                 (* add_child)       (GooCanvasItem       *item,
 					    GooCanvasItem       *child,
 					    gint                 position);
-  void                 (* move_child)      (GooCanvasItem       *group,
+  void                 (* move_child)      (GooCanvasItem       *item,
 					    gint                 old_position,
 					    gint                 new_position);
-  void                 (* remove_child)    (GooCanvasItem       *group,
+  void                 (* remove_child)    (GooCanvasItem       *item,
 					    gint                 child_num);
+  void                 (*get_child_property) (GooCanvasItem     *item,
+					      GooCanvasItem     *child,
+					      guint              property_id,
+					      GValue            *value,
+					      GParamSpec        *pspec);
+  void                 (*set_child_property) (GooCanvasItem     *item,
+					      GooCanvasItem     *child,
+					      guint              property_id,
+					      const GValue      *value,
+					      GParamSpec        *pspec);
 
   /* Virtual methods that all canvas items must implement. */
-  GooCanvasItem*       (* get_parent)	  (GooCanvasItem       *item);
-  void                 (* set_parent)	  (GooCanvasItem       *item,
-					   GooCanvasItem       *parent);
+  GooCanvasItem*       (* get_parent)	   (GooCanvasItem       *item);
+  void                 (* set_pa