GTK+ / Gnome Application Development | |||
---|---|---|---|
<<< Previous | Home | Next >>> |
GtkStyle is not part of GDK, but it is an important abstraction layer between GTK+ and GDK that allows users to customize how widgets are rendered. Instead of drawing with GDK directly, widgets should prefer GDK resources from a GtkStyle, and special drawing functions provided in gtk/gtkstyle.h. Often there is no appropriate function, but when there is it should be used.
A GtkStyle stores GDK resources to be used when drawing widgets. Styles allow widgets to share these resources, reducing overhead; they also permit users to customize GTK+'s appearance. Here is the GtkStyle struct:
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; }; |
The private fields should be ignored. The public fields contain GDK resources for widget rendering. The first group of fields contains arrays of colors; these arrays are indexed by the widget state enumeration (GTK_STATE_ACTIVE, etc.). A widget might use widget->style->fg[GTK_STATE_NORMAL] to render text, for example. Each widget has an associated style, stored in the style field of GtkWidget.
Widgets should use the font stored in their associated GtkStyle; they should use the style's graphics contexts when drawing in the style's colors.
GtkStyle also contains a virtual table, GtkStyleClass, which can be implemented by a dynamically-loaded theme engine. The virtual table is quite large, so it isn't reproduced here. Have a look at gtk/gtkstyle.h.
gtk/gtkstyle.h contains drawing functions that use a style's virtual table to draw various GUI elements. There are two variants of each drawing function. One variant, prefixed with gtk_draw_, renders to any drawable; the other variant, prefixed with gtk_paint_, renders part of a widget. For example, gtk_draw_shadow() looks like this:
void gtk_draw_shadow (GtkStyle *style, GdkWindow *window, GtkStateType state_type, GtkShadowType shadow_type, gint x, gint y, gint width, gint height); |
While gtk_paint_shadow() adds area, widget, and detail arguments:
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); |
Each of these corresponds to the draw_shadow member in GtkStyleClass.
All gtk_paint_ functions add the same three arguments to their gtk_draw_ counterparts; the area argument is a clipping rectangle, the widget argument is the widget being drawn to, and the detail argument is a hint used by theme engines. Here's a call to gtk_paint_shadow() from the GtkEntry source code, for example:
gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, "entry", x, y, width, height); |
Here the area argument is NULL, specifying that no clipping should be used.
Because there are a couple dozen functions in GtkStyleClass, and there are numerous examples in the GTK+ source code, this book won't describe them in detail. When writing your own widgets, simply locate a GTK+ widget that draws a similar graphical element, and use the same gtk_paint_ function it uses.