Writing a GnomeCanvasItem

Table of Contents
Overview
Drawing Methods
Other Methods

This chapter explains how to write a GnomeCanvasItem. Custom canvas items allows you to extend the canvas; consider writing a canvas item if the stock items (or some combination of them placed in a GnomeCanvasGroup) do not meet your needs. As an example, the chapter describes the implementation of GnomeCanvasRect.

Overview

To write a GnomeCanvasItem, you create a concrete implemenation of the GnomeCanvasItem abstract base class. This chapter assumes you've read the chapter called The GTK+ Object and Type System and understand how a GtkObject works; you will need to understand objects to write your own.

Canvas items can support GDK mode, antialiased mode, or both. The canvas has a flag indicating which kind of canvas it is; items can check this flag at runtime:


  if (item->canvas->aa)
    {
      /* antialiased mode */
    } 
  else 
    {
      /* Gdk mode */
    }
    

However, most code will be the same for both canvas types. The only real difference is in the drawing process: GDK mode draws to a pixmap, antialiased mode draws to an RGB buffer. You do not have to support both kinds of canvas, just be careful not to use your item with the unsupported canvas type.

Here is the GnomeCanvasItem type you will be subclassing:


typedef struct _GnomeCanvasItem       GnomeCanvasItem;
typedef struct _GnomeCanvasItemClass  GnomeCanvasItemClass;

struct _GnomeCanvasItem {
  GtkObject object;

  /* Canvas we are on */
  GnomeCanvas *canvas;

  /* Parent group */
  GnomeCanvasItem *parent;

  /* Bounding box for this item */
  double x1, y1, x2, y2;

  /* If NULL, the identity transform */
  double *xform;
};

struct _GnomeCanvasItemClass {
  GtkObjectClass parent_class;

  void (* update) (GnomeCanvasItem *item, double *affine, 
                   ArtSVP *clip_path, int flags);

  void (* realize) (GnomeCanvasItem *item);

  void (* unrealize) (GnomeCanvasItem *item);

  void (* map) (GnomeCanvasItem *item);

  void (* unmap) (GnomeCanvasItem *item);

  /* Unused in Gnome 1.0 */
  ArtUta *(* coverage) (GnomeCanvasItem *item);

  /* Used only in Gdk mode */
  void (* draw) (GnomeCanvasItem *item, GdkDrawable *drawable,
                 int x, int y, int width, int height);

  /* Used only in RGB mode */
  void (* render) (GnomeCanvasItem *item, GnomeCanvasBuf *buf);

  double (* point) (GnomeCanvasItem *item, double x, double y, 
                    int cx, int cy,
                    GnomeCanvasItem **actual_item);

  /* Obsolete; not used in Gnome 1.0 */
  void (* translate) (GnomeCanvasItem *item, double dx, double dy);

  /* Deprecated, but occasionally used in Gnome 1.0 */
  void (* bounds) (GnomeCanvasItem *item, 
                   double *x1, double *y1, 
                   double *x2, double *y2);

  /* The only canvas item class function that is also a signal */
  gint (* event) (GnomeCanvasItem *item, GdkEvent *event);
};
    

This chapter explains everything in more detail; keep reading.

GnomeCanvasRect

GnomeCanvasRect and GnomeCanvasEllipse have almost identical implementations; in fact, all but three of GnomeCanvasItem's methods are implemented by the GnomeCanvasRE base class. GnomeCanvasRE handles their user-visible interface, as discussed in the previous chapter.

To understand the implementation of GnomeCanvasRect presented in this chapter, you should first read the previous chapter's discussion of the object arguments it supports. You'll also want to see the object itself:


typedef struct _GnomeCanvasRE GnomeCanvasRE;

struct _GnomeCanvasRE {
  GnomeCanvasItem item;

  double x1, y1, x2, y2;        /* Corners of item, item coordinates */
  double width;                 /* Outline width, item coordinates */

  guint fill_color;             /* Fill color, RGBA */
  guint outline_color;          /* Outline color, RGBA */

  gulong fill_pixel;            /* Fill color */
  gulong outline_pixel;         /* Outline color */

  GdkBitmap *fill_stipple;      /* Stipple for fill */
  GdkBitmap *outline_stipple;   /* Stipple for outline */

  GdkGC *fill_gc;               /* GC for filling */
  GdkGC *outline_gc;            /* GC for outline */

  /* Antialiased specific stuff follows */

  ArtSVP *fill_svp;             /* The SVP for the filled shape */
  ArtSVP *outline_svp;          /* The SVP for the outline shape */

  /* Configuration flags */

  unsigned int fill_set : 1;    /* Is fill color set? */
  unsigned int outline_set : 1; /* Is outline color set? */
  unsigned int width_pixels : 1;/* Is outline width specified in pixels or units? */
};
      

GnomeCanvasRect adds no new members not found in GnomeCanvasRE. The method implementations discussed in this chapter should make clear the purpose of the various struct members.

This chapter discusses all the interesting parts of GnomeCanvasRect; complete source code comes with the Gnome libraries.