[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
- Previous message: [cairo-commit] goocanvas/src goocanvas.c, NONE,
1.1 goocanvasitemmodel.c, NONE, 1.1 goocanvasitemmodel.h, NONE,
1.1 goocanvasstyle.c, NONE, 1.1 goocanvasstyle.h, NONE,
1.1 goocanvaswidget.c, NONE, 1.1 goocanvaswidget.h, NONE, 1.1
- Next message: [cairo-commit] goocanvas configure.in,1.9,1.10
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
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_parent) (GooCanvasItem *item,
+ GooCanvasItem *parent);
+ void (* get_bounds) (GooCanvasItem *item,
+ GooCanvasBounds *bounds);
+ GooCanvasItem* (* get_item_at) (GooCanvasItem *item,
+ gdouble x,
+ gdouble y,
+ cairo_t *cr,
+ gboolean is_pointer_event,
+ gboolean parent_is_visible);
+ void (* update) (GooCanvasItem *item,
+ gboolean entire_tree,
+ cairo_t *cr,
+ GooCanvasBounds *bounds);
+ void (* paint) (GooCanvasItem *item,
+ cairo_t *cr,
+ GooCanvasBounds *bounds,
+ gdouble scale);
- cairo_matrix_t* (* get_transform) (GooCanvasItem *item);
- void (* set_transform) (GooCanvasItem *item,
- cairo_matrix_t *matrix);
+ /* Virtual methods that canvas items may implement. */
+ cairo_matrix_t* (* get_transform) (GooCanvasItem *item);
+ void (* set_transform) (GooCanvasItem *item,
+ cairo_matrix_t *matrix);
+ GooCanvasStyle* (* get_style) (GooCanvasItem *item);
+ void (* set_style) (GooCanvasItem *item,
+ GooCanvasStyle *style);
+ gboolean (* is_visible) (GooCanvasItem *item);
+
+ /* Virtual methods that model/view items must implement. */
+ GooCanvasItemModel* (* get_model) (GooCanvasItem *item);
+ void (* set_model) (GooCanvasItem *item,
+ GooCanvasItemModel *model);
- GooCanvasItemView* (* create_view) (GooCanvasItem *item,
- GooCanvasView *canvas_view,
- GooCanvasItemView *parent_view);
/* Signals. */
- void (* child_added) (GooCanvasItem *item,
- gint child_num);
- void (* child_moved) (GooCanvasItem *item,
- gint old_child_num,
- gint new_child_num);
- void (* child_removed) (GooCanvasItem *item,
- gint child_num);
- void (* changed) (GooCanvasItem *item,
- gboolean recompute_bounds);
+ gboolean (* enter_notify_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventCrossing *event);
+ gboolean (* leave_notify_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventCrossing *event);
+ gboolean (* motion_notify_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventMotion *event);
+ gboolean (* button_press_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventButton *event);
+ gboolean (* button_release_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventButton *event);
+ gboolean (* focus_in_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventFocus *event);
+ gboolean (* focus_out_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventFocus *event);
+ gboolean (* key_press_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventKey *event);
+ gboolean (* key_release_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventKey *event);
+ gboolean (* grab_broken_event) (GooCanvasItem *item,
+ GooCanvasItem *target,
+ GdkEventGrabBroken *event);
+ void (* child_notify) (GooCanvasItem *item,
+ GParamSpec *pspec);
};
-GType goo_canvas_item_get_type (void) G_GNUC_CONST;
+GType goo_canvas_item_get_type (void) G_GNUC_CONST;
-GooCanvasItem * goo_canvas_item_new (GooCanvasItem *parent,
- GType type,
- const gchar *first_property,
- ...);
/*
* Group functions - these should only be called on container items.
*/
-gint goo_canvas_item_get_n_children (GooCanvasItem *group);
-GooCanvasItem* goo_canvas_item_get_child (GooCanvasItem *group,
- gint child_num);
-void goo_canvas_item_add_child (GooCanvasItem *group,
- GooCanvasItem *item,
- gint position);
-void goo_canvas_item_move_child (GooCanvasItem *group,
- gint old_position,
- gint new_position);
-void goo_canvas_item_remove_child (GooCanvasItem *group,
- gint child_num);
-gint goo_canvas_item_find_child (GooCanvasItem *group,
- GooCanvasItem *child);
+gint goo_canvas_item_get_n_children (GooCanvasItem *item);
+GooCanvasItem* goo_canvas_item_get_child (GooCanvasItem *item,
+ gint child_num);
+gint goo_canvas_item_find_child (GooCanvasItem *item,
+ GooCanvasItem *child);
+void goo_canvas_item_add_child (GooCanvasItem *item,
+ GooCanvasItem *child,
+ gint position);
+void goo_canvas_item_move_child (GooCanvasItem *item,
+ gint old_position,
+ gint new_position);
+void goo_canvas_item_remove_child (GooCanvasItem *item,
+ gint child_num);
+
+void goo_canvas_item_get_child_properties (GooCanvasItem *item,
+ GooCanvasItem *child,
+ ...) G_GNUC_NULL_TERMINATED;
+void goo_canvas_item_set_child_properties (GooCanvasItem *item,
+ GooCanvasItem *child,
+ ...) G_GNUC_NULL_TERMINATED;
+void goo_canvas_item_get_child_properties_valist (GooCanvasItem *item,
+ GooCanvasItem *child,
+ va_list var_args);
+void goo_canvas_item_set_child_properties_valist (GooCanvasItem *item,
+ GooCanvasItem *child,
+ va_list var_args);
+
/*
* Item functions - these are safe to call on all items.
*/
-GooCanvasModel* goo_canvas_item_get_model (GooCanvasItem *item);
-GooCanvasItem* goo_canvas_item_get_parent (GooCanvasItem *item);
-void goo_canvas_item_set_parent (GooCanvasItem *item,
- GooCanvasItem *parent);
-gboolean goo_canvas_item_is_container (GooCanvasItem *item);
+GooCanvas* goo_canvas_item_get_canvas (GooCanvasItem *item);
+void goo_canvas_item_set_canvas (GooCanvasItem *item,
+ GooCanvas *canvas);
+GooCanvasItem* goo_canvas_item_get_parent (GooCanvasItem *item);
+void goo_canvas_item_set_parent (GooCanvasItem *item,
+ GooCanvasItem *parent);
+gboolean goo_canvas_item_is_container (GooCanvasItem *item);
-void goo_canvas_item_raise (GooCanvasItem *item,
- GooCanvasItem *above);
-void goo_canvas_item_lower (GooCanvasItem *item,
- GooCanvasItem *below);
+void goo_canvas_item_raise (GooCanvasItem *item,
+ GooCanvasItem *above);
+void goo_canvas_item_lower (GooCanvasItem *item,
+ GooCanvasItem *below);
-cairo_matrix_t* goo_canvas_item_get_transform (GooCanvasItem *item);
-void goo_canvas_item_set_transform (GooCanvasItem *item,
- cairo_matrix_t *matrix);
+cairo_matrix_t* goo_canvas_item_get_transform (GooCanvasItem *item);
+void goo_canvas_item_set_transform (GooCanvasItem *item,
+ cairo_matrix_t *matrix);
+
+void goo_canvas_item_translate (GooCanvasItem *item,
+ double tx,
+ double ty);
+void goo_canvas_item_scale (GooCanvasItem *item,
+ double sx,
+ double sy);
+void goo_canvas_item_rotate (GooCanvasItem *item,
+ double degrees,
+ double cx,
+ double cy);
+void goo_canvas_item_skew_x (GooCanvasItem *item,
+ double degrees,
+ double cx,
+ double cy);
+void goo_canvas_item_skew_y (GooCanvasItem *item,
+ double degrees,
+ double cx,
+ double cy);
+
+GooCanvasStyle* goo_canvas_item_get_style (GooCanvasItem *item);
+void goo_canvas_item_set_style (GooCanvasItem *item,
+ GooCanvasStyle *style);
+
+void goo_canvas_item_animate (GooCanvasItem *item,
+ double x,
+ double y,
+ double scale,
+ double degrees,
+ gint duration,
+ gint step_time,
+ GooCanvasAnimateType type);
+void goo_canvas_item_stop_animation (GooCanvasItem *item);
+
+
+
+void goo_canvas_item_get_bounds (GooCanvasItem *item,
+ GooCanvasBounds *bounds);
+GooCanvasItem* goo_canvas_item_get_item_at (GooCanvasItem *item,
+ gdouble x,
+ gdouble y,
+ cairo_t *cr,
+ gboolean is_pointer_event,
+ gboolean parent_is_visible);
+gboolean goo_canvas_item_is_visible (GooCanvasItem *item);
+
+GooCanvasItemModel* goo_canvas_item_get_model (GooCanvasItem *item);
+void goo_canvas_item_set_model (GooCanvasItem *item,
+ GooCanvasItemModel *model);
+
+void goo_canvas_item_request_update (GooCanvasItem *item);
+void goo_canvas_item_ensure_updated (GooCanvasItem *item);
+void goo_canvas_item_update (GooCanvasItem *item,
+ gboolean entire_tree,
+ cairo_t *cr,
+ GooCanvasBounds *bounds);
+void goo_canvas_item_paint (GooCanvasItem *item,
+ cairo_t *cr,
+ GooCanvasBounds *bounds,
+ gdouble scale);
+
+
+/*
+ * Functions to support child properties when implementing new canvas items.
+ */
+void goo_canvas_item_class_install_child_property (GObjectClass *iclass,
+ guint property_id,
+ GParamSpec *pspec);
+GParamSpec* goo_canvas_item_class_find_child_property (GObjectClass *iclass,
+ const gchar *property_name);
+GParamSpec** goo_canvas_item_class_list_child_properties (GObjectClass *iclass,
+ guint *n_properties);
-void goo_canvas_item_translate (GooCanvasItem *item,
- double tx,
- double ty);
-void goo_canvas_item_scale (GooCanvasItem *item,
- double sx,
- double sy);
-void goo_canvas_item_rotate (GooCanvasItem *item,
- double degrees,
- double cx,
- double cy);
-void goo_canvas_item_skew_x (GooCanvasItem *item,
- double degrees,
- double cx,
- double cy);
-void goo_canvas_item_skew_y (GooCanvasItem *item,
- double degrees,
- double cx,
- double cy);
-void goo_canvas_item_animate (GooCanvasItem *item,
- double x,
- double y,
- double scale,
- double degrees,
- gint duration,
- gint step_time,
- GooCanvasAnimateType type);
-void goo_canvas_item_stop_animation (GooCanvasItem *item);
G_END_DECLS
Index: goocanvasitemsimple.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitemsimple.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- goocanvasitemsimple.c 15 Aug 2006 10:08:25 -0000 1.14
+++ goocanvasitemsimple.c 29 Nov 2006 18:40:53 -0000 1.15
@@ -1,29 +1,30 @@
/*
- * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
* Released under the GNU LGPL license. See COPYING for details.
*
- * goocanvasitemsimple.c - abstract base class for simple items with styles.
+ * goocanvasitemsimple.c - abstract base class for simple item views.
*/
/**
* SECTION:goocanvasitemsimple
[...1690 lines suppressed...]
+ else
+ {
+ simple_data->style = NULL;
+ simple_data->own_style = FALSE;
+ }
+
+ g_signal_emit_by_name (smodel, "changed", TRUE);
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+ iface->get_parent = goo_canvas_item_model_simple_get_parent;
+ iface->set_parent = goo_canvas_item_model_simple_set_parent;
+ iface->get_transform = goo_canvas_item_model_simple_get_transform;
+ iface->set_transform = goo_canvas_item_model_simple_set_transform;
+ iface->get_style = goo_canvas_item_model_simple_get_style;
+ iface->set_style = goo_canvas_item_model_simple_set_style;
+}
Index: goocanvasitemsimple.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitemsimple.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- goocanvasitemsimple.h 8 Jun 2006 08:45:27 -0000 1.10
+++ goocanvasitemsimple.h 29 Nov 2006 18:40:53 -0000 1.11
@@ -1,105 +1,49 @@
/*
- * GooCanvas. Copyright (C) 2005 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
* Released under the GNU LGPL license. See COPYING for details.
*
- * goocanvasitemsimple.h - abstract base class for simple items with styles.
+ * goocanvasitemsimple.h - abstract base class for simple items.
*/
#ifndef __GOO_CANVAS_ITEM_SIMPLE_H__
#define __GOO_CANVAS_ITEM_SIMPLE_H__
#include <gtk/gtk.h>
#include "goocanvasitem.h"
+#include "goocanvasitemmodel.h"
+#include "goocanvasstyle.h"
#include "goocanvasutils.h"
G_BEGIN_DECLS
-/**
- * GooCanvasStyleValuesMask
- * @GOO_CANVAS_STYLE_STROKE_PATTERN: the stroke pattern has been set.
- * @GOO_CANVAS_STYLE_FILL_PATTERN: the fill pattern has been set.
- * @GOO_CANVAS_STYLE_FILL_RULE: the fill rule has been set.
- * @GOO_CANVAS_STYLE_OPERATOR: the operator has been set.
- * @GOO_CANVAS_STYLE_ANTIALIAS: the antialias setting has been set.
- * @GOO_CANVAS_STYLE_LINE_WIDTH: the line width has been set.
- * @GOO_CANVAS_STYLE_LINE_CAP: the line cap style has been set.
- * @GOO_CANVAS_STYLE_LINE_JOIN: the line join style has been set.
- * @GOO_CANVAS_STYLE_LINE_JOIN_MITER_LIMIT: the miter limit of line joins has
- * been set.
- * @GOO_CANVAS_STYLE_LINE_DASH: the line dash pattern has been set.
- *
- * Specifies which fields of a #GooCanvasStyle object have been set.
- */
-typedef enum
+/* This is the data used by both model and view classes. */
+typedef struct _GooCanvasItemSimpleData GooCanvasItemSimpleData;
+struct _GooCanvasItemSimpleData
{
- GOO_CANVAS_STYLE_STROKE_PATTERN = 1 << 0,
- GOO_CANVAS_STYLE_FILL_PATTERN = 1 << 1,
- GOO_CANVAS_STYLE_FILL_RULE = 1 << 2,
- GOO_CANVAS_STYLE_OPERATOR = 1 << 3,
- GOO_CANVAS_STYLE_ANTIALIAS = 1 << 4,
-
- GOO_CANVAS_STYLE_LINE_WIDTH = 1 << 5,
- GOO_CANVAS_STYLE_LINE_CAP = 1 << 6,
- GOO_CANVAS_STYLE_LINE_JOIN = 1 << 7,
- GOO_CANVAS_STYLE_LINE_JOIN_MITER_LIMIT = 1 << 8,
- GOO_CANVAS_STYLE_LINE_DASH = 1 << 9
-} GooCanvasStyleValuesMask;
-
+ /* The style to draw with. */
+ GooCanvasStyle *style;
-/* These are the standard cairo drawing attributes. We allow the style to
- be shared between multiple objects to avoid wasting memory. */
-/**
- * GooCanvasStyle
- * @ref_count: the reference count of the struct.
- * @mask: a mask specifying which fields of the #GooCanvasStyle have been set.
- * @stroke_pattern: the stroke pattern (or color).
- * @fill_pattern: the fill pattern (or color).
- * @line_width: the line width.
- * @line_join_miter_limit: the minimum angle in degrees at which the miter
- * join style will be used. For smaller angles a bevel join is used instead.
- * @dash: the dash pattern.
- * @fill_rule: the fill rule.
- * @op: the drawing operator.
- * @antialias: the type of antialiasing to do.
- * @line_cap: the line cap style.
- * @line_join: the line join style.
- *
- * #GooCanvasStyle describes the style in which an item is to be drawn, e.g.
- * its stroke and fill colors or patterns, and its line width and style.
- */
-typedef struct _GooCanvasStyle GooCanvasStyle;
-struct _GooCanvasStyle
-{
- int ref_count;
+ /* The transformation matrix of the item, or NULL. */
+ cairo_matrix_t *transform;
- /* This specifies which fields are actually set. If the STROKE_PATTERN bit
- is set, and stroke_pattern is NULL, no stroke will be drawn. */
- GooCanvasStyleValuesMask mask;
+ /* 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;
- cairo_pattern_t *stroke_pattern;
- cairo_pattern_t *fill_pattern;
+ /* Whether the item is visible, invisible, or visible above a given scale. */
+ GooCanvasItemVisibility visibility : 2;
- double line_width, line_join_miter_limit;
+ /* What events the item should receive. */
+ GooCanvasPointerEvents pointer_events : 4;
- GooCanvasLineDash *dash;
+ /* If the item can take the keyboard focus. */
+ guint can_focus : 1;
- /* We use bitmasks here to cut down on memory use a bit. I've given each
- field a few bits more than it needs to allow for new values. */
- cairo_fill_rule_t fill_rule : 3;
- cairo_operator_t op : 6;
- cairo_antialias_t antialias : 4;
- cairo_line_cap_t line_cap : 4;
- cairo_line_join_t line_join : 4;
+ /* If the item has its own style, rather than using its parents. */
+ guint own_style : 1;
};
-#define GOO_TYPE_CANVAS_STYLE (goo_canvas_style_get_type ())
-GType goo_canvas_style_get_type (void);
-GooCanvasStyle* goo_canvas_style_new (void);
-GooCanvasStyle* goo_canvas_style_ref (GooCanvasStyle *style);
-void goo_canvas_style_unref (GooCanvasStyle *style);
-
-
#define GOO_TYPE_CANVAS_ITEM_SIMPLE (goo_canvas_item_simple_get_type ())
#define GOO_CANVAS_ITEM_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ITEM_SIMPLE, GooCanvasItemSimple))
#define GOO_CANVAS_ITEM_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ITEM_SIMPLE, GooCanvasItemSimpleClass))
@@ -111,6 +55,8 @@
typedef struct _GooCanvasItemSimple GooCanvasItemSimple;
typedef struct _GooCanvasItemSimpleClass GooCanvasItemSimpleClass;
+typedef struct _GooCanvasItemModelSimple GooCanvasItemModelSimple;
+
/**
* GooCanvasItemSimple
*
@@ -120,59 +66,101 @@
{
GObject parent_object;
+ /* The canvas. */
+ GooCanvas *canvas;
+
/* The parent item. */
GooCanvasItem *parent;
- /* The style to draw with. */
- GooCanvasStyle *style;
-
- /* The transformation matrix, or NULL. */
- cairo_matrix_t *transform;
+ /* The model, if the canvas is in model/view mode, or NULL. */
+ GooCanvasItemModelSimple *model;
- /* Whether the item is visible, invisible, or visible above a given scale. */
- GooCanvasItemVisibility visibility;
+ /* The data shared between the model & view classes. */
+ GooCanvasItemSimpleData *simple_data;
- /* 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 bounds of the item, relative to the entire canvas. */
+ GooCanvasBounds bounds;
- /* What events the item should receive. */
- GooCanvasPointerEvents pointer_events;
+ /* If the item needs to recompute its bounds and redraw. */
+ guint need_update : 1;
- /* The title and description of the item for accessibility. */
- gchar *title;
- gchar *description;
+ /* If all descendants need to be updated. */
+ guint need_entire_subtree_update : 1;
};
struct _GooCanvasItemSimpleClass
{
GObjectClass parent_class;
+
+ /* Virtual methods. */
+ void (* create_path) (GooCanvasItemSimple *item,
+ cairo_t *cr);
};
-GType goo_canvas_item_simple_get_type (void) G_GNUC_CONST;
+GType goo_canvas_item_simple_get_type (void) G_GNUC_CONST;
-void goo_canvas_item_simple_set_style (GooCanvasItemSimple *item,
- GooCanvasStyle *style);
+void goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *item,
+ cairo_t *cr,
+ GooCanvasBounds *bounds);
+void goo_canvas_item_simple_user_bounds_to_device (GooCanvasItemSimple *item,
+ cairo_t *cr,
+ GooCanvasBounds *bounds);
+gboolean goo_canvas_item_simple_check_in_path (GooCanvasItemSimple *item,
+ gdouble x,
+ gdouble y,
+ cairo_t *cr,
+ GooCanvasPointerEvents pointer_events);
+void goo_canvas_item_simple_paint_path (GooCanvasItemSimple *item,
+ cairo_t *cr);
-void goo_canvas_item_simple_set_fill_options (GooCanvasItemSimple *item,
- cairo_t *cr);
-void goo_canvas_item_simple_set_stroke_options (GooCanvasItemSimple *item,
- cairo_t *cr);
-void goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *item,
- cairo_t *cr,
- GooCanvasBounds *bounds);
-void goo_canvas_item_simple_user_bounds_to_device (GooCanvasItemSimple *item,
- cairo_t *cr,
- GooCanvasBounds *bounds);
-gboolean goo_canvas_item_simple_check_in_path (GooCanvasItemSimple *item,
- gdouble x,
- gdouble y,
- cairo_t *cr,
- GooCanvasPointerEvents pointer_events);
-void goo_canvas_item_simple_paint_path (GooCanvasItemSimple *item,
- cairo_t *cr);
+void goo_canvas_item_simple_changed (GooCanvasItemSimple *item,
+ gboolean recompute_bounds);
+void goo_canvas_item_simple_check_style (GooCanvasItemSimple *item);
+
+
+
+
+
+#define GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE (goo_canvas_item_model_simple_get_type ())
+#define GOO_CANVAS_ITEM_MODEL_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE, GooCanvasItemModelSimple))
+#define GOO_CANVAS_ITEM_MODEL_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE, GooCanvasItemModelSimpleClass))
+#define GOO_IS_CANVAS_ITEM_MODEL_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE))
+#define GOO_IS_CANVAS_ITEM_MODEL_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE))
+#define GOO_CANVAS_ITEM_MODEL_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE, GooCanvasItemModelSimpleClass))
+
+
+typedef struct _GooCanvasItemModelSimpleClass GooCanvasItemModelSimpleClass;
+
+/**
+ * GooCanvasItemModelSimple
+ *
+ * The #GooCanvasItemModelSimple-struct struct contains private data only.
+ */
+struct _GooCanvasItemModelSimple
+{
+ GObject parent_object;
+
+ /* The parent model. */
+ GooCanvasItemModel *parent;
+
+ /* The data shared between the model & view classes. */
+ GooCanvasItemSimpleData simple_data;
+
+ /* The title and description of the item for accessibility. */
+ gchar *title;
+ gchar *description;
+};
+
+
+struct _GooCanvasItemModelSimpleClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType goo_canvas_item_model_simple_get_type (void) G_GNUC_CONST;
G_END_DECLS
--- goocanvasitemview.c DELETED ---
--- goocanvasitemview.h DELETED ---
--- goocanvasitemviewsimple.c DELETED ---
--- goocanvasitemviewsimple.h DELETED ---
--- goocanvasmodel.c DELETED ---
--- goocanvasmodel.h DELETED ---
--- goocanvasmodelsimple.c DELETED ---
--- goocanvasmodelsimple.h DELETED ---
Index: goocanvaspath.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaspath.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- goocanvaspath.c 12 Oct 2006 10:33:27 -0000 1.7
+++ goocanvaspath.c 29 Nov 2006 18:40:53 -0000 1.8
@@ -31,13 +31,13 @@
*
* To respond to events such as mouse clicks on the path you must connect
* to the signal handlers of the corresponding #GooCanvasPathView 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 <math.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include "goocanvaspath.h"
-#include "goocanvaspathview.h"
enum {
@@ -46,33 +46,28 @@
PROP_DATA,
};
-static void goo_canvas_path_finalize (GObject *object);
-static void item_interface_init (GooCanvasItemIface *iface);
-static void goo_canvas_path_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-static void goo_canvas_path_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
+static void canvas_item_interface_init (GooCanvasItemIface *iface);
+static void goo_canvas_path_finalize (GObject *object);
+static void goo_canvas_path_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void goo_canvas_path_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void goo_canvas_path_create_path (GooCanvasItemSimple *simple,
+ cairo_t *cr);
G_DEFINE_TYPE_WITH_CODE (GooCanvasPath, goo_canvas_path,
GOO_TYPE_CANVAS_ITEM_SIMPLE,
G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
- item_interface_init))
+ canvas_item_interface_init))
static void
-goo_canvas_path_class_init (GooCanvasPathClass *klass)
+goo_canvas_path_install_common_properties (GObjectClass *gobject_class)
{
- GObjectClass *gobject_class = (GObjectClass*) klass;
-
- gobject_class->finalize = goo_canvas_path_finalize;
-
- gobject_class->get_property = goo_canvas_path_get_property;
- gobject_class->set_property = goo_canvas_path_set_property;
-
/**
* GooCanvasPath:data
*
@@ -90,38 +85,26 @@
static void
-goo_canvas_path_init (GooCanvasPath *path)
+goo_canvas_path_class_init (GooCanvasPathClass *klass)
{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+ GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
-}
-
+ gobject_class->finalize = goo_canvas_path_finalize;
-static void
-goo_canvas_path_finalize (GObject *object)
-{
- GooCanvasPath *path = (GooCanvasPath*) object;
+ gobject_class->get_property = goo_canvas_path_get_property;
+ gobject_class->set_property = goo_canvas_path_set_property;
- if (path->commands)
- g_array_free (path->commands, TRUE);
+ simple_class->create_path = goo_canvas_path_create_path;
- G_OBJECT_CLASS (goo_canvas_path_parent_class)->finalize (object);
+ goo_canvas_path_install_common_properties (gobject_class);
}
static void
-goo_canvas_path_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+goo_canvas_path_init (GooCanvasPath *path)
{
- /*GooCanvasPath *path = (GooCanvasPath*) object;*/
-
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ path->path_commands = g_array_new (0, 0, sizeof (GooCanvasPathCommand));
}
@@ -186,18 +169,18 @@
static void
-goo_canvas_path_parse_data (GooCanvasPath *path,
- const gchar *path_data)
+goo_canvas_path_parse_data (GArray *path_commands,
+ const gchar *path_data)
{
GooCanvasPathCommand cmd;
gchar *pos, command = 0, next_command;
gboolean error = FALSE;
- /* Free the current path data. */
- if (path->commands)
- g_array_free (path->commands, TRUE);
+ /* Clear any current commands. */
+ g_array_set_size (path_commands, 0);
- path->commands = g_array_new (0, 0, sizeof (GooCanvasPathCommand));
+ if (!path_data)
+ return;
pos = (gchar*) path_data;
for (;;)
@@ -338,50 +321,11 @@
if (error)
return;
- g_array_append_val (path->commands, cmd);
+ g_array_append_val (path_commands, cmd);
}
}
-static void
-goo_canvas_path_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GooCanvasPath *path = (GooCanvasPath*) object;
-
- switch (prop_id)
- {
- case PROP_DATA:
- goo_canvas_path_parse_data (path, g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
- g_signal_emit_by_name (path, "changed", TRUE);
-}
-
-
-static GooCanvasItemView*
-goo_canvas_path_create_view (GooCanvasItem *item,
- GooCanvasView *canvas_view,
- GooCanvasItemView *parent_view)
-{
- return goo_canvas_path_view_new (canvas_view, parent_view,
- (GooCanvasPath*) item);
-}
-
-
-static void
-item_interface_init (GooCanvasItemIface *iface)
-{
- iface->create_view = goo_canvas_path_create_view;
-}
-
-
/**
* goo_canvas_path_new:
* @parent: the parent item, or %NULL. If a parent is specified, it will assume
@@ -436,19 +380,18 @@
{
GooCanvasItem *item;
GooCanvasPath *path;
+ const char *first_property;
va_list var_args;
- const char *first_arg_name;
item = g_object_new (GOO_TYPE_CANVAS_PATH, NULL);
- path = GOO_CANVAS_PATH (item);
+ path = (GooCanvasPath*) item;
- goo_canvas_path_parse_data (path, path_data);
+ goo_canvas_path_parse_data (path->path_commands, path_data);
va_start (var_args, path_data);
-
- first_arg_name = va_arg (var_args, char*);
- g_object_set_valist (G_OBJECT (item), first_arg_name, var_args);
-
+ 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)
@@ -461,3 +404,668 @@
}
+static void
+goo_canvas_path_finalize (GObject *object)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasPath *path = (GooCanvasPath*) object;
+
+ if (!simple->model)
+ g_array_free (path->path_commands, TRUE);
+ path->path_commands = NULL;
+
+ G_OBJECT_CLASS (goo_canvas_path_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_path_get_common_property (GObject *object,
+ GArray *path_commands,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+goo_canvas_path_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasPath *path = (GooCanvasPath*) object;
+
+ goo_canvas_path_get_common_property (object, path->path_commands, prop_id,
+ value, pspec);
+}
+
+
+static void
+goo_canvas_path_set_common_property (GObject *object,
+ GArray *path_commands,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_DATA:
+ goo_canvas_path_parse_data (path_commands, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+goo_canvas_path_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasPath *path = (GooCanvasPath*) 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_path_set_common_property (object, path->path_commands, prop_id,
+ value, pspec);
+ goo_canvas_item_simple_changed (simple, TRUE);
+}
+
+
+static void
+do_curve_to (GooCanvasPathCommand *cmd,
+ cairo_t *cr,
+ gdouble *x,
+ gdouble *y,
+ gdouble *last_control_point_x,
+ gdouble *last_control_point_y)
+{
+ if (cmd->curve.relative)
+ {
+ cairo_curve_to (cr, *x + cmd->curve.x1, *y + cmd->curve.y1,
+ *x + cmd->curve.x2, *y + cmd->curve.y2,
+ *x + cmd->curve.x, *y + cmd->curve.y);
+ *last_control_point_x = *x + cmd->curve.x2;
+ *last_control_point_y = *y + cmd->curve.y2;
+ *x += cmd->curve.x;
+ *y += cmd->curve.y;
+ }
+ else
+ {
+ cairo_curve_to (cr, cmd->curve.x1, cmd->curve.y1,
+ cmd->curve.x2, cmd->curve.y2,
+ cmd->curve.x, cmd->curve.y);
+ *last_control_point_x = cmd->curve.x2;
+ *last_control_point_y = cmd->curve.y2;
+ *x = cmd->curve.x;
+ *y = cmd->curve.y;
+ }
+}
+
+
+static void
+do_smooth_curve_to (GooCanvasPathCommand *cmd,
+ GooCanvasPathCommandType prev_cmd_type,
+ cairo_t *cr,
+ gdouble *x,
+ gdouble *y,
+ gdouble *last_control_point_x,
+ gdouble *last_control_point_y)
+{
+ gdouble x1, y1;
+
+ /* If the last command was a curveto or smooth curveto, we use the
+ reflection of the last control point about the current point as
+ the first control point of this curve. Otherwise we use the
+ current point as the first control point. */
+ if (prev_cmd_type == GOO_CANVAS_PATH_CURVE_TO
+ || prev_cmd_type == GOO_CANVAS_PATH_SMOOTH_CURVE_TO)
+ {
+ x1 = *x + (*x - *last_control_point_x);
+ y1 = *y + (*y - *last_control_point_y);
+ }
+ else
+ {
+ x1 = *x;
+ y1 = *y;
+ }
+
+ if (cmd->curve.relative)
+ {
+ cairo_curve_to (cr, x1, y1, *x + cmd->curve.x2, *y + cmd->curve.y2,
+ *x + cmd->curve.x, *y + cmd->curve.y);
+ *last_control_point_x = *x + cmd->curve.x2;
+ *last_control_point_y = *y + cmd->curve.y2;
+ *x += cmd->curve.x;
+ *y += cmd->curve.y;
+ }
+ else
+ {
+ cairo_curve_to (cr, x1, y1, cmd->curve.x2, cmd->curve.y2,
+ cmd->curve.x, cmd->curve.y);
+ *last_control_point_x = cmd->curve.x2;
+ *last_control_point_y = cmd->curve.y2;
+ *x = cmd->curve.x;
+ *y = cmd->curve.y;
+ }
+}
+
+
+static void
+do_quadratic_curve_to (GooCanvasPathCommand *cmd,
+ cairo_t *cr,
+ gdouble *x,
+ gdouble *y,
+ gdouble *last_control_point_x,
+ gdouble *last_control_point_y)
+{
+ gdouble qx1, qy1, qx2, qy2, x1, y1, x2, y2;
+
+ if (cmd->curve.relative)
+ {
+ qx1 = *x + cmd->curve.x1;
+ qy1 = *y + cmd->curve.y1;
+ qx2 = *x + cmd->curve.x;
+ qy2 = *y + cmd->curve.y;
+ }
+ else
+ {
+ qx1 = cmd->curve.x1;
+ qy1 = cmd->curve.y1;
+ qx2 = cmd->curve.x;
+ qy2 = cmd->curve.y;
+ }
+
+ /* We need to convert the quadratic into a cubic bezier. */
+ x1 = *x + (qx1 - *x) * 2.0 / 3.0;
+ y1 = *y + (qy1 - *y) * 2.0 / 3.0;
+
+ x2 = x1 + (qx2 - *x) / 3.0;
+ y2 = y1 + (qy2 - *y) / 3.0;
+
+ cairo_curve_to (cr, x1, y1, x2, y2, qx2, qy2);
+
+ *x = qx2;
+ *y = qy2;
+ *last_control_point_x = qx1;
+ *last_control_point_y = qy1;
+}
+
+
+static void
+do_smooth_quadratic_curve_to (GooCanvasPathCommand *cmd,
+ GooCanvasPathCommandType prev_cmd_type,
+ cairo_t *cr,
+ gdouble *x,
+ gdouble *y,
+ gdouble *last_control_point_x,
+ gdouble *last_control_point_y)
+{
+ gdouble qx1, qy1, qx2, qy2, x1, y1, x2, y2;
+
+ /* If the last command was a quadratic or smooth quadratic, we use
+ the reflection of the last control point about the current point
+ as the first control point of this curve. Otherwise we use the
+ current point as the first control point. */
+ if (prev_cmd_type == GOO_CANVAS_PATH_QUADRATIC_CURVE_TO
+ || prev_cmd_type == GOO_CANVAS_PATH_SMOOTH_QUADRATIC_CURVE_TO)
+ {
+ qx1 = *x + (*x - *last_control_point_x);
+ qy1 = *y + (*y - *last_control_point_y);
+ }
+ else
+ {
+ qx1 = *x;
+ qy1 = *y;
+ }
+
+ if (cmd->curve.relative)
+ {
+ qx2 = *x + cmd->curve.x;
+ qy2 = *y + cmd->curve.y;
+ }
+ else
+ {
+ qx2 = cmd->curve.x;
+ qy2 = cmd->curve.y;
+ }
+
+ /* We need to convert the quadratic into a cubic bezier. */
+ x1 = *x + (qx1 - *x) * 2.0 / 3.0;
+ y1 = *y + (qy1 - *y) * 2.0 / 3.0;
+
+ x2 = x1 + (qx2 - *x) / 3.0;
+ y2 = y1 + (qy2 - *y) / 3.0;
+
+ cairo_curve_to (cr, x1, y1, x2, y2, qx2, qy2);
+
+ *x = qx2;
+ *y = qy2;
+ *last_control_point_x = qx1;
+ *last_control_point_y = qy1;
+}
+
+
+static gdouble
+calc_angle (gdouble ux, gdouble uy, gdouble vx, gdouble vy)
+{
+ gdouble top, u_magnitude, v_magnitude, angle_cos, angle;
+
+ top = ux * vx + uy * vy;
+ u_magnitude = sqrt (ux * ux + uy * uy);
+ v_magnitude = sqrt (vx * vx + vy * vy);
+ angle_cos = top / (u_magnitude * v_magnitude);
+
+ /* We check if the cosine is slightly out-of-bounds. */
+ if (angle_cos >= 1.0)
+ angle = 0.0;
+ if (angle_cos <= -1.0)
+ angle = M_PI;
+ else
+ angle = acos (angle_cos);
+
+ if (ux * vy - uy * vx < 0)
+ angle = - angle;
+
+ return angle;
+}
+
+
+/* FIXME: Maybe we should do these calculations once when the path data is
+ parsed, and keep the cairo parameters we need in the command instead. */
+static void
+do_elliptical_arc (GooCanvasPathCommand *cmd,
+ cairo_t *cr,
+ gdouble *x,
+ gdouble *y)
+{
+ gdouble x1 = *x, y1 = *y, x2, y2, rx, ry, lambda;
+ gdouble v1, v2, angle, angle_sin, angle_cos, x11, y11;
+ gdouble rx_squared, ry_squared, x11_squared, y11_squared, top, bottom;
+ gdouble c, cx1, cy1, cx, cy, start_angle, angle_delta;
+
+ /* Calculate the end point of the arc - x2,y2. */
+ if (cmd->arc.relative)
+ {
+ x2 = x1 + cmd->arc.x;
+ y2 = y1 + cmd->arc.y;
+ }
+ else
+ {
+ x2 = cmd->arc.x;
+ y2 = cmd->arc.y;
+ }
+
+ *x = x2;
+ *y = y2;
+
+ /* If the endpoints are exactly the same, just return (see SVG spec). */
+ if (x1 == x2 && y1 == y2)
+ return;
+
+ /* If either rx or ry is 0, do a simple lineto (see SVG spec). */
+ if (cmd->arc.rx == 0.0 || cmd->arc.ry == 0.0)
+ {
+ cairo_line_to (cr, x2, y2);
+ return;
+ }
+
+ /* Calculate x1' and y1' (as per SVG implementation notes). */
+ v1 = (x1 - x2) / 2.0;
+ v2 = (y1 - y2) / 2.0;
+
+ angle = cmd->arc.x_axis_rotation * (M_PI / 180.0);
+ angle_sin = sin (angle);
+ angle_cos = cos (angle);
+
+ x11 = (angle_cos * v1) + (angle_sin * v2);
+ y11 = - (angle_sin * v1) + (angle_cos * v2);
+
+ /* Ensure rx and ry are positive and large enough. */
+ rx = cmd->arc.rx > 0.0 ? cmd->arc.rx : - cmd->arc.rx;
+ ry = cmd->arc.ry > 0.0 ? cmd->arc.ry : - cmd->arc.ry;
+ lambda = (x11 * x11) / (rx * rx) + (y11 * y11) / (ry * ry);
+ if (lambda > 1.0)
+ {
+ gdouble square_root = sqrt (lambda);
+ rx *= square_root;
+ ry *= square_root;
+ }
+
+ /* Calculate cx' and cy'. */
+ rx_squared = rx * rx;
+ ry_squared = ry * ry;
+ x11_squared = x11 * x11;
+ y11_squared = y11 * y11;
+
+ top = (rx_squared * ry_squared) - (rx_squared * y11_squared)
+ - (ry_squared * x11_squared);
+ if (top < 0.0)
+ {
+ c = 0.0;
+ }
+ else
+ {
+ bottom = (rx_squared * y11_squared) + (ry_squared * x11_squared);
+ c = sqrt (top / bottom);
+ }
+
+ if (cmd->arc.large_arc_flag == cmd->arc.sweep_flag)
+ c = - c;
+
+ cx1 = c * ((rx * y11) / ry);
+ cy1 = c * (- (ry * x11) / rx);
+
+ /* Calculate cx and cy. */
+ cx = (angle_cos * cx1) - (angle_sin * cy1) + (x1 + x2) / 2;
+ cy = (angle_sin * cx1) + (angle_cos * cy1) + (y1 + y2) / 2;
+
+ /* Calculate the start and end angles. */
+ v1 = (x11 - cx1) / rx;
+ v2 = (y11 - cy1) / ry;
+
+ start_angle = calc_angle (1, 0, v1, v2);
+ angle_delta = calc_angle (v1, v2, (-x11 - cx1) / rx, (-y11 - cy1) / ry);
+
+ if (cmd->arc.sweep_flag == 0 && angle_delta > 0.0)
+ angle_delta -= 2 * M_PI;
+ else if (cmd->arc.sweep_flag == 1 && angle_delta < 0.0)
+ angle_delta += 2 * M_PI;
+
+ /* Now draw the arc. */
+ cairo_save (cr);
+ cairo_translate (cr, cx, cy);
+ cairo_rotate (cr, angle);
+ cairo_scale (cr, rx, ry);
+
+ if (angle_delta > 0.0)
+ cairo_arc (cr, 0.0, 0.0, 1.0,
+ start_angle, start_angle + angle_delta);
+ else
+ cairo_arc_negative (cr, 0.0, 0.0, 1.0,
+ start_angle, start_angle + angle_delta);
+
+ cairo_restore (cr);
+}
+
+
+static void
+goo_canvas_path_create_path (GooCanvasItemSimple *simple,
+ cairo_t *cr)
+{
+ GooCanvasPath *path = (GooCanvasPath*) simple;
+ GooCanvasPathCommand *cmd;
+ GooCanvasPathCommandType prev_cmd_type = GOO_CANVAS_PATH_CLOSE_PATH;
+ gdouble x = 0, y = 0, path_start_x = 0, path_start_y = 0;
+ gdouble last_control_point_x = 0.0, last_control_point_y = 0.0;
+ gint i;
+
+ cairo_new_path (cr);
+
+ if (!path->path_commands || path->path_commands->len == 0)
+ return;
+
+ for (i = 0; i < path->path_commands->len; i++)
+ {
+ cmd = &g_array_index (path->path_commands, GooCanvasPathCommand, i);
+ switch (cmd->simple.type)
+ {
+ /* Simple commands like moveto and lineto: MmZzLlHhVv. */
+ case GOO_CANVAS_PATH_MOVE_TO:
+ if (cmd->simple.relative)
+ {
+ x += cmd->simple.x;
+ y += cmd->simple.y;
+ }
+ else
+ {
+ x = cmd->simple.x;
+ y = cmd->simple.y;
+ }
+ path_start_x = x;
+ path_start_y = y;
+ cairo_move_to (cr, x, y);
+ break;
+
+ case GOO_CANVAS_PATH_CLOSE_PATH:
+ x = path_start_x;
+ y = path_start_y;
+ cairo_close_path (cr);
+ break;
+
+ case GOO_CANVAS_PATH_LINE_TO:
+ if (cmd->simple.relative)
+ {
+ x += cmd->simple.x;
+ y += cmd->simple.y;
+ }
+ else
+ {
+ x = cmd->simple.x;
+ y = cmd->simple.y;
+ }
+ cairo_line_to (cr, x, y);
+ break;
+
+ case GOO_CANVAS_PATH_HORIZONTAL_LINE_TO:
+ if (cmd->simple.relative)
+ x += cmd->simple.x;
+ else
+ x = cmd->simple.x;
+ cairo_line_to (cr, x, y);
+ break;
+
+ case GOO_CANVAS_PATH_VERTICAL_LINE_TO:
+ if (cmd->simple.relative)
+ y += cmd->simple.y;
+ else
+ y = cmd->simple.y;
+ cairo_line_to (cr, x, y);
+ break;
+
+ /* Bezier curve commands: CcSsQqTt. */
+ case GOO_CANVAS_PATH_CURVE_TO:
+ do_curve_to (cmd, cr, &x, &y,
+ &last_control_point_x, &last_control_point_y);
+ break;
+
+ case GOO_CANVAS_PATH_SMOOTH_CURVE_TO:
+ do_smooth_curve_to (cmd, prev_cmd_type, cr, &x, &y,
+ &last_control_point_x, &last_control_point_y);
+ break;
+
+ case GOO_CANVAS_PATH_QUADRATIC_CURVE_TO:
+ do_quadratic_curve_to (cmd, cr, &x, &y,
+ &last_control_point_x, &last_control_point_y);
+ break;
+
+ case GOO_CANVAS_PATH_SMOOTH_QUADRATIC_CURVE_TO:
+ do_smooth_quadratic_curve_to (cmd, prev_cmd_type, cr, &x, &y,
+ &last_control_point_x,
+ &last_control_point_y);
+ break;
+
+ /* The elliptical arc commands: Aa. */
+ case GOO_CANVAS_PATH_ELLIPTICAL_ARC:
+ do_elliptical_arc (cmd, cr, &x, &y);
+ break;
+ }
+
+ prev_cmd_type = cmd->simple.type;
+ }
+}
+
+
+static void
+goo_canvas_path_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;
+ GooCanvasPath *path = (GooCanvasPath*) item;
+ GooCanvasPathModel *emodel = (GooCanvasPathModel*) model;
+
+ /* If our data was allocated, free it. */
+ if (!simple->model)
+ g_array_free (path->path_commands, TRUE);
+
+ /* Now use the new model's data instead. */
+ path->path_commands = emodel->path_commands;
+
+ /* 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_path_set_model;
+}
+
+
+/*
+ * GooCanvasPathModel.
+ */
+
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void goo_canvas_path_model_finalize (GObject *object);
+static void goo_canvas_path_model_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void goo_canvas_path_model_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasPathModel, goo_canvas_path_model,
+ GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+ G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+ item_model_interface_init))
+
+
+static void
+goo_canvas_path_model_class_init (GooCanvasPathModelClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+
+ gobject_class->finalize = goo_canvas_path_model_finalize;
+
+ gobject_class->get_property = goo_canvas_path_model_get_property;
+ gobject_class->set_property = goo_canvas_path_model_set_property;
+
+ goo_canvas_path_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_path_model_init (GooCanvasPathModel *pmodel)
+{
+ pmodel->path_commands = g_array_new (0, 0, sizeof (GooCanvasPathCommand));
+}
+
+
+GooCanvasItemModel*
+goo_canvas_path_model_new (GooCanvasItemModel *parent,
+ const gchar *path_data,
+ ...)
+{
+ GooCanvasItemModel *model;
+ GooCanvasPathModel *pmodel;
+ const char *first_property;
+ va_list var_args;
+
+ model = g_object_new (GOO_TYPE_CANVAS_PATH_MODEL, NULL);
+ pmodel = (GooCanvasPathModel*) model;
+
+ goo_canvas_path_parse_data (pmodel->path_commands, path_data);
+
+ va_start (var_args, path_data);
+ 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_path_model_finalize (GObject *object)
+{
+ GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object;
+
+ g_array_free (pmodel->path_commands, TRUE);
+
+ G_OBJECT_CLASS (goo_canvas_path_model_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_path_model_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object;
+
+ goo_canvas_path_get_common_property (object, pmodel->path_commands, prop_id,
+ value, pspec);
+}
+
+
+static void
+goo_canvas_path_model_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasPathModel *pmodel = (GooCanvasPathModel*) object;
+
+ goo_canvas_path_set_common_property (object, pmodel->path_commands, prop_id,
+ value, pspec);
+ g_signal_emit_by_name (pmodel, "changed", TRUE);
+}
+
+
+static GooCanvasItem*
+goo_canvas_path_model_create_item (GooCanvasItemModel *model,
+ GooCanvas *canvas)
+{
+ GooCanvasItem *item;
+
+ item = g_object_new (GOO_TYPE_CANVAS_PATH, NULL);
+ goo_canvas_item_set_model (item, model);
+
+ return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+ iface->create_item = goo_canvas_path_model_create_item;
+}
Index: goocanvaspath.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaspath.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- goocanvaspath.h 12 Oct 2006 10:33:27 -0000 1.5
+++ goocanvaspath.h 29 Nov 2006 18:40:53 -0000 1.6
@@ -13,14 +13,6 @@
G_BEGIN_DECLS
-#define GOO_TYPE_CANVAS_PATH (goo_canvas_path_get_type ())
-#define GOO_CANVAS_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_PATH, GooCanvasPath))
-#define GOO_CANVAS_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_PATH, GooCanvasPathClass))
-#define GOO_IS_CANVAS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_PATH))
-#define GOO_IS_CANVAS_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_PATH))
-#define GOO_CANVAS_PATH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_PATH, GooCanvasPathClass))
-
-
/**
* GooCanvasPathCommandType
* @GOO_CANVAS_PATH_MOVE_TO: move to the given point.
@@ -110,24 +102,28 @@
};
+#define GOO_TYPE_CANVAS_PATH (goo_canvas_path_get_type ())
+#define GOO_CANVAS_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_PATH, GooCanvasPath))
+#define GOO_CANVAS_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_PATH, GooCanvasPathClass))
+#define GOO_IS_CANVAS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_PATH))
+#define GOO_IS_CANVAS_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_PATH))
+#define GOO_CANVAS_PATH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_PATH, GooCanvasPathClass))
+
+
typedef struct _GooCanvasPath GooCanvasPath;
typedef struct _GooCanvasPathClass GooCanvasPathClass;
/**
* GooCanvasPath
- * @commands: an array of #GooCanvasPathCommand holding the specification of
- * the path. Applications can modify this directly, but must call
- * goo_canvas_item_simple_emit_changed() afterwards to notify the
- * views that the #GooCanvasPath has changed.
*
- * The #GooCanvasPath-struct contains the list of commands specifying the path.
+ * The #GooCanvasPath-struct struct contains private data only.
*/
struct _GooCanvasPath
{
GooCanvasItemSimple parent;
- /*< public >*/
- GArray *commands;
+ /* An array of GooCanvasPathCommand. */
+ GArray *path_commands;
};
struct _GooCanvasPathClass
@@ -136,10 +132,49 @@
};
-GType goo_canvas_path_get_type (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_path_new (GooCanvasItem *parent,
- const gchar *path_data,
- ...);
+GType goo_canvas_path_get_type (void) G_GNUC_CONST;
+
+GooCanvasItem* goo_canvas_path_new (GooCanvasItem *parent,
+ const gchar *path_data,
+ ...);
+
+
+
+#define GOO_TYPE_CANVAS_PATH_MODEL (goo_canvas_path_model_get_type ())
+#define GOO_CANVAS_PATH_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_PATH_MODEL, GooCanvasPathModel))
+#define GOO_CANVAS_PATH_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_PATH_MODEL, GooCanvasPathModelClass))
+#define GOO_IS_CANVAS_PATH_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_PATH_MODEL))
+#define GOO_IS_CANVAS_PATH_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_PATH_MODEL))
+#define GOO_CANVAS_PATH_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_PATH_MODEL, GooCanvasPathModelClass))
+
+
+typedef struct _GooCanvasPathModel GooCanvasPathModel;
+typedef struct _GooCanvasPathModelClass GooCanvasPathModelClass;
+
+/**
+ * GooCanvasPathModel
+ *
+ * The #GooCanvasPathModel-struct struct contains private data only.
+ */
+struct _GooCanvasPathModel
+{
+ GooCanvasItemModelSimple parent_object;
+
+ /* An array of GooCanvasPathCommand. */
+ GArray *path_commands;
+};
+
+struct _GooCanvasPathModelClass
+{
+ GooCanvasItemModelSimpleClass parent_class;
+};
+
+
+GType goo_canvas_path_model_get_type (void) G_GNUC_CONST;
+
+GooCanvasItemModel* goo_canvas_path_model_new (GooCanvasItemModel *parent,
+ const gchar *path_data,
+ ...);
G_END_DECLS
--- goocanvaspathview.c DELETED ---
--- goocanvaspathview.h DELETED ---
Index: goocanvaspolyline.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaspolyline.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvaspolyline.c 24 Aug 2006 08:06:23 -0000 1.6
+++ goocanvaspolyline.c 29 Nov 2006 18:40:53 -0000 1.7
@@ -27,7 +27,7 @@
*
* To respond to events such as mouse clicks on the polyline you must connect
* to the signal handlers of the corresponding #GooCanvasPolylineView 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 <math.h>
@@ -36,11 +36,8 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
[...1116 lines suppressed...]
+
+
+static GooCanvasItem*
+goo_canvas_polyline_model_create_item (GooCanvasItemModel *model,
+ GooCanvas *canvas)
+{
+ GooCanvasItem *item;
+
+ item = g_object_new (GOO_TYPE_CANVAS_POLYLINE, NULL);
+ goo_canvas_item_set_model (item, model);
+
+ return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+ iface->create_item = goo_canvas_polyline_model_create_item;
+}
Index: goocanvaspolyline.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaspolyline.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- goocanvaspolyline.h 12 Oct 2006 10:33:27 -0000 1.4
+++ goocanvaspolyline.h 29 Nov 2006 18:40:53 -0000 1.5
@@ -36,13 +36,6 @@
void goo_canvas_points_unref (GooCanvasPoints *points);
-#define GOO_TYPE_CANVAS_POLYLINE (goo_canvas_polyline_get_type ())
-#define GOO_CANVAS_POLYLINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_POLYLINE, GooCanvasPolyline))
-#define GOO_CANVAS_POLYLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_POLYLINE, GooCanvasPolylineClass))
-#define GOO_IS_CANVAS_POLYLINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_POLYLINE))
-#define GOO_IS_CANVAS_POLYLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_POLYLINE))
-#define GOO_CANVAS_POLYLINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_POLYLINE, GooCanvasPolylineClass))
-
#define NUM_ARROW_POINTS 5 /* number of points in an arrowhead */
typedef struct _GooCanvasPolylineArrowData GooCanvasPolylineArrowData;
@@ -58,6 +51,30 @@
};
+/* This is the data used by both model and view classes. */
+typedef struct _GooCanvasPolylineData GooCanvasPolylineData;
+struct _GooCanvasPolylineData
+{
+ gdouble *coords;
+
+ GooCanvasPolylineArrowData *arrow_data;
+
+ guint num_points : 16;
+ guint close_path : 1;
+ guint start_arrow : 1;
+ guint end_arrow : 1;
+ guint reconfigure_arrows : 1;
+};
+
+
+#define GOO_TYPE_CANVAS_POLYLINE (goo_canvas_polyline_get_type ())
+#define GOO_CANVAS_POLYLINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_POLYLINE, GooCanvasPolyline))
+#define GOO_CANVAS_POLYLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_POLYLINE, GooCanvasPolylineClass))
+#define GOO_IS_CANVAS_POLYLINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_POLYLINE))
+#define GOO_IS_CANVAS_POLYLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_POLYLINE))
+#define GOO_CANVAS_POLYLINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_POLYLINE, GooCanvasPolylineClass))
+
+
typedef struct _GooCanvasPolyline GooCanvasPolyline;
typedef struct _GooCanvasPolylineClass GooCanvasPolylineClass;
@@ -70,15 +87,7 @@
{
GooCanvasItemSimple parent;
- gdouble *coords;
-
- GooCanvasPolylineArrowData *arrow_data;
-
- guint num_points : 16;
- guint close_path : 1;
- guint start_arrow : 1;
- guint end_arrow : 1;
- guint reconfigure_arrows : 1;
+ GooCanvasPolylineData *polyline_data;
};
struct _GooCanvasPolylineClass
@@ -87,20 +96,64 @@
};
-GType goo_canvas_polyline_get_type (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_polyline_new (GooCanvasItem *parent,
- gboolean close_path,
- gint num_points,
- ...);
+GType goo_canvas_polyline_get_type (void) G_GNUC_CONST;
+
+GooCanvasItem* goo_canvas_polyline_new (GooCanvasItem *parent,
+ gboolean close_path,
+ gint num_points,
+ ...);
+
+GooCanvasItem* goo_canvas_polyline_new_line (GooCanvasItem *parent,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ ...);
+
+
+
+#define GOO_TYPE_CANVAS_POLYLINE_MODEL (goo_canvas_polyline_model_get_type ())
+#define GOO_CANVAS_POLYLINE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_POLYLINE_MODEL, GooCanvasPolylineModel))
+#define GOO_CANVAS_POLYLINE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_POLYLINE_MODEL, GooCanvasPolylineModelClass))
+#define GOO_IS_CANVAS_POLYLINE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_POLYLINE_MODEL))
+#define GOO_IS_CANVAS_POLYLINE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_POLYLINE_MODEL))
+#define GOO_CANVAS_POLYLINE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_POLYLINE_MODEL, GooCanvasPolylineModelClass))
+
+
+typedef struct _GooCanvasPolylineModel GooCanvasPolylineModel;
+typedef struct _GooCanvasPolylineModelClass GooCanvasPolylineModelClass;
+
+/**
+ * GooCanvasPolylineModel
+ *
+ * The #GooCanvasPolylineModel-struct struct contains private data only.
+ */
+struct _GooCanvasPolylineModel
+{
+ GooCanvasItemModelSimple parent_object;
+
+ GooCanvasPolylineData polyline_data;
+};
+
+struct _GooCanvasPolylineModelClass
+{
+ GooCanvasItemModelSimpleClass parent_class;
+};
-GooCanvasItem* goo_canvas_polyline_new_line (GooCanvasItem *parent,
- gdouble x1,
- gdouble y1,
- gdouble x2,
- gdouble y2,
- const gchar *first_property,
- ...);
+GType goo_canvas_polyline_model_get_type (void) G_GNUC_CONST;
+
+GooCanvasItemModel* goo_canvas_polyline_model_new (GooCanvasItemModel *parent,
+ gboolean close_path,
+ gint num_points,
+ ...);
+
+GooCanvasItemModel* goo_canvas_polyline_model_new_line (GooCanvasItemModel *parent,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ ...);
G_END_DECLS
--- goocanvaspolylineview.c DELETED ---
--- goocanvaspolylineview.h DELETED ---
Index: goocanvasrect.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasrect.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvasrect.c 24 Aug 2006 08:06:23 -0000 1.6
+++ goocanvasrect.c 29 Nov 2006 18:40:53 -0000 1.7
@@ -25,14 +25,14 @@
* g_object_get() and g_object_set().
*
* To respond to events such as mouse clicks on the rect you must connect
- * to the signal handlers of the corresponding #GooCanvasRectView objects.
- * (See goo_canvas_view_get_item_view() and #GooCanvasView::item-view-created.)
+ * to the signal handlers of the corresponding #GooCanvasRect 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 "goocanvasrect.h"
-#include "goocanvasrectview.h"
enum {
@@ -47,7 +47,8 @@
};
-static void item_interface_init (GooCanvasItemIface *iface);
+static void canvas_item_interface_init (GooCanvasItemIface *iface);
+static void goo_canvas_rect_finalize (GObject *object);
static void goo_canvas_rect_get_property (GObject *object,
guint param_id,
GValue *value,
@@ -56,21 +57,18 @@
guint param_id,
const GValue *value,
GParamSpec *pspec);
+static void goo_canvas_rect_create_path (GooCanvasItemSimple *simple,
+ cairo_t *cr);
G_DEFINE_TYPE_WITH_CODE (GooCanvasRect, goo_canvas_rect,
GOO_TYPE_CANVAS_ITEM_SIMPLE,
G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
- item_interface_init))
+ canvas_item_interface_init))
static void
-goo_canvas_rect_class_init (GooCanvasRectClass *klass)
+goo_canvas_rect_install_common_properties (GObjectClass *gobject_class)
{
- GObjectClass *gobject_class = (GObjectClass*) klass;
-
- gobject_class->get_property = goo_canvas_rect_get_property;
- gobject_class->set_property = goo_canvas_rect_set_property;
-
g_object_class_install_property (gobject_class, PROP_X,
g_param_spec_double ("x",
"X",
@@ -118,9 +116,26 @@
static void
-goo_canvas_rect_init (GooCanvasRect *canvas_rect)
+goo_canvas_rect_class_init (GooCanvasRectClass *klass)
{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+ GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
+ gobject_class->finalize = goo_canvas_rect_finalize;
+
+ gobject_class->get_property = goo_canvas_rect_get_property;
+ gobject_class->set_property = goo_canvas_rect_set_property;
+
+ simple_class->create_path = goo_canvas_rect_create_path;
+
+ goo_canvas_rect_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_rect_init (GooCanvasRect *rect)
+{
+ rect->rect_data = g_slice_new0 (GooCanvasRectData);
}
@@ -133,9 +148,7 @@
* @y: the y coordinate of the top of the rectangle.
* @width: the width of the rectangle.
* @height: the height of the rectangle.
- * @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 rectangle item.
*
@@ -160,26 +173,30 @@
gdouble y,
gdouble width,
gdouble height,
- const gchar *first_property,
...)
{
GooCanvasItem *item;
GooCanvasRect *rect;
- va_list args;
+ GooCanvasRectData *rect_data;
+ const char *first_property;
+ va_list var_args;
item = g_object_new (GOO_TYPE_CANVAS_RECT, NULL);
- rect = GOO_CANVAS_RECT (item);
+ rect = (GooCanvasRect*) item;
- rect->x = x;
- rect->y = y;
- rect->width = width;
- rect->height = height;
- rect->radius_x = 0;
- rect->radius_y = 0;
+ rect_data = rect->rect_data;
+ rect_data->x = x;
+ rect_data->y = y;
+ rect_data->width = width;
+ rect_data->height = height;
+ rect_data->radius_x = 0;
+ rect_data->radius_y = 0;
- va_start (args, first_property);
- g_object_set_valist (G_OBJECT (item), first_property, args);
- va_end (args);
+ va_start (var_args, height);
+ 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)
{
@@ -191,50 +208,46 @@
}
-static GooCanvasItemView*
-goo_canvas_rect_create_view (GooCanvasItem *item,
- GooCanvasView *canvas_view,
- GooCanvasItemView *parent_view)
+static void
+goo_canvas_rect_finalize (GObject *object)
{
- return goo_canvas_rect_view_new (canvas_view, parent_view,
- (GooCanvasRect*) item);
-}
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasRect *rect = (GooCanvasRect*) object;
+ if (!simple->model)
+ g_slice_free (GooCanvasRectData, rect->rect_data);
+ rect->rect_data = NULL;
-static void
-item_interface_init (GooCanvasItemIface *iface)
-{
- iface->create_view = goo_canvas_rect_create_view;
+ G_OBJECT_CLASS (goo_canvas_rect_parent_class)->finalize (object);
}
static void
-goo_canvas_rect_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+goo_canvas_rect_get_common_property (GObject *object,
+ GooCanvasRectData *rect_data,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GooCanvasRect *rect = (GooCanvasRect*) object;
-
switch (prop_id)
{
case PROP_X:
- g_value_set_double (value, rect->x);
+ g_value_set_double (value, rect_data->x);
break;
case PROP_Y:
- g_value_set_double (value, rect->y);
+ g_value_set_double (value, rect_data->y);
break;
case PROP_WIDTH:
- g_value_set_double (value, rect->width);
+ g_value_set_double (value, rect_data->width);
break;
case PROP_HEIGHT:
- g_value_set_double (value, rect->height);
+ g_value_set_double (value, rect_data->height);
break;
case PROP_RADIUS_X:
- g_value_set_double (value, rect->radius_x);
+ g_value_set_double (value, rect_data->radius_x);
break;
case PROP_RADIUS_Y:
- g_value_set_double (value, rect->radius_y);
+ g_value_set_double (value, rect_data->radius_y);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -244,38 +257,298 @@
static void
-goo_canvas_rect_set_property (GObject *object,
+goo_canvas_rect_get_property (GObject *object,
guint prop_id,
- const GValue *value,
+ GValue *value,
GParamSpec *pspec)
{
GooCanvasRect *rect = (GooCanvasRect*) object;
+ goo_canvas_rect_get_common_property (object, rect->rect_data, prop_id,
+ value, pspec);
+}
+
+
+static void
+goo_canvas_rect_set_common_property (GObject *object,
+ GooCanvasRectData *rect_data,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
switch (prop_id)
{
case PROP_X:
- rect->x = g_value_get_double (value);
+ rect_data->x = g_value_get_double (value);
break;
case PROP_Y:
- rect->y = g_value_get_double (value);
+ rect_data->y = g_value_get_double (value);
break;
case PROP_WIDTH:
- rect->width = g_value_get_double (value);
+ rect_data->width = g_value_get_double (value);
break;
case PROP_HEIGHT:
- rect->height = g_value_get_double (value);
+ rect_data->height = g_value_get_double (value);
break;
case PROP_RADIUS_X:
- rect->radius_x = g_value_get_double (value);
+ rect_data->radius_x = g_value_get_double (value);
break;
case PROP_RADIUS_Y:
- rect->radius_y = g_value_get_double (value);
+ rect_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 (rect, "changed", TRUE);
+
+static void
+goo_canvas_rect_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasRect *rect = (GooCanvasRect*) 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_rect_set_common_property (object, rect->rect_data, prop_id,
+ value, pspec);
+ goo_canvas_item_simple_changed (simple, TRUE);
}
+
+static void
+goo_canvas_rect_create_path (GooCanvasItemSimple *simple,
+ cairo_t *cr)
+{
+ GooCanvasRect *rect = (GooCanvasRect*) simple;
+ GooCanvasRectData *rect_data = rect->rect_data;
+
+ cairo_new_path (cr);
+
+ /* Check if we need to draw rounded corners. */
+ if (rect_data->radius_x > 0 && rect_data->radius_y > 0)
+ {
+ /* The radii can't be more than half the size of the rect. */
+ double rx = MIN (rect_data->radius_x, rect_data->width / 2);
+ double ry = MIN (rect_data->radius_y, rect_data->height / 2);
+
+ /* Draw the top-right arc. */
+ cairo_save (cr);
+ cairo_translate (cr, rect_data->x + rect_data->width - rx,
+ rect_data->y + ry);
+ cairo_scale (cr, rx, ry);
+ cairo_arc (cr, 0.0, 0.0, 1.0, 1.5 * M_PI, 2.0 * M_PI);
+ cairo_restore (cr);
+
+ /* Draw the line down the right side. */
+ cairo_line_to (cr, rect_data->x + rect_data->width,
+ rect_data->y + rect_data->height - ry);
+
+ /* Draw the bottom-right arc. */
+ cairo_save (cr);
+ cairo_translate (cr, rect_data->x + rect_data->width - rx,
+ rect_data->y + rect_data->height - ry);
+ cairo_scale (cr, rx, ry);
+ cairo_arc (cr, 0.0, 0.0, 1.0, 0.0, 0.5 * M_PI);
+ cairo_restore (cr);
+
+ /* Draw the line left across the bottom. */
+ cairo_line_to (cr, rect_data->x + rx, rect_data->y + rect_data->height);
+
+ /* Draw the bottom-left arc. */
+ cairo_save (cr);
+ cairo_translate (cr, rect_data->x + rx,
+ rect_data->y + rect_data->height - ry);
+ cairo_scale (cr, rx, ry);
+ cairo_arc (cr, 0.0, 0.0, 1.0, 0.5 * M_PI, M_PI);
+ cairo_restore (cr);
+
+ /* Draw the line up the left side. */
+ cairo_line_to (cr, rect_data->x, rect_data->y + ry);
+
+ /* Draw the top-left arc. */
+ cairo_save (cr);
+ cairo_translate (cr, rect_data->x + rx, rect_data->y + ry);
+ cairo_scale (cr, rx, ry);
+ cairo_arc (cr, 0.0, 0.0, 1.0, M_PI, 1.5 * M_PI);
+ cairo_restore (cr);
+
+ /* Close the path across the top. */
+ cairo_close_path (cr);
+ }
+ else
+ {
+ /* Draw the plain rectangle. */
+ cairo_move_to (cr, rect_data->x, rect_data->y);
+ cairo_line_to (cr, rect_data->x, rect_data->y + rect_data->height);
+ cairo_line_to (cr, rect_data->x + rect_data->width,
+ rect_data->y + rect_data->height);
+ cairo_line_to (cr, rect_data->x + rect_data->width, rect_data->y);
+ cairo_close_path (cr);
+ }
+}
+
+
+
+static void
+goo_canvas_rect_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;
+ GooCanvasRect *rect = (GooCanvasRect*) item;
+ GooCanvasRectModel *emodel = (GooCanvasRectModel*) model;
+
+ /* If our rect_data was allocated, free it. */
+ if (!simple->model)
+ g_slice_free (GooCanvasRectData, rect->rect_data);
+
+ /* Now use the new model's rect_data instead. */
+ rect->rect_data = &emodel->rect_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_rect_set_model;
+}
+
+
+/*
+ * GooCanvasRectModel.
+ */
+
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void goo_canvas_rect_model_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void goo_canvas_rect_model_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasRectModel, goo_canvas_rect_model,
+ GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+ G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+ item_model_interface_init))
+
+
+static void
+goo_canvas_rect_model_class_init (GooCanvasRectModelClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+
+ gobject_class->get_property = goo_canvas_rect_model_get_property;
+ gobject_class->set_property = goo_canvas_rect_model_set_property;
+
+ goo_canvas_rect_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_rect_model_init (GooCanvasRectModel *rmodel)
+{
+
+}
+
+
+GooCanvasItemModel*
+goo_canvas_rect_model_new (GooCanvasItemModel *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ ...)
+{
+ GooCanvasItemModel *model;
+ GooCanvasRectModel *rmodel;
+ GooCanvasRectData *rect_data;
+ const char *first_property;
+ va_list var_args;
+
+ model = g_object_new (GOO_TYPE_CANVAS_RECT_MODEL, NULL);
+ rmodel = (GooCanvasRectModel*) model;
+
+ rect_data = &rmodel->rect_data;
+ rect_data->x = x;
+ rect_data->y = y;
+ rect_data->width = width;
+ rect_data->height = height;
+ rect_data->radius_x = 0;
+ rect_data->radius_y = 0;
+
+ va_start (var_args, height);
+ 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_rect_model_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasRectModel *rmodel = (GooCanvasRectModel*) object;
+
+ goo_canvas_rect_get_common_property (object, &rmodel->rect_data, prop_id,
+ value, pspec);
+}
+
+
+static void
+goo_canvas_rect_model_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasRectModel *rmodel = (GooCanvasRectModel*) object;
+
+ goo_canvas_rect_set_common_property (object, &rmodel->rect_data, prop_id,
+ value, pspec);
+ g_signal_emit_by_name (rmodel, "changed", TRUE);
+}
+
+
+static GooCanvasItem*
+goo_canvas_rect_model_create_item (GooCanvasItemModel *model,
+ GooCanvas *canvas)
+{
+ GooCanvasItem *item;
+
+ item = g_object_new (GOO_TYPE_CANVAS_RECT, NULL);
+ goo_canvas_item_set_model (item, model);
+
+ return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+ iface->create_item = goo_canvas_rect_model_create_item;
+}
Index: goocanvasrect.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasrect.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- goocanvasrect.h 13 Apr 2006 16:06:04 -0000 1.2
+++ goocanvasrect.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 _GooCanvasRectData GooCanvasRectData;
+struct _GooCanvasRectData
+{
+ gdouble x, y, width, height, radius_x, radius_y;
+};
+
+
#define GOO_TYPE_CANVAS_RECT (goo_canvas_rect_get_type ())
#define GOO_CANVAS_RECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_RECT, GooCanvasRect))
#define GOO_CANVAS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_RECT, GooCanvasRectClass))
@@ -33,7 +41,7 @@
{
GooCanvasItemSimple parent;
- gdouble x, y, width, height, radius_x, radius_y;
+ GooCanvasRectData *rect_data;
};
struct _GooCanvasRectClass
@@ -42,14 +50,54 @@
};
-GType goo_canvas_rect_get_type (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_rect_new (GooCanvasItem *parent,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height,
- const gchar *first_property,
- ...);
+GType goo_canvas_rect_get_type (void) G_GNUC_CONST;
+
+GooCanvasItem* goo_canvas_rect_new (GooCanvasItem *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ ...);
+
+
+
+#define GOO_TYPE_CANVAS_RECT_MODEL (goo_canvas_rect_model_get_type ())
+#define GOO_CANVAS_RECT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_RECT_MODEL, GooCanvasRectModel))
+#define GOO_CANVAS_RECT_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_RECT_MODEL, GooCanvasRectModelClass))
+#define GOO_IS_CANVAS_RECT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_RECT_MODEL))
+#define GOO_IS_CANVAS_RECT_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_RECT_MODEL))
+#define GOO_CANVAS_RECT_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_RECT_MODEL, GooCanvasRectModelClass))
+
+
+typedef struct _GooCanvasRectModel GooCanvasRectModel;
+typedef struct _GooCanvasRectModelClass GooCanvasRectModelClass;
+
+/**
+ * GooCanvasRectModel
+ *
+ * The #GooCanvasRectModel-struct struct contains private data only.
+ */
+struct _GooCanvasRectModel
+{
+ GooCanvasItemModelSimple parent_object;
+
+ GooCanvasRectData rect_data;
+};
+
+struct _GooCanvasRectModelClass
+{
+ GooCanvasItemModelSimpleClass parent_class;
+};
+
+
+GType goo_canvas_rect_model_get_type (void) G_GNUC_CONST;
+
+GooCanvasItemModel* goo_canvas_rect_model_new (GooCanvasItemModel *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ ...);
G_END_DECLS
--- goocanvasrectview.c DELETED ---
--- goocanvasrectview.h DELETED ---
Index: goocanvastext.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastext.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvastext.c 24 Aug 2006 08:06:23 -0000 1.6
+++ goocanvastext.c 29 Nov 2006 18:40:53 -0000 1.7
@@ -26,13 +26,13 @@
*
* To respond to events such as mouse clicks on the text you must connect
* to the signal handlers of the corresponding #GooCanvasTextView objects.
- * (See goo_canvas_view_get_item_view() and #GooCanvasView::item-view-created.)
+ * (See goo_canvas_get_item_view() and #GooCanvas::item-view-created.)
*/
#include <config.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include "goocanvastext.h"
-#include "goocanvastextview.h"
+#include "goocanvas.h"
enum {
@@ -43,14 +43,12 @@
PROP_WIDTH,
PROP_TEXT,
PROP_USE_MARKUP,
- PROP_FONT,
- PROP_FONT_DESC,
PROP_ANCHOR,
PROP_ALIGN
};
-static void goo_canvas_text_finalize (GObject *object);
-static void item_interface_init (GooCanvasItemIface *iface);
+static void goo_canvas_text_finalize (GObject *object);
+static void canvas_item_interface_init (GooCanvasItemIface *iface);
static void goo_canvas_text_get_property (GObject *object,
guint param_id,
GValue *value,
@@ -63,19 +61,12 @@
G_DEFINE_TYPE_WITH_CODE (GooCanvasText, goo_canvas_text,
GOO_TYPE_CANVAS_ITEM_SIMPLE,
G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
- item_interface_init))
+ canvas_item_interface_init))
static void
-goo_canvas_text_class_init (GooCanvasTextClass *klass)
+goo_canvas_text_install_common_properties (GObjectClass *gobject_class)
{
- GObjectClass *gobject_class = (GObjectClass*) klass;
-
- gobject_class->finalize = goo_canvas_text_finalize;
-
- gobject_class->get_property = goo_canvas_text_get_property;
- gobject_class->set_property = goo_canvas_text_set_property;
-
/* Text */
g_object_class_install_property (gobject_class, PROP_TEXT,
g_param_spec_string ("text",
@@ -131,29 +122,36 @@
PANGO_TYPE_ALIGNMENT,
PANGO_ALIGN_LEFT,
G_PARAM_READWRITE));
+}
- /* Font */
- g_object_class_install_property (gobject_class, PROP_FONT,
- g_param_spec_string ("font",
- _("Font"),
- _("The base font to use for the text"),
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_FONT_DESC,
- g_param_spec_boxed ("font-desc",
- _("Font Description"),
- _("The attributes specifying which font to use"),
- PANGO_TYPE_FONT_DESCRIPTION,
- G_PARAM_READWRITE));
+static void
+goo_canvas_text_class_init (GooCanvasTextClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+
+ gobject_class->finalize = goo_canvas_text_finalize;
+
+ gobject_class->get_property = goo_canvas_text_get_property;
+ gobject_class->set_property = goo_canvas_text_set_property;
+
+ goo_canvas_text_install_common_properties (gobject_class);
+
+ /* Create the font options once and reuse it. */
+ klass->font_options = cairo_font_options_create ();
+ cairo_font_options_set_hint_metrics (klass->font_options,
+ CAIRO_HINT_METRICS_OFF);
+ cairo_font_options_set_hint_style (klass->font_options,
+ CAIRO_HINT_STYLE_NONE);
}
static void
goo_canvas_text_init (GooCanvasText *text)
{
- text->width = -1.0;
- text->anchor = GTK_ANCHOR_NW;
+ text->text_data = g_slice_new0 (GooCanvasTextData);
+ text->text_data->width = -1.0;
+ text->text_data->anchor = GTK_ANCHOR_NW;
}
@@ -171,9 +169,7 @@
* top-left of the text being placed at the given @x and @y coordinates.
* An anchor of %GDK_ANCHOR_CENTER will result in the center of the text being
* placed at the @x and @y coordinates.
- * @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 text item.
*
@@ -197,25 +193,29 @@
gdouble y,
gdouble width,
GtkAnchorType anchor,
- const gchar *first_property,
...)
{
GooCanvasItem *item;
GooCanvasText *text;
- va_list args;
+ GooCanvasTextData *text_data;
+ const char *first_property;
+ va_list var_args;
item = g_object_new (GOO_TYPE_CANVAS_TEXT, NULL);
- text = GOO_CANVAS_TEXT (item);
+ text = (GooCanvasText*) item;
- text->text = g_strdup (string);
- text->x = x;
- text->y = y;
- text->width = width;
- text->anchor = anchor;
+ text_data = text->text_data;
+ text_data->text = g_strdup (string);
+ text_data->x = x;
+ text_data->y = y;
+ text_data->width = width;
+ text_data->anchor = anchor;
- va_start (args, first_property);
- g_object_set_valist (G_OBJECT (item), first_property, args);
- va_end (args);
+ va_start (var_args, anchor);
+ 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)
{
@@ -230,76 +230,49 @@
static void
goo_canvas_text_finalize (GObject *object)
{
- GooCanvasText *item = (GooCanvasText*) object;
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasText *text = (GooCanvasText*) object;
- g_free (item->text);
+ if (!simple->model)
+ {
+ g_free (text->text_data->text);
+ g_slice_free (GooCanvasTextData, text->text_data);
+ }
+ text->text_data = NULL;
G_OBJECT_CLASS (goo_canvas_text_parent_class)->finalize (object);
}
-static GooCanvasItemView*
-goo_canvas_text_create_view (GooCanvasItem *item,
- GooCanvasView *canvas_view,
- GooCanvasItemView *parent_view)
-{
- return goo_canvas_text_view_new (canvas_view, parent_view,
- (GooCanvasText*) item);
-}
-
-
-static void
-item_interface_init (GooCanvasItemIface *iface)
-{
- iface->create_view = goo_canvas_text_create_view;
-}
-
-
static void
-goo_canvas_text_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+goo_canvas_text_get_common_property (GObject *object,
+ GooCanvasTextData *text_data,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GooCanvasText *text = (GooCanvasText*) object;
-
switch (prop_id)
{
case PROP_X:
- g_value_set_double (value, text->x);
+ g_value_set_double (value, text_data->x);
break;
case PROP_Y:
- g_value_set_double (value, text->y);
+ g_value_set_double (value, text_data->y);
break;
case PROP_WIDTH:
- g_value_set_double (value, text->width);
+ g_value_set_double (value, text_data->width);
break;
case PROP_TEXT:
- g_value_set_string (value, text->text);
+ g_value_set_string (value, text_data->text);
break;
case PROP_USE_MARKUP:
- g_value_set_boolean (value, text->use_markup);
- break;
- case PROP_FONT:
- if (text->font_desc)
- {
- char *font = pango_font_description_to_string (text->font_desc);
- g_value_set_string (value, font);
- g_free (font);
- }
- else
- {
- g_value_set_string (value, NULL);
- }
- break;
- case PROP_FONT_DESC:
- g_value_set_boxed (value, text->font_desc);
+ g_value_set_boolean (value, text_data->use_markup);
break;
case PROP_ANCHOR:
- g_value_set_enum (value, text->anchor);
+ g_value_set_enum (value, text_data->anchor);
break;
case PROP_ALIGN:
- g_value_set_enum (value, text->alignment);
+ g_value_set_enum (value, text_data->alignment);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -309,62 +282,543 @@
static void
-goo_canvas_text_set_property (GObject *object,
+goo_canvas_text_get_property (GObject *object,
guint prop_id,
- const GValue *value,
+ GValue *value,
GParamSpec *pspec)
{
GooCanvasText *text = (GooCanvasText*) object;
- const char *font_name;
- PangoFontDescription *font_desc;
+ goo_canvas_text_get_common_property (object, text->text_data, prop_id,
+ value, pspec);
+}
+
+
+static void
+goo_canvas_text_set_common_property (GObject *object,
+ GooCanvasTextData *text_data,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
switch (prop_id)
{
case PROP_X:
- text->x = g_value_get_double (value);
+ text_data->x = g_value_get_double (value);
break;
case PROP_Y:
- text->y = g_value_get_double (value);
+ text_data->y = g_value_get_double (value);
break;
case PROP_WIDTH:
- text->width = g_value_get_double (value);
+ text_data->width = g_value_get_double (value);
break;
case PROP_TEXT:
- g_free (text->text);
- text->text = g_value_dup_string (value);
+ g_free (text_data->text);
+ text_data->text = g_value_dup_string (value);
break;
case PROP_USE_MARKUP:
- text->use_markup = g_value_get_boolean (value);
- break;
- case PROP_FONT:
- if (text->font_desc)
- pango_font_description_free (text->font_desc);
- font_name = g_value_get_string (value);
- if (font_name)
- text->font_desc = pango_font_description_from_string (font_name);
- else
- text->font_desc = NULL;
- break;
- case PROP_FONT_DESC:
- if (text->font_desc)
- pango_font_description_free (text->font_desc);
- font_desc = g_value_peek_pointer (value);
- if (font_desc)
- text->font_desc = pango_font_description_copy (font_desc);
- else
- text->font_desc = NULL;
+ text_data->use_markup = g_value_get_boolean (value);
break;
case PROP_ANCHOR:
- text->anchor = g_value_get_enum (value);
+ text_data->anchor = g_value_get_enum (value);
break;
case PROP_ALIGN:
- text->alignment = g_value_get_enum (value);
+ text_data->alignment = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+}
- g_signal_emit_by_name (text, "changed", TRUE);
+
+static void
+goo_canvas_text_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasText *text = (GooCanvasText*) 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_text_set_common_property (object, text->text_data, prop_id,
+ value, pspec);
+ goo_canvas_item_simple_changed (simple, TRUE);
+}
+
+
+static PangoLayout*
+goo_canvas_text_create_layout (GooCanvasText *text,
+ cairo_t *cr,
+ GooCanvasBounds *bounds,
+ gdouble *origin_x_return,
+ gdouble *origin_y_return)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) text;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasTextData *text_data = text->text_data;
+ GooCanvasStyle *style = simple_data->style;
+ GValue *svalue;
+ PangoLayout *layout;
+ PangoContext *context;
+ PangoRectangle logical_rect;
+ double logical_width, logical_height, align_width, origin_x, origin_y;
+ gchar *string;
+
+ string = text_data->text ? text_data->text : "";
+
+ layout = pango_cairo_create_layout (cr);
+
+ /* Set the font options to ensure the text layout is the same whatever
+ the scale is. */
+ context = pango_layout_get_context (layout);
+ pango_cairo_context_set_font_options (context, GOO_CANVAS_TEXT_GET_CLASS (text)->font_options);
+
+ if (text_data->width > 0)
+ pango_layout_set_width (layout, (double) text_data->width * PANGO_SCALE);
+
+ if (text_data->use_markup)
+ pango_layout_set_markup (layout, string, -1);
+ else
+ pango_layout_set_text (layout, string, -1);
+
+ svalue = goo_canvas_style_get_property (style, goo_canvas_style_font_desc_id);
+ if (svalue)
+ pango_layout_set_font_description (layout, svalue->data[0].v_pointer);
+
+ if (text_data->alignment != PANGO_ALIGN_LEFT)
+ pango_layout_set_alignment (layout, text_data->alignment);
+
+ /* FIXME: Sometimes we should be using the ink_rect rather than the
+ logical rect, e.g. for the actual bounds of the item view. */
+ if (bounds)
+ {
+ /* Get size of the text, so we can position it according to anchor. */
+ pango_layout_get_extents (layout, NULL, &logical_rect);
+
+ logical_width = (double) logical_rect.width / PANGO_SCALE;
+ logical_height = (double) logical_rect.height / PANGO_SCALE;
+
+ /* If the text width has been set, that width is used to do the alignment
+ positioning. Otherwise the actual width is used. */
+ if (text_data->width > 0)
+ align_width = text_data->width;
+ else
+ align_width = logical_width;
+
+ /* Now calculate the origin of the text, i.e. where we will tell Pango
+ to draw it. */
+ origin_x = text_data->x;
+ origin_y = text_data->y;
+
+ switch (text_data->anchor)
+ {
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_S:
+ origin_x -= align_width / 2.0;
+ break;
+ case GTK_ANCHOR_NE:
+ case GTK_ANCHOR_E:
+ case GTK_ANCHOR_SE:
+ origin_x -= align_width;
+ break;
+ default:
+ break;
+ }
+
+ switch (text_data->anchor)
+ {
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_E:
+ origin_y -= logical_height / 2.0;
+ break;
+ case GTK_ANCHOR_SW:
+ case GTK_ANCHOR_S:
+ case GTK_ANCHOR_SE:
+ origin_y -= logical_height;
+ break;
+ default:
+ break;
+ }
+
+ /* Return the origin of the text if required. */
+ if (origin_x_return)
+ *origin_x_return = origin_x;
+ if (origin_y_return)
+ *origin_y_return = origin_y;
+
+ /* Now calculate the bounds. */
+ bounds->x1 = origin_x;
+ bounds->y1 = origin_y;
+
+ if (text_data->width > 0)
+ {
+ /* If the text width has been set, and the alignment isn't
+ PANGO_ALIGN_LEFT, we need to adjust for the difference between
+ the actual width of the text and the width that was used for
+ alignment. */
+ switch (text_data->alignment)
+ {
+ case PANGO_ALIGN_CENTER:
+ bounds->x1 += (align_width - logical_width) / 2.0;
+ break;
+ case PANGO_ALIGN_RIGHT:
+ bounds->x1 += align_width - logical_width;
+ break;
+ default:
+ break;
+ }
+ }
+
+ bounds->x2 = origin_x + logical_width;
+ bounds->y2 = origin_y + logical_height;
+ }
+
+ return layout;
+}
+
+
+static void
+goo_canvas_text_update (GooCanvasItem *item,
+ gboolean entire_tree,
+ cairo_t *cr,
+ GooCanvasBounds *bounds)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasText *text = (GooCanvasText*) item;
+ PangoLayout *layout;
+
+ 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. */
+ layout = goo_canvas_text_create_layout (text, cr, &simple->bounds,
+ NULL, NULL);
+ g_object_unref (layout);
+
+ 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 GooCanvasItem*
+goo_canvas_text_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;
+ GooCanvasText *text = (GooCanvasText*) item;
+ GooCanvasItem *found_item = NULL;
+ PangoLayout *layout;
+ GooCanvasBounds bounds;
+ PangoLayoutIter *iter;
+ PangoRectangle log_rect;
+ int px, py;
+ double user_x = x, user_y = y;
+ gdouble origin_x, origin_y;
+
+ /* If there is no text just return. */
+ if (!text->text_data->text || !text->text_data->text[0])
+ return NULL;
+
+ if (simple->need_update)
+ goo_canvas_item_ensure_updated (item);
+
+ /* Check if the item should receive events. */
+ 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;
+ if (simple_data->pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK)
+ {
+ if (!goo_canvas_style_set_fill_options (simple_data->style, cr))
+ return NULL;
+ }
+ }
+
+ cairo_save (cr);
+ if (simple_data->transform)
+ cairo_transform (cr, simple_data->transform);
+
+ cairo_device_to_user (cr, &user_x, &user_y);
+
+ layout = goo_canvas_text_create_layout (text, cr, &bounds,
+ &origin_x, &origin_y);
+
+ /* Convert the coordinates into Pango units. */
+ px = (user_x - origin_x) * PANGO_SCALE;
+ py = (user_y - origin_y) * PANGO_SCALE;
+
+ /* We use line extents here. Note that SVG uses character cells to determine
+ hits so we have slightly different behavior. */
+ iter = pango_layout_get_iter (layout);
+ do
+ {
+ pango_layout_iter_get_line_extents (iter, NULL, &log_rect);
+
+ if (px >= log_rect.x && px < log_rect.x + log_rect.width
+ && py >= log_rect.y && py < log_rect.y + log_rect.height)
+ {
+ found_item = item;
+ break;
+ }
+
+ } while (pango_layout_iter_next_line (iter));
+
+ pango_layout_iter_free (iter);
+
+ g_object_unref (layout);
+
+ cairo_restore (cr);
+
+ return found_item;
+}
+
+
+static void
+goo_canvas_text_paint (GooCanvasItem *item,
+ cairo_t *cr,
+ GooCanvasBounds *bounds,
+ gdouble scale)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasText *text = (GooCanvasText*) item;
+ PangoLayout *layout;
+ GooCanvasBounds layout_bounds;
+ gdouble origin_x, origin_y;
+
+ /* If there is no text just return. */
+ if (!text->text_data->text || !text->text_data->text[0])
+ 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_new_path (cr);
+ layout = goo_canvas_text_create_layout (text, cr, &layout_bounds,
+ &origin_x, &origin_y);
+ cairo_move_to (cr, origin_x, origin_y);
+ pango_cairo_show_layout (cr, layout);
+ g_object_unref (layout);
+
+ cairo_restore (cr);
+}
+
+
+static void
+goo_canvas_text_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;
+ GooCanvasText *text = (GooCanvasText*) item;
+ GooCanvasTextModel *emodel = (GooCanvasTextModel*) model;
+
+ /* If our text_data was allocated, free it. */
+ if (!simple->model)
+ g_slice_free (GooCanvasTextData, text->text_data);
+
+ /* Now use the new model's text_data instead. */
+ text->text_data = &emodel->text_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_text_get_item_at;
+ iface->update = goo_canvas_text_update;
+ iface->paint = goo_canvas_text_paint;
+ iface->set_model = goo_canvas_text_set_model;
+}
+
+
+
+/*
+ * GooCanvasTextModel.
+ */
+
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+static void goo_canvas_text_model_finalize (GObject *object);
+static void goo_canvas_text_model_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void goo_canvas_text_model_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasTextModel, goo_canvas_text_model,
+ GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+ G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+ item_model_interface_init))
+
+
+static void
+goo_canvas_text_model_class_init (GooCanvasTextModelClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+
+ gobject_class->finalize = goo_canvas_text_model_finalize;
+
+ gobject_class->get_property = goo_canvas_text_model_get_property;
+ gobject_class->set_property = goo_canvas_text_model_set_property;
+
+ goo_canvas_text_install_common_properties (gobject_class);
+}
+
+
+static void
+goo_canvas_text_model_init (GooCanvasTextModel *emodel)
+{
+
+}
+
+
+GooCanvasItemModel*
+goo_canvas_text_model_new (GooCanvasItemModel *parent,
+ const char *string,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ GtkAnchorType anchor,
+ ...)
+{
+ GooCanvasItemModel *model;
+ GooCanvasTextModel *emodel;
+ GooCanvasTextData *text_data;
+ const char *first_property;
+ va_list var_args;
+
+ model = g_object_new (GOO_TYPE_CANVAS_TEXT_MODEL, NULL);
+ emodel = (GooCanvasTextModel*) model;
+
+ text_data = &emodel->text_data;
+ text_data->text = g_strdup (string);
+ text_data->x = x;
+ text_data->y = y;
+ text_data->width = width;
+ text_data->anchor = anchor;
+
+ va_start (var_args, anchor);
+ 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_text_model_finalize (GObject *object)
+{
+ /*GooCanvasTextModel *emodel = (GooCanvasTextModel*) object;*/
+
+ G_OBJECT_CLASS (goo_canvas_text_model_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_text_model_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasTextModel *emodel = (GooCanvasTextModel*) object;
+
+ goo_canvas_text_get_common_property (object, &emodel->text_data, prop_id,
+ value, pspec);
+}
+
+
+static void
+goo_canvas_text_model_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasTextModel *emodel = (GooCanvasTextModel*) object;
+
+ goo_canvas_text_set_common_property (object, &emodel->text_data, prop_id,
+ value, pspec);
+ g_signal_emit_by_name (emodel, "changed", TRUE);
+}
+
+
+static GooCanvasItem*
+goo_canvas_text_model_create_item (GooCanvasItemModel *model,
+ GooCanvas *canvas)
+{
+ GooCanvasItem *item;
+
+ item = g_object_new (GOO_TYPE_CANVAS_TEXT, NULL);
+ goo_canvas_item_set_model (item, model);
+
+ return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+ iface->create_item = goo_canvas_text_model_create_item;
+}
Index: goocanvastext.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastext.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- goocanvastext.h 13 Apr 2006 16:06:04 -0000 1.3
+++ goocanvastext.h 29 Nov 2006 18:40:53 -0000 1.4
@@ -13,6 +13,19 @@
G_BEGIN_DECLS
+/* This is the data used by both model and view classes. */
+typedef struct _GooCanvasTextData GooCanvasTextData;
+struct _GooCanvasTextData
+{
+ gchar *text;
+ gboolean use_markup;
+
+ gdouble x, y, width;
+ GtkAnchorType anchor;
+ PangoAlignment alignment;
+};
+
+
#define GOO_TYPE_CANVAS_TEXT (goo_canvas_text_get_type ())
#define GOO_CANVAS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_TEXT, GooCanvasText))
#define GOO_CANVAS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_TEXT, GooCanvasTextClass))
@@ -33,30 +46,68 @@
{
GooCanvasItemSimple parent;
- gchar *text;
- gboolean use_markup;
- PangoFontDescription *font_desc;
-
- gdouble x, y, width;
- GtkAnchorType anchor;
- PangoAlignment alignment;
+ GooCanvasTextData *text_data;
};
struct _GooCanvasTextClass
{
GooCanvasItemSimpleClass parent_class;
+
+ /* The font options we always use. */
+ cairo_font_options_t *font_options;
};
-GType goo_canvas_text_get_type (void) G_GNUC_CONST;
-GooCanvasItem* goo_canvas_text_new (GooCanvasItem *parent,
- const char *string,
- gdouble x,
- gdouble y,
- gdouble width,
- GtkAnchorType anchor,
- const gchar *first_property,
- ...);
+GType goo_canvas_text_get_type (void) G_GNUC_CONST;
+
+GooCanvasItem* goo_canvas_text_new (GooCanvasItem *parent,
+ const char *string,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ GtkAnchorType anchor,
+ ...);
+
+
+
+#define GOO_TYPE_CANVAS_TEXT_MODEL (goo_canvas_text_model_get_type ())
+#define GOO_CANVAS_TEXT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_TEXT_MODEL, GooCanvasTextModel))
+#define GOO_CANVAS_TEXT_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_TEXT_MODEL, GooCanvasTextModelClass))
+#define GOO_IS_CANVAS_TEXT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_TEXT_MODEL))
+#define GOO_IS_CANVAS_TEXT_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_TEXT_MODEL))
+#define GOO_CANVAS_TEXT_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_TEXT_MODEL, GooCanvasTextModelClass))
+
+
+typedef struct _GooCanvasTextModel GooCanvasTextModel;
+typedef struct _GooCanvasTextModelClass GooCanvasTextModelClass;
+
+/**
+ * GooCanvasTextModel
+ *
+ * The #GooCanvasTextModel-struct struct contains private data only.
+ */
+struct _GooCanvasTextModel
+{
+ GooCanvasItemModelSimple parent_object;
+
+ GooCanvasTextData text_data;
+};
+
+struct _GooCanvasTextModelClass
+{
+ GooCanvasItemModelSimpleClass parent_class;
+};
+
+
+GType goo_canvas_text_model_get_type (void) G_GNUC_CONST;
+
+GooCanvasItemModel* goo_canvas_text_model_new (GooCanvasItemModel *parent,
+ const char *string,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ GtkAnchorType anchor,
+ ...);
G_END_DECLS
--- goocanvastextview.c DELETED ---
--- goocanvastextview.h DELETED ---
--- goocanvasview.c DELETED ---
--- goocanvasview.h DELETED ---
- Previous message: [cairo-commit] goocanvas/src goocanvas.c, NONE,
1.1 goocanvasitemmodel.c, NONE, 1.1 goocanvasitemmodel.h, NONE,
1.1 goocanvasstyle.c, NONE, 1.1 goocanvasstyle.h, NONE,
1.1 goocanvaswidget.c, NONE, 1.1 goocanvaswidget.h, NONE, 1.1
- Next message: [cairo-commit] goocanvas configure.in,1.9,1.10
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list