1. The engine
The pixmap (or pixbuf engine) engine allows relatively low level theming of the different widgets. Unlike engines like Clearlooks , Redmond, etc. pretty much every aspect of the interface can be modified from the theme. At the same time the burden is pretty high as creating a consistent theme can be a lot of work.
There are some limitations as some hacks are not possible, and information is not always accessible to the theme. An example of this are right to left languages, which result in swapped spinbuttons. Another limitation is that all widgets have a fixed color as they are drawn using pixmaps.
1.1. Overview over the theming
More complex GTKRCs may be needed to be able to create complete themes. Reading ../../GtkThemes is advised, as a it is neccessary to understand how styles, merging and matching works. (Some example to merging would be good on this page.)
1.2. GTK+ drawing primitives and the pixmap engine
The pixmap engine usually just exposes the GTK+ drawing primitives directly. There are only a couple of exceptions to this. GTK+ abstracts all drawing into a number of drawing functions. There are some common arguments like state or detail, and others that only exist for some functions. Some functions also need additional information like the orientation of the widgets.
The following functions exist in the pixmap engine:
Function |
arguments |
Used for |
HLINE |
state, orientation |
Separator drawing mostly |
VLINE |
state, orientation |
Separator drawing mostly |
SHADOW |
shadow, state |
Shadows around widgets. For example frames (without a title) or entries |
BOX |
shadow, state |
One of the most important functions used for buttons and in a lot of other places |
SHADOW_GAP |
shadow, state, gap_side, orientation ( the value is random, do not set!) |
Similar to shadow, but used whenever a gap is needed. ie. frames with labels |
BOX_GAP |
shadow, state, gap_side, orientation ( the value is random, do not set!) |
Similar to box, but used whenever a gap is needed. ie. notebooks |
STEPPER |
shadow, state, arrow_direction |
The stepper buttons of scrollbars (emulated) |
ARROW |
shadow, state, arrow_direction |
Arrows, for example on the combobox |
FLAT_BOX |
shadow, state |
Used to fill in backgrounds, and for example for the radiobutton prelight |
CHECK |
shadow, state |
Check button indicator |
OPTION |
shadow, state |
Radio button indicator |
TAB |
shadow, state |
The "tab" (arrows) of the OptionMenu |
EXTENSION |
shadow, state, gap_side |
The extension of the notebook |
FOCUS |
(nothing other than detail) |
The focus |
SLIDER |
shadow, state, orientation |
The slider of ../../GtkThemes/GtkScale and ../../GtkThemes/GtkScrollbar |
HANDLE |
shadow, state, orientation |
The handle of paned, handle box or also on the gnome-panel |
EXPANDER |
state, expander_style |
Drawing expanders. eg. treeview and a expander widgets |
RESIZE_GRIP |
state, window_edge |
The resize grip of windows |
DIAMOND |
shadow, state |
Some relict from GTK+ 1.x times I think |
The different arguments and their possible values:
Argument |
Values |
Description |
detail |
any string |
The detail string set by GTK+ or the application |
state |
NORMAL, PRELIGHT, ACTIVE, INSENSITIVE, SELECTED |
The state of the widget. This may be different than the "real" state in some cases (eg. notebook tabs) |
shadow |
IN, OUT, ETCHED_IN, ETCHED_OUT, NONE |
The shadow. Used for frames, but also for example for the check and radio button indicator state. |
orientation |
HORIZONTAL, VERTICAL |
Orientation of sliders and other widgets. |
gap_side |
TOP, BOTTOM, LEFT, RIGHT |
The side of the gap. This is the side that the gap is on, so for the extension it is where the notebook is, and for the notebook where the tab is. |
expander_style |
COLLAPSED, SEMI_COLLAPSED, SEMI_EXPANDED, EXPANDED |
The status of the expander. The semi states are in-between states for a basic animation. |
window_edge |
NORTH_WEST, NORTH, NORTH_EAST, WEST, EAST, SOUTH_WEST, SOUTH, SOUTH_EAST |
The window corner that the resize grip is in. |
This is a placeholder until I know more about this.
style "NAME-scrollbar" { engine "pixmap" { image { function = SLIDER orientation = HORIZONTAL recolorable = TRUE # what does that mean? it's not implemented! file = "nf_slider-h.png" border = { 10, 10, 0, 0 } # = {Left, Right, Top, Bottom} stretch = TRUE # this stretches the image overlay_file = "thumb-h-scrollbar.png" overlay_stretch = FALSE } ... } } class "GtkScrollbar" style "NAME-Scrollbar"
This applies the PixmapEngine to the style above.
This is a lot of stuff that isn't obvious from looking at the resource file API so here's what I know. The 'engine "pixmap"' bit says to use the theme engine named "pixmap" to draw widgets of this style. An engine is a kind of module that Gnome can load to do theme drawing. The only one I've seen so far is pixmap and it is a tad slow so don't go overboard here.
- The 'function' line tells the engine what part of the engine you're specifying parameters for. In our example we're describing a horizontal scrollbar slider.
- The 'orientation' specifies direction horizontal/vertical
The 'recolorable' line means uh... umm... nothing, it is ignored -- -- BenjaminBerg 2005-06-05 12:21:55
- The 'file' line specifies an image to use.
- The 'border' line defines the border widths in this manner {Left, Right, Top, Bottom} (described in detail below).
- The 'stretch' line says to stretch the image to fit the widget.
- The 'overlay_file' line defines another image to lay on top of the other one.
- The 'overlay_stretch' line says whether to stretch the overlay image.
(to be continued...)
Complete GtkVScrollbar theming sample:
style "my-vscrollbar" { engine "pixmap" { image { function = SLIDER orientation = VERTICAL file = "scrollbar_slider.png" border = { 0, 0, 10, 10 } # = {Left, Right, Top, Bottom} stretch = TRUE # this stretches the image } image { function = BOX orientation = VERTICAL file = "scrollbar_background.png" border = { 0, 0, 32, 32} # = {Left, Right, Top, Bottom} stretch = TRUE # this stretches the image } image { function = BOX detail = "vscrollbar" } image { function = ARROW # override all states # consider adding per state image block # state = NORMAL # state = INSENSITIVE overlay_file = "scrollbar_arrow_up.png" overlay_stretch = FALSE arrow_direction = UP } image { function = ARROW # override all states # consider adding per state image block # state = NORMAL # state = INSENSITIVE overlay_file = "scrollbar_arrow_down.png" overlay_stretch = FALSE arrow_direction = DOWN } } } class "GtkScrollbar" style "my-vscrollbar"
How to theme GtkWindow with a background image:
style "my-background" { engine "pixmap" { image { function = FLAT_BOX file = "background.png" border = {10, 10, 10, 10} detail = "base" } } } class "GtkWindow" style "my-background"
Or if you have an enclosing GtkFrame, and want only theming the outer of the window:
(02:45:04 PM) benzea: which one could consider a good thing, because scaling is relatively slow
style "my-background" { engine "pixmap" { image { function = SHADOW file = "background.png" border = {10, 10, 10, 10} } } } class "GtkFrame" style "my-background"
How to theme a GtkPaned with images:
style "my-paned" { GtkPaned ::handle_size = 15 engine "pixmap" { image { function = HANDLE overlay_file = "handle.png" overlay_border = {0, 0, 0, 0} overlay_stretch = FALSE orientation = HORIZONTAL file = "handle_background.png" border = {0, 0, 0, 0} stretch = TRUE } } } class "GtkPaned" style "my-paned"
How to theme a GtkHSeparator with an image:
style "my-hseparator" { engine "pixmap" { image { function = BOX file = "hseparator.png" border = {0, 0, 0, 0} stretch = TRUE } } GtkHSeparator:: wide-separators = 1 GtkHSeparator:: separator-height = 10 } class "GtkHSeparator" style "my-hseparator"