Creare un GnomeCanvasItem

Questo capitolo mostra come scrivere un GnomeCanvasItem. Oggetti personalizzati vi permettono di estendere il canvas. Prendete in considerazione l'implementazione di un nuovo oggetto per il canvas se gli oggetti standard (o una loro combinazione presente in GnomeCanvasGroup) non sono sufficienti a soddisfare le vostre necessità. A titolo di esempio, questo capitolo descrive l'implementazione di un GnomeCanvasRect.

Introduzione

Per scrivere un GnomeCanvasItem, è necessario creare una implementazione concreta di una astrazione della classe di base GnomeCanvasItem. Questo capitolo assume che abbiate letto il il capitolo I tipi e gli oggetti in GTK+ e abbiate compreso come opera GtkObject. Dovete comprendere gli oggetti per poter poterne scrivere di vostri.

Gli oggetti del Canvas possono supportare la modalitá GDK, la modalitá antialiased, oppure entrambe. Il canvas possiede un flag che specifica la sua tipologia. Gli oggetti possono controllare questo flag a runtime:

  if (item->canvas->aa)
    {
      /* modalità antialiased */
    } 
  else 
    {
      /* Modalità Gdk  */
    }
    

Ad ogni modo, la maggior parte del codice sarà identico per entrambe le tipologie. L'unica reale differenza è il processo di disegno: la modalità GDK disegna in una pixmap, la modalità antialiased invece in un buffer RGB. Non è necessario supportare entrambe le tipologie di canvas, fate unicamente attenzione a non utilizzare oggetti che non sono supportati dal tipo di canvas.

Ecco il tipo GnomeCanvasItem per la sotto-classe:

typedef struct _GnomeCanvasItem       GnomeCanvasItem;
typedef struct _GnomeCanvasItemClass  GnomeCanvasItemClass;

struct _GnomeCanvasItem {
  GtkObject object;

  /* Il Canvas dove ci troviamo */
  GnomeCanvas *canvas;

  /* Gruppo genitore */
  GnomeCanvasItem *parent;

  /* Bounding box per questo oggetto */
  double x1, y1, x2, y2;

  /* Se NULL, l'indentità si trasforma */
  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);

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

  /* Specifica per il  Gdk mode */
  void (* draw) (GnomeCanvasItem *item, GdkDrawable *drawable,
                 int x, int y, int width, int height);

  /* Specifica per l'RGB mode */
  void (* render) (GnomeCanvasItem *item, GnomeCanvasBuf *buf);

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

  /* Obsoleta; non utilizzata in Gnome 1.0 */
  void (* translate) (GnomeCanvasItem *item, double dx, double dy);

  /* Deprecata, ma utilizzata occasionalmente in 
   * Gnome 1.0
   */
  void (* bounds) (GnomeCanvasItem *item, 
                   double *x1, double *y1, 
                   double *x2, double *y2);

    gint (* event) (GnomeCanvasItem *item, GdkEvent *event);
};
    

Questo capitolo descrive ciascun punto in dettaglio, continuate a leggere!

GnomeCanvasRect

GnomeCanvasRect e GnomeCanvasEllipse hanno implementazione quasi identiche, infatti tutti e tre i metodi di GnomeCanvasItem sono implementati attraverso la classe di base GnomeCanvasRE. GnomeCanvasRE gestisce la loro interfaccia visibile all'utente, come discusso nel capitolo precedente.

Per comprendere l'implementazione di GnomeCanvasRect presentata in questo capitolo dovete aver prima letto la discussione, nel precedente capitolo, sugli argomenti che l'oggetto supporta. È interessante anche l'oggetto in sé:

typedef struct _GnomeCanvasRE GnomeCanvasRE;

struct _GnomeCanvasRE {
  GnomeCanvasItem item;

  double x1, y1, x2, y2;        /* Angoli dell'oggeto e sue coordinate */
  double width;                 /* Spessore bordo */

  guint fill_color;             /* Colore di riempimento, RGBA */
  guint outline_color;          /* Colore del bordo, RGBA */

  gulong fill_pixel;            /* Colore di riempimento */
  gulong outline_pixel;         /* Colore del bordo */

  GdkBitmap *fill_stipple;      /* Stipple per riempimento */
  GdkBitmap *outline_stipple;   /* Stipple per bordo */

  GdkGC *fill_gc;               /* GC per riempimento */
  GdkGC *outline_gc;            /* GC per bordo */

  /* Il seguente codice è specifico dell'antialiased mode */

  ArtSVP *fill_svp;             /* Il SVP per la forma riempita */
  ArtSVP *outline_svp;          /* Il SVP per la forma del bordo */

  /* Flags di configurazione */

  unsigned int fill_set : 1;    /* È impostato il colore di riempimento? */
  unsigned int outline_set : 1; /* È impostato il colore del bordo? */

  /* Lo spessore del bordo è specificato in pixels o in unità? */
  unsigned int width_pixels : 1;
};
      

GnomeCanvasRect non aggiunge alcun membro che non si trovi in GnomeCanvasRE. Le implementazioni di queto metodo discusse in questo capitolo dovrebbero chiarire la presenza di vari membri della struttura.

Questo capitolo descrive tutte le componenti interessanti di GnomeCanvasRect. Il codice sorgente completo viene fornito con le librerie di Gnome.