| 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.