| 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,
const 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 TRUE,
otherwise it should return FALSE. */
static gboolean
goo_demo_item_is_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 FALSE;
return TRUE;
}
/* The class initialization function. Here we set the class' update(), paint()
and is_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->is_item_at = goo_demo_item_is_item_at;
}