Skip to content

Styling

Every widget has a Style that controls its appearance. Styles use C++23 designated initializers - you only set the fields you care about, everything else stays at its default.

widget->setStyle(Style{
.fg = {255, 255, 255}, // foreground (text) color, RGB
.bg = {30, 30, 46}, // background color, RGB
.text = TextDecoration{
.bold = true,
.italic = false,
.underline = false,
.strikethrough = false,
},
.border = Border{
.style = BorderStyle::Rounded,
.color = {100, 100, 255},
},
.padding = PaddingSpec{ .top = 1, .left = 2 },
.innerAlignX = Align::Center,
.innerAlignY = Align::Center,
});

Every field is optional. A plain Style{} means transparent background, white text, no border, no decoration.

Colors are RGB - three values from 0 to 255.

Style{ .fg = {255, 100, 0} } // orange text
Style{ .bg = {20, 20, 20} } // dark background
Style{ .fg = {0, 0, 0}, .bg = {255, 255, 255} } // black on white
Style{ .text = TextDecoration{ .bold = true } }
Style{ .text = TextDecoration{ .italic = true, .underline = true } }
Style{ .text = TextDecoration{ .strikethrough = true } }

All four flags default to false. Combine as many as you like.

Border takes a BorderStyle and an optional color and title/footer labels.

Style{ .border = Border{ .style = BorderStyle::Single } } // ─┐
Style{ .border = Border{ .style = BorderStyle::Double } } // ═╗
Style{ .border = Border{ .style = BorderStyle::Rounded } } // ─╮
Style{ .border = Border{ .style = BorderStyle::Thick } } // ━┓
Style{ .border = Border{ .style = BorderStyle::Dashed } } // ╌┐

You can also set a border color and title:

Style{
.border = Border{
.style = BorderStyle::Rounded,
.color = {100, 200, 255},
.title = { BorderLabel{ "My Widget" } },
}
}

innerAlignX and innerAlignY control how content is positioned inside the widget’s own bounds.

Style{ .innerAlignX = Align::Center, .innerAlignY = Align::Center }

Available values: Align::Start, Align::Center, Align::End, Align::Stretch.

Padding adds space between the widget’s border and its content.

Style{
.padding = PaddingSpec{ .top = 1, .bottom = 1, .left = 2, .right = 2 }
}

Every widget can have a separate style for when it has keyboard focus. The framework switches between them automatically - you never check focus state manually.

button->setStyle( Style{ .bg = {60, 60, 60} });
button->setFocusedStyle(Style{ .bg = {0, 120, 255} });

A common pattern is to keep the focused style identical to the normal one except for background or border color, so the user can clearly see which widget is active.


→ Next: Events - handling keyboard input and shortcuts.