| GooCanvas Reference Manual |
|---|
Creating New ItemsCreating New Items — how to create new canvas items. |
There are 3 ways to create new canvas items, listed here in increasing order of complexity:
These will be discussed in turn below. (It is also possible to create new container items by subclassing GooCanvasGroup, but that is not covered here.)
The final part of this section covers
For items that consist of a simple graphic element such
as a line, rectangle or circle, it is possible to create a subclass
of GooCanvasItemSimple and override just one method,
simple_create_path()
The simple_create_path()
This example shows the simple_create_path()
static void
my_item_simple_create_path (GooCanvasItemSimple *simple,
cairo_t *cr)
{
MyItem *item = (MyItem*) simple;
cairo_rectangle (cr, item->x, item->y, item->width, item->height);
}
Whenever the item is changed in some way it should call
goo_canvas_item_simple_changed(), passing a boolean value indicating
whether the item's bounds need to be recalculated or if it only needs
to be repainted. The GooCanvasItemSimple code will take care of
updating the item and repainting the appropriate parts of the canvas.
Most items will need more than a simple line or rectangle, so they
will need to create a subclass of GooCanvasItemSimple and override
three methods, simple_update()simple_paint()simple_is_item_at()
The simple_update()cairo_identity_matrix()
The simple_paint()goo_canvas_style_set_stroke_options()
and goo_canvas_style_set_fill_options() before calling cairo_stroke()cairo_fill()
The simple_is_item_at()TRUE
This example code shows the simple_update()simple_paint()simple_is_item_at()
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;
}
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);
}
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;
}
As with the simple GooCanvasItemSimple subclass, the item should
call goo_canvas_item_simple_changed() whenever it is changed, to
ensure that the item's bounds are recomputed and it is repainted
if necessary.
The most complicated way to create new canvas items is to implement the GooCanvasItem interface directly. This should not be needed in most cases, but may be desired if the developer wants to avoid the memory and processor overheads associated with the GooCanvasItemSimple class, or if the developer wants to turn an existing application object into a canvas item.
At a minimum the canvas item must implement these 6 methods:
get_parent()
set_parent()
get_bounds()goo_canvas_item_ensure_updated() if
necessary.
update()TRUE
paint()
get_items_at()
The canvas item must also implement the "parent", "title", "description", "visibility", "visibility-threshold", "transform" and "pointer-events" properties. (The last 4 properties can simply be ignored if the application doesn't intend to use them.)
If the canvas item will be used within a container that does item layout, such as GooCanvasTable, it must implement the first two methods here at least:
get_requested_area()
allocate_area()
get_requested_height()
If the canvas item supports a transformation matrix it must implement:
get_transform()
set_transform()
If the canvas item supports a GooCanvasStyle setting, it must implement:
get_style()
set_style()
Since GooCanvasItemSimple implements most of the above methods and properties its source code is a good place to look for help.
As with creating canvas items, to create item models it is possible to subclass GooCanvasItemModelSimple or to implement the GooCanvasItemModel interface directly.
Subclassing GooCanvasItemModelSimple is very easy, since only one
method from the GooCanvasItemModel interface must be implemented -
create_item()
The GooCanvasItemModelSimple subclass should emit the "changed" signal whenever it has changed, with a boolean flag indicating if the bounds need to be recomputed. The canvas items will connect to this signal and request an update or a redraw as appropriate.
To implement the GooCanvasItemModel interface directly, the class
must implement the get_parent()set_parent()create_item()get_transform()set_transform()get_style()set_style()
The class must also implement the "parent", "title", "description", "can-focus", "visibility", "visibility-threshold", "transform" and "pointer-events" properties. (The last 4 properties can simply be ignored if the application doesn't intend to use them.)