GtkStyle e i temi

GtkStyle non è una parte di GDK, ma è un'importante layer di astrazione tra GTK+ e GDK che permette agli utenti di personalizzare il modo in cui i widget vengono rappresentati. Anziché utilizzare direttamente GDK per disegnare un widget, si dovrebbero preferire le risorse fornite da uno GtkStyle, e utilizzare le speciali funzioni di disegno dichiarate in gtk/gtkstyle.h. Spesso non esiste una funzione appropriata per compiere un'azione specifica ma, se esiste, dovrebbe essere utilizzata.

Un GtkStyle memorizza risorse di GDK da utilizzare nel disegno dei widget. Gli stili permettono ai widget di condividere queste risorse riducendo l'overhead; rendono anche possibile la personalizzazione dei widget da parte degli utenti. Ecco la struttura GtkStyle:

typedef struct _GtkStyle GtkStyle;

struct _GtkStyle
{
  GtkStyleClass *klass;

  GdkColor fg[5];
  GdkColor bg[5];
  GdkColor light[5];
  GdkColor dark[5];
  GdkColor mid[5];
  GdkColor text[5];
  GdkColor base[5];
  
  GdkColor black;
  GdkColor white;
  GdkFont *font;
  
  GdkGC *fg_gc[5];
  GdkGC *bg_gc[5];
  GdkGC *light_gc[5];
  GdkGC *dark_gc[5];
  GdkGC *mid_gc[5];
  GdkGC *text_gc[5];
  GdkGC *base_gc[5];
  GdkGC *black_gc;
  GdkGC *white_gc;
  
  GdkPixmap *bg_pixmap[5];
  
  /* private */
  
  gint ref_count;
  gint attach_count;
  
  gint depth;
  GdkColormap *colormap;
  
  GtkThemeEngine *engine;
  
  gpointer        engine_data;
  
  GtkRcStyle     *rc_style;

  GSList         *styles;
};

    

I campi privati dovrebbero essere ignorati. I campi pubblici contengono risorse di GDK per il rendering dei widget. Il primo gruppo di campi contiene array di colori; questi array vengono indicizzati dall'enumerazione di stato dei widget (GTK_STATE_ACTIVE, etc.). Un widget attivo usa widget->style->fg[GTK_STATE_NORMAL] per disegnare del testo, per esempio. Ogni widget ha uno stile associato, memorizzato nel campo style di GtkWidget.

I widget dovrebbero usare il font memorizzato nello GtkStyle associato a essi; dovrebbero anche utilizzare i GC dello stile quando disegnano con i colori dello stile.

GtkStyle contiene anche una tabella virtuale, GtkStyleClass, che può essere implementata da una libreria caricata dinamicamente. La tabella virtuale è abbastanza grande, quindi non è riprodotta qui. Date un occhiata a gtk/gtkstyle.h.

gtk/gtkstyle.h contiene funzioni grafiche che utilizzano la tabella virtuale dello stile per disegnare vari elementi della GUI. Ci sono due varianti di ogni funzione. Una variante, prefissata con gtk_draw_, disegna in un qualunque drawable; l'altra variante, prefissata con gtk_paint_, disegna parti di un widget. Per esempio, gtk_draw_shadow() è dichiarata nel modo seguente:

void gtk_draw_shadow  (GtkStyle      *style,
                       GdkWindow     *window,
                       GtkStateType   state_type,
                       GtkShadowType  shadow_type,
                       gint           x,
                       gint           y,
                       gint           width,
                       gint           height);

    

Mentre gtk_paint_shadow() ha in più gli argomenti area, widget, e detail:

void gtk_paint_shadow  (GtkStyle     *style,
                        GdkWindow    *window,
                        GtkStateType  state_type,
                        GtkShadowType shadow_type,
                        GdkRectangle  *area,
                        GtkWidget     *widget,
                        gchar         *detail,
                        gint           x,
                        gint           y,
                        gint           width,
                        gint           height);

    

Tutte le funzioni gtk_paint_ hanno gli stessi tre argomenti in più delle loro controparti gtk_draw_; l'argomento area è un rettangolo di clipping, l'argomento widget è il widget in cui si deve disegnare e l'argomento detail è un "hint" utilizzato dai motori per i theme (temi). Ecco una chiamata a gtk_paint_shadow() dal codice sorgente di GtkEntry:

  gtk_paint_shadow (widget->style, widget->window,
                    GTK_STATE_NORMAL, GTK_SHADOW_IN,
                    NULL, widget, "entry",
                    x, y, width, height);

L'argomento area è NULL, specificando che non deve essere attuato nessun clipping.

Poiché nella GtkStyleClass ci sono moltissime funzioni, e ci sono numerosi esempi nel codice sorgente di GTK+, in questo libro non le descriveremo in dettaglio. Quando scrivete un vostro widget, cercate un widget simile nei sorgenti di GTK+ e utilizzate le stesse funzioni gtk_paint_.