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.