This chapter discusses how to to use colors, palettes, and themes.


The Color class internally keeps track of a 32-bit RGBA (red, green, blue, and alpha) color by managing the individual color components. However, this class also supports at least the HSV and HSL colorspaces, and conversion between the different colorspaces. The Pattern class helps with managing a pattern consisting of color steps at specific offsets. Also, the experimental::ColorMap class deals with color steps and allows interpolation between the different color steps in any of the supported colorspaces.

Supporting different colorspaces provides a variety of different ways to perform interpolation between colors.

SharkD [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)]


The Palette contains a list of Predefined Colors.

The Palette class manages a set of colors. However, colors are not stored as a one dimensional list internally. Colors are identified by a Palette::ColorId and also a Palette::GroupId. The GroupId is associated with different states of a color in the palette, which corresponds with different states of a widget. For example, when a button is pressed, it changes from a normal to active state and uses the same Palette::ColorId to identify its background color, but uses a different Palette::GroupId.

The default palette for every widget comes from the theme. However, you can override any individual color for a specific widget instance by calling Widget::set_color().

Button button(window, "Press Me");

For a list of configurable palette colors, see Palette::ColorId.

If you change the global theme, it will retroactively have an effect on any widget, as long as that widget does not have an override for a Palette::ColorId and Palette::GroupId set.

The Palette class also defines a set of default colors to reference and use. With a few minor exceptions, these are the same colors defined by the CSS standard.


The theme contains the default palette and font and also can be used as a place to override Widget::draw() methods.

By default, themes are inherited in the widget hierarchy. If the top level window does not have a custom theme or a widget does not have a parent, it will use global_theme() by default. So, when you add a button widget to a window, that button will use the theme from the window and on up the widget hierarchy as needed. This means if you change the font of the window theme, the button and all of its children will inherit that change. Each Widget can hold its own instance of a theme, set with Widget::set_theme().

See also
Creating New Widgets for more information on how to create custom widgets.

EGT does not use native style widgets by default. It defines the look and feel of its own widgets, which is customizable. The look and feel of widgets can be extended or modified in several ways.

  1. The first method is to register a new draw() function for a specific widget type. This will make the new draw function apply to any widget of the same type.
  2. The second method is to derive from an existing widget and create a new widget type with a new default draw function.

Theme Inheritance

Theme is a class that holds a palette, font, and other functions and properties used by widgets. By default, there is a global_theme() that is used by all widgets. This can be changed by calling the set_global_theme() function.

Each widget references a theme through its Widget::theme() call. However, themes are inherited by default from a widget's parent. If no parent widget has a theme, the global_theme() is used by default.

To break the inheritance, call Widget::set_theme(). This will cause the widget to maintain its own theme and not inherit from its parent or the global theme. So, if you change the theme for a window, all of its child widgets will inherit that theme by default unless you call Widget::set_theme() on one of the children.

Inheritance of the theme provides a natural and flexible way to manage the look of widgets with less code.

Widget Type Default Draw Functions

Each widget type has a default_draw() function that implements the EGT default drawing method for the widget type. This function provides an example of how you would implement your own draw function to customize the look of a widget.

Widget Type Draw Functions

It is possible to change the Widget::draw() function for a widget type globally based only on the widget's C++ type. For example, you can change the draw() function for all button widgets by setting one draw method.

Drawer<Button>::set_draw([](Button & widget, Painter & painter, const Rect & rect)

Widget Instance Draw Functions

It is currently not possible to change the draw() function for a specific instance of a widget. To accomplish this task, you must inherit from the widget type you wish to change and overload the draw() function. Then, use the new widget type.

virtual void draw(Painter &painter, const Rect &rect) override
Draw the widget.
ToggleBox(const Rect &rect={}) noexcept
static void set_draw(typename Drawable< T >::draw_t d)
Set the default Drawable for all buttons.
Definition: theme.h:77
bool checked() const
Return the boolean checked state of the a widget.
Definition: widget.h:939
void ignoreparam(T &&)
Utility function to safely ignore a parameter to a function.
Definition: utils.h:37
Button text color.
constexpr static Color green
Predefined color.
Definition: palette.h:107
Palette::pattern_type color(Palette::ColorId id) const
Get a Widget color.
RectType< default_dim_type, detail::compatible::normal > Rect
Helper type for a default rect.
Definition: geometry.h:910
virtual const Rect & box() const
Bounding box for the Widget.
virtual ~ToggleBox()=default