While GnomeCanvas widget is inside the libgnomeui library, it definitely deserves a separate chapter. The canvas is a very high level high performance graphics drawing widget and on top of that it's easy to use. It includes support for both Xlib drawn graphics, which is faster especially over the network, and anti-aliased drawing for better looking results.
To create a gnome canvas widget, you call the gnome_canvas_new. You need to make sure that the canvas is created with a proper visual and colormap. For example if you wish to draw imlib images inside it, you should do this:
GtkWidget *canvas; ... gtk_widget_push_visual(gdk_imlib_get_visual()); gtk_widget_push_colormap(gdk_imlib_get_colormap()); canvas = gnome_canvas_new(); gtk_widget_pop_visual(); gtk_widget_pop_colormap();
GnomeCanvas *canvas; ... /*already created a canvas, now set it up*/ gnome_canvas_set_pixels_per_unit(canvas,10); gnome_canvas_set_scroll_region(canvas,0.0,0.0,50.0,50.0);
In the canvas there are items, the actual objects that are on the canvas, and groups, which are just groupings of items. A group is actually derived from a base GnomeCanvasItem object, this is useful to applying functions to all the items inside the group. Such as moving or hiding the entire group. There is also one default group, the root group. You can get this group by calling gnome_canvas_root.
Creating items is slightly different usual. It's using the standard GTK+ object model argument mechanism. Basically you call gnome_canvas_item, with the parent canvas group as the first argument, the type of object as the second argument, and then arguments given in pairs (argument, value), terminated with a NULL. This is best illustrated by an example:
GnomeCanvas *canvas; GnomeCanvasItem *item; ... item = gnome_canvas_item_new(gnome_canvas_root(canvas), GNOME_TYPE_CANVAS_RECT, "x1", 1.0, "y1", 1.0, "x2", 23.0, "y2", 20.0, "fill_color", "black", NULL);
To find out the arguments that each item takes, consult the gnome documentation or look into the libgnomeui/gnome-canvas*.h header files. They contain a table at the top of the file just like the one that follows (which was taken from libgnomeui/gnome-canvas-rect-ellipse.h).
For example here are arguments for rectangle (GNOME_TYPE_CANVAS_RECT) and ellipse (GNOME_TYPE_CANVAS_ELLIPSE):
Table 3-14. Arguments for Rectangle and Ellipse Canvas Items
|x1||double||RW||Leftmost coordinate of rectangle or ellipse|
|y1||double||RW||Topmost coordinate of rectangle or ellipse|
|x2||double||RW||Rightmost coordinate of rectangle or ellipse|
|y2||double||RW||Bottommost coordinate of rectangle or ellipse|
|fill_color||string||W||X color specification for fill color, or NULL pointer for no color (transparent)|
|fill_color_gdk||GdkColor*||RW||Allocated GdkColor for fill|
|outline_color||string||W||X color specification for outline color, or NULL pointer for no color (transparent)|
|outline_color_gdk||GdkColor*||RW||Allocated GdkColor for outline|
|fill_stipple||GdkBitmap*||RW||Stipple pattern for fill|
|outline_stipple||GdkBitmap*||RW||Stipple pattern for outline|
|width_pixels||uint||RW||Width of the outline in pixels. The outline will not be scaled when the canvas zoom factor is changed.|
|width_units||double||RW||Width of the outline in canvas units. The outline will be scaled when the canvas zoom factor is changed.|
Now suppose we want to change some of these properties. This is done with a call to gnome_canvas_item_set. The first argument to this function is the canvas item object pointer. The next arguments are the same argument pairs as above when creating a new canvas object. For example if we want to set the color to red on the rectangle we created above, we can do this:
GnomeCanvas *canvas; GnomeCanvasItem *item; ... gnome_canvas_item_set(item "fill_color", "red", NULL);
Then there are item methods for other operations on items. For example the gnome_canvas_item_move method will take the x and y as second and third argument, and will move the item relative to it's current position by x and y. Or the gnome_canvas_item_hide and gnome_canvas_item_show, which hide and show the item, respectively. To control the z order of the items, you can use the methods gnome_canvas_item_raise_to_top and gnome_canvas_item_lower_to_bottom to raise or lower the item to the top or bottom of it's parent group's z order. To have finer control over z order you can use the gnome_canvas_item_raise and gnome_canvas_item_lower methods which take an extra integer argument which is 1 or larger, and specifies the number of levels the item should move in the z order.
To create a canvas which uses anti aliasing for rendering of it's items, instead of gnome_canvas_new function, you should use the gnome_canvas_new_aa. You should also use the GdkRgb visual and colormap. So you would do this to create a new anti-aliased canvas:
GtkWidget *canvas; ... gtk_widget_push_visual (gdk_rgb_get_visual ()); gtk_widget_push_colormap (gdk_rgb_get_cmap ()); canvas = gnome_canvas_new_aa (); gtk_widget_pop_colormap (); gtk_widget_pop_visual ();
Anti-aliased canvas items can generally do more then normal canvas items. This is because of limitations of Xlib as a graphics library. It can for example do any kind of affine transformation on it's objects, where on and Xlib canvas you can only do affine transformations on some objects.