![]() |
![]() |
![]() |
GooCanvas Reference Manual | ![]() |
---|
Creating New ItemsCreating New Items — how to create new canvas items. |
Here's an example of how to create a new simple canvas item. (Note that this item doesn't have a model-view split.)
Here's the header file - a fairly standard GObject header file. Our item derives from GooCanvasItemSimple and just has its own x, y, width and height variables:
/* * GooCanvas Demo. Copyright (C) 2006 Damon Chaplin. * Released under the GNU LGPL license. See COPYING for details. * * demo-item.c - a simple demo item. */ #ifndef __GOO_DEMO_ITEM_H__ #define __GOO_DEMO_ITEM_H__ #include <gtk/gtk.h> #include "goocanvasitemsimple.h" G_BEGIN_DECLS #define GOO_TYPE_DEMO_ITEM (goo_demo_item_get_type ()) #define GOO_DEMO_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_DEMO_ITEM, GooDemoItem)) #define GOO_DEMO_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_DEMO_ITEM, GooDemoItemClass)) #define GOO_IS_DEMO_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_DEMO_ITEM)) #define GOO_IS_DEMO_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_DEMO_ITEM)) #define GOO_DEMO_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_DEMO_ITEM, GooDemoItemClass)) typedef struct _GooDemoItem GooDemoItem; typedef struct _GooDemoItemClass GooDemoItemClass; struct _GooDemoItem { GooCanvasItemSimple parent_object; gdouble x, y, width, height; }; struct _GooDemoItemClass { GooCanvasItemSimpleClass parent_class; }; GType goo_demo_item_get_type (void) G_GNUC_CONST; GooCanvasItem* goo_demo_item_new (GooCanvasItem *parent, gdouble x, gdouble y, gdouble width, gdouble height, ...); G_END_DECLS #endif /* __GOO_DEMO_ITEM_H__ */
And here's the source file:
/* * GooCanvas Demo. Copyright (C) 2006 Damon Chaplin. * Released under the GNU LGPL license. See COPYING for details. * * demo-item.c - a simple demo item. */ #include <config.h> #include "goocanvas.h" #include "demo-item.h" /* Use the GLib convenience macro to define the type. GooDemoItem is the class struct, goo_demo_item is the function prefix, and our class is a subclass of GOO_TYPE_CANVAS_ITEM_SIMPLE. */ G_DEFINE_TYPE (GooDemoItem, goo_demo_item, GOO_TYPE_CANVAS_ITEM_SIMPLE) /* The standard object initialization function. */ static void goo_demo_item_init (GooDemoItem *demo_item) { demo_item->x = 0.0; demo_item->y = 0.0; demo_item->width = 0.0; demo_item->height = 0.0; } /* The convenience function to create new items. This should start with a parent argument and end with a variable list of object properties to fit in with the standard canvas items. */ GooCanvasItem* goo_demo_item_new (GooCanvasItem *parent, gdouble x, gdouble y, gdouble width, gdouble height, ...) { GooCanvasItem *item; GooDemoItem *demo_item; const char *first_property; va_list var_args; item = g_object_new (GOO_TYPE_DEMO_ITEM, NULL); demo_item = (GooDemoItem*) item; demo_item->x = x; demo_item->y = y; demo_item->width = width; demo_item->height = height; 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) { goo_canvas_item_add_child (parent, item, -1); g_object_unref (item); } return item; } /* The update method. This is called when the canvas is initially shown and also whenever the object is updated and needs to change its size and/or shape. It should calculate its new bounds in its own coordinate space, storing them in simple->bounds. */ static void goo_demo_item_update (GooCanvasItemSimple *simple, cairo_t *cr) { GooDemoItem *demo_item = (GooDemoItem*) simple; /* Compute the new bounds. */ simple->bounds.x1 = demo_item->x; simple->bounds.y1 = demo_item->y; simple->bounds.x2 = demo_item->x + demo_item->width; simple->bounds.y2 = demo_item->y + demo_item->height; } /* The paint method. This should draw the item on the given cairo_t, using the item's own coordinate space. */ static void goo_demo_item_paint (GooCanvasItemSimple *simple, cairo_t *cr, GooCanvasBounds *bounds) { GooDemoItem *demo_item = (GooDemoItem*) simple; cairo_move_to (cr, demo_item->x, demo_item->y); cairo_line_to (cr, demo_item->x, demo_item->y + demo_item->height); cairo_line_to (cr, demo_item->x + demo_item->width, demo_item->y + demo_item->height); cairo_line_to (cr, demo_item->x + demo_item->width, demo_item->y); cairo_close_path (cr); goo_canvas_style_set_fill_options (simple->simple_data->style, cr); cairo_fill (cr); } /* Hit detection. This should check if the given coordinate (in the item's coordinate space) is within the item. If it is it should return the item, otherwise it should return NULL. */ static GooCanvasItem* goo_demo_item_get_item_at (GooCanvasItemSimple *simple, gdouble x, gdouble y, cairo_t *cr, gboolean is_pointer_event) { GooDemoItem *demo_item = (GooDemoItem*) simple; if (x < demo_item->x || (x > demo_item->x + demo_item->width) || y < demo_item->y || (y > demo_item->y + demo_item->height)) return NULL; return (GooCanvasItem*) simple; } /* The class initialization function. Here we set the class' update(), paint() and get_item_at() methods. */ static void goo_demo_item_class_init (GooDemoItemClass *klass) { GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass; simple_class->update = goo_demo_item_update; simple_class->paint = goo_demo_item_paint; simple_class->get_item_at = goo_demo_item_get_item_at; }