Themes

Theme plugins

Just before the first window is shown, fltk calls the "theme" function, which is used to initialize the styles to the user's and programmer's preferences. This is a function pointer and it is set and read with fltk::theme(x) and fltk::theme(). This function should set all the NamedStyle structures to the correct values for the appearance selected by the user and operating system. The return value is ignored but you should return true for future compatability.

This pointer is declared as a "C" function to make it easier to load the correct function by name from a plugin. Theme functions are actually of the form extern "C" bool fltk_theme(). A typedef of fltk::Theme is provided.

By default this points at a C function called "fltk_theme" that in turn calls the function fltk::system_theme(). You can "override" the theme function and customize fltk's appearance in several ways:

  1. If fltk is dynamically linked (or statically linked on some Unix systems, including Linux if -shared was given to the linker) a "theme plugin" can be loaded. You can use the function fltk::load_plugin() to read such a plugin in a portable way. The default fltk::args() function does this.
  2. If fltk is statically linked (or in all cases on some Unix systems such as Irix), your program can replace fltk_theme with it's own definition at compile time. The one you supply will replace the one in the fltk library.
  3. You can call fltk::theme(function) to set the function directly.

Controlling themes

static fltk::Theme fltk::theme();
static void fltk::theme(fltk::Theme f);

Get or set the function that will be called when the theme is loaded.

static const char* fltk::scheme();
static void fltk::scheme(const char* f);

(NYI) This string is maintained so that a theme plugin can look at it and use it for any purpose it wants. fltk::args() will set this if the user gives the "-scheme" switch. The default value is null.

static void fltk::load_theme();

Force the theme to be loaded. Calling this multiple times does nothing (call reload_theme() if you want to make a change to theme(). take effect). Normally fltk calls this just before the first window is shown(). You can call this earlier to make sure all the styles are correct, for instance if you want to measure the size of labels, which depends on the font selected.

static void fltk::reload_theme();

If load_theme() has been called, this will restore all the Style information back to the compiled-in default values, and then call the theme() function again. This is useful if theme() changes, or if external information that your theme uses changes.

If load_theme() has never been called this returns and does nothing. This allows your code to change the themes several times without wasting time before the first window is shown.

On Windows this is automatically called in response to a WM_SYSCOLORCHANGE. On X the theme itself needs to set up some event handler to call this, see the KDE theme source code for an example.

Implementing a Theme

To implement "themes" the theme code needs to write a number of static locations, primarily the default style of several classes. You ususally only need to change a few styles to implement a theme. All widgets inherit from the default style anything that they don't set themselves.

The following functions are useful when writing a theme.

bool fltk::system_theme();

System-specific "theme". This is called by default by fltk, and if you write a theme function you probably want to call it as well. On Window it uses GetSysColor(), and it does similar things on other operating systems to get the appearance to match the user's settings for other software as much as possible.

void* fltk::load_plugin(const char* name, const char* symbol);

Loads a shared object (DLL) in a portable way. name is a complete filename and symbol is the name of some object in the plugin.

If the plugin file successfully loads (or has already been loaded) then a pointer to the given symbol is returned. If the plugin is not found or the symbol is not in it then an appropriate error message is printed on stderr and null is returned.

You can pass NULL as the symbol to indicate that you just want to load the plugin. In this case a non-zero value is returned if the plugin successfully loads, but you cannot use this value for anything other than to test for success.

fltk::Widget::default_style

Provides all the defaults described above. This is the only style that does not have a parent. Highlighting is disabled by default, to turn it on you should set highlight color.

fltk::Style::find("input")

This style is used by fltk::Input, but a few other widgets directly refer to it to draw imbedded text editing fields.

fltk::Style::find("output")

This style is used by fltk::Output, but a few other widgets directly refer to it to draw imbedded display fields. Setting the color to gray will simulate NeXTStep or other user interfaces where interactivity is indicated by color.

fltk::Style::find("CheckButton")

Styles usually need to mess with the button_color and glyph function here to get check marks correct.

fltk::Style::find("menu")

This style is used for the pop-up menu windows. button_box is drawn around each item, and selection_color is used to color the current one.

fltk::Style::find("item")

Menu items. If you use checkmarks in menus you will have to make similar fixes to this as to CheckButton. Notice that the box drawn around each item is chosen by "menu", not by this.

fltk::Style::find("Scrollbar")

Styles usually need to mess with the box, button_box, button_color, and glyph function to get these to appear correctly.

fltk::Tooltip::default_style

The box and color of this controls the appearance of the tooltips. This is always linked in, so you don't need find(). Tooltips also have some other static fields to set the timeout and position, see the fltk::Tooltip documentation.