Themes
The erbsland::cterm::theme namespace provides the theme
system used by the UI framework. A theme keeps visual decisions out of
individual controls, so you can change the look of an application
without teaching every scroll bar, panel, or status line about the same
colors, block shapes, margins, and padding again.
The public include for this subsystem is:
#include <erbsland/cterm/theme/all.hpp>
The UI umbrella include also makes the theme types available for normal UI applications:
#include <erbsland/cterm/ui/all.hpp>
Core Model
A theme is an immutable hierarchy of property sheets:
ThemeBuilderis the mutable authoring API. It stores onePropertiesobject perSelector.Themefreezes those authored definitions and resolves fallback chains on demand.PropertySheetis the effective result for one selector. It contains the resolved color, color sequence, attributes, block table, margins, and padding.
This model lets you change text styling, terminal-cell graphics, and layout spacing through the same selector tree. You can override only the value you care about and inherit the remaining properties from the nearest base sheet.
The default application theme is
Theme::dark(). You can
replace it on the application, or override it on a page:
using namespace erbsland::cterm;
auto app = ui::Application{};
app.setTheme(theme::Theme::light());
auto page = ui::Page::create();
page->setTheme(theme::Theme::monochrome());
For small customizations, start with a builder copied from an existing theme and edit only the affected selectors:
auto builder = theme::ThemeBuilder::from(theme::Theme::dark());
builder.edit(theme::Selector{theme::Element::StatusLine, theme::Part::Background})
.setColor(Color{fg::BrightWhite, bg::Blue});
app.setTheme(builder.build());
Selectors
Theme lookup uses compact identifiers instead of strings in the paint loop. A selector has four parts:
Elementdescribes the themed control or surface.Partdescribes a visual role inside the element.Statesdescribes required UI states such as focus or disabled.Tagsdescribes optional, application-defined variants.
The built-in elements are static constants on
Element:
theme::Element::Base
theme::Element::Page
theme::Element::Layout
theme::Element::Surface
theme::Element::Panel
theme::Element::TextBox
theme::Element::StatusLine
theme::Element::HeaderLine
theme::Element::FooterLine
theme::Element::ActionHelp
theme::Element::HorizontalScrollBar
theme::Element::VerticalScrollBar
theme::Element::ScrollCorner
theme::Element::Sections
theme::Element::Buttons
theme::Element::Button
theme::Element::Frame
theme::Element::Choice
theme::Element::HelpViewer
The built-in parts are static constants on
Part:
theme::Part::Background
theme::Part::Text
theme::Part::Border
theme::Part::Track
theme::Part::Thumb
theme::Part::Decrease
theme::Part::Increase
theme::Part::Indicator
theme::Part::Key
theme::Part::KeyBracket
theme::Part::Title
theme::Part::TitleBracket
theme::Part::Spacing
The built-in states are static constants on
State:
theme::State::Focused
theme::State::FocusWithin
theme::State::Selected
theme::State::Disabled
theme::State::Checked
You can create custom elements and parts for your own controls:
inline constexpr auto cSearchBox = theme::Element::custom(10'000);
inline constexpr auto cCursor = theme::Part::custom(10'001);
Keep these identifiers stable in your application or library. They are small numeric values by design, so lookup stays direct and cheap. Custom element and part identifiers are offset by the library, so they do not collide with predefined identifiers.
Custom elements can also inherit from a built-in element:
theme::Theme::registerElement(cSearchBox, theme::Element::Surface);
After that, unresolved search-box selectors fall back through
Surface before they reach the base sheet.
Rule Matching
Theme resolution follows a fallback chain instead of returning just the single most specific rule. Starting at the requested selector, the theme looks for an authored sheet and then resolves its base sheet:
tags fall back to the best authored tag subset, then to no tags
states fall back to the best authored state subset, then to no states
parts fall back through the element base hierarchy for the same part, then to the same element without a part
elements fall back through their registered base element, then to
Element::Base
When several tag or state subsets could match, the larger subset wins.
If two candidates are equally specific, the later edited selector wins.
The resolved PropertySheet
inherits every unspecified property from its base sheet.
Building Themes
You normally start with one of the predefined builders and add only the rules that make your application different. The following example keeps the default dark structure, changes the regular status line, and gives a tagged status line a stronger background:
using namespace erbsland::cterm;
auto builder = theme::ThemeBuilder::dark();
const auto warning = builder.registerTag();
builder.edit(theme::Selector{theme::Element::StatusLine, theme::Part::Background})
.setColor(Color{fg::BrightWhite, bg::Blue});
builder.edit(theme::Selector{theme::Element::StatusLine, theme::Part::Background}.requireTag(warning))
.setStyle(CharStyle{Color{fg::BrightYellow, bg::Red}, CharAttributes::Bold});
app.setTheme(builder.build());
The same editor handles text styling and structural blocks. Action-help
formatting, for example, uses colors for key text, bracket text, and
action names. The ActionHelp/KeyBracket sheet also supplies the
bracket glyphs: BlockRole::West is the opening bracket,
BlockRole::Center separates multiple keys, and BlockRole::East
is the closing bracket.
auto builder = theme::ThemeBuilder::dark();
builder.edit(theme::Selector{theme::Element::ActionHelp, theme::Part::KeyBracket})
.setColor(Color{fg::BrightBlack, bg::Inherited})
.setBlocks(U" </> ");
app.setTheme(builder.build());
Block tables contain sixteen code points named by
BlockRole. Use
setBlock() for one role, or setBlocks() with a 9-character or
16-character UTF-32 string.
Margins and padding have different owners. Margins are outside a themed
part; the parent surface keeps that space and the part does not paint it.
Padding is inside the themed part; text-focused UI elements paint padding
with the part’s BlockRole::Background block and style before drawing
the text. Strict one-line text ignores top and bottom margins and padding
but still uses left and right values. When adjacent one-line text parts
meet, their horizontal margins collapse to the larger value instead of
being added together.
Scroll bars use the track margins to decide where the thumb may appear:
auto builder = theme::ThemeBuilder::dark();
builder.edit(theme::Selector{theme::Element::VerticalScrollBar, theme::Part::Track})
.setBlocks(U"░░░░░░░░░░░░↑░↓↑")
.setMargins(Margins{0, 1});
builder.edit(theme::Selector{theme::Element::VerticalScrollBar, theme::Part::Thumb})
.setBlocks(U" ▔ ▁ ");
app.setTheme(builder.build());
Using Themes In Custom Surfaces
Each surface has theme attributes for its element and tags. Built-in surfaces set their element automatically. Custom surfaces should set the element in their constructor:
class SearchBox final : public ui::Surface {
public:
explicit SearchBox(ProtectedTag) : Surface{cSearchBox} {}
[[nodiscard]] static auto create() -> std::shared_ptr<SearchBox> {
return std::make_shared<SearchBox>(ProtectedTag{});
}
protected:
void onPaint(WritableBuffer &buffer, const ui::PaintContext &context) noexcept override {
auto backgroundTheme = context.theme().forPart(theme::Part::Background);
theme::ThemePainter{buffer, backgroundTheme}.fill(context.surfaceRect());
const auto textRect = backgroundTheme.contentRect(context.surfaceRect());
const auto textColor = context.theme().forPart(theme::Part::Text).color();
buffer.drawText(_text, textRect, Alignment::CenterLeft, textColor);
}
private:
String _text;
};
For layout decisions that depend on themed margins, override
onLayout(Size, const LayoutContext &) and use
LayoutContext there. The
same theme scope is then used during layout and paint:
void SearchBox::onLayout(Size newParentSize, const ui::LayoutContext &context) noexcept {
const auto contentRect = context.theme().forPart(theme::Part::Background).contentRect(
Rectangle{Position{}, newParentSize});
_contentWidth = contentRect.width();
}
Runtime Updates
When you call
Application::setTheme(),
Page::setTheme(), or
SurfaceFlags::setThemeOutdated(), the affected
surface tree marks layout and paint as outdated. This is intentional: a
color-only change may only alter cells, while a block or margin change
may also alter content rectangles and therefore layout size.
Changing surface->themeAttributes().setElement(...) or
surface->themeAttributes().setTags(...) is passive. This keeps
constructor-time setup cheap and predictable. If you change an element or
tag dynamically, call surface->flags().setThemeOutdated() yourself.
State-like changes such as setEnabled(false), setSelected(true),
and setChecked(true) belong to SurfaceFlags and invalidate the
theme scope automatically.
Paint code should use the resolved context helpers instead of querying a global object:
const auto backgroundTheme = context.theme().forPart(theme::Part::Background);
buffer.fill(context.surfaceRect(), backgroundTheme.block());
The ThemePainter is a
thin convenience wrapper around WritableBuffer and
ThemeAccessor. It is
not a separate style engine; it simply fills or frames rectangles with
blocks resolved through the active theme scope.
Predefined Themes
The library provides predefined builders:
It also provides ready-to-use immutable themes:
Reference
-
class Element
A fast theme element identifier.
Public Types
-
using Id = Identifier<IdentifierType::Element>
The underlying element identifier.
Public Functions
-
constexpr Element() noexcept = default
Create an empty element identifier.
-
inline constexpr Element(const Id id) noexcept
Create an element from an element identifier.
- Parameters:
id – The element identifier.
-
inline constexpr bool operator==(const Element &other) const noexcept
Compare two element identifiers.
-
inline constexpr bool operator!=(const Element &other) const noexcept
Compare two element identifiers.
-
inline constexpr uint16_t value() const noexcept
Get the numeric identifier.
-
inline constexpr bool isValid() const noexcept
Test if this identifier is non-empty.
-
inline constexpr std::size_t hash() const noexcept
Get a stable hash for this element identifier.
Public Static Functions
Public Static Attributes
A footer line element.
-
using Id = Identifier<IdentifierType::Element>
-
enum class erbsland::cterm::theme::IdentifierType : uint8_t
The logical kind of a theme identifier.
Values:
-
template<IdentifierType tIdentifierType>
class Identifier A strongly typed numeric theme identifier.
- Template Parameters:
tIdentifierType – The logical identifier kind.
Public Functions
-
constexpr Identifier() noexcept = default
Create an invalid identifier.
-
inline explicit constexpr Identifier(const uint16_t value) noexcept
Create an identifier from a raw value.
- Parameters:
value – The raw identifier value.
-
bool operator==(const Identifier &other) const noexcept = default
Compare two identifiers.
-
bool operator!=(const Identifier &other) const noexcept = default
Compare two identifiers.
-
inline constexpr uint16_t value() const noexcept
Get the raw identifier value.
- Returns:
The raw identifier value.
-
inline constexpr bool isValid() const noexcept
Test if this identifier is non-empty.
- Returns:
trueif this identifier has a positive value.
-
inline constexpr std::size_t hash() const noexcept
Get a stable hash for this identifier.
- Returns:
The hash value.
-
class Part
A fast theme part identifier.
Parts identify the visual role inside an element, for example a scrollbar track or thumb.
Public Types
-
using Id = Identifier<IdentifierType::Part>
The underlying part identifier.
Public Functions
-
constexpr Part() noexcept = default
Create an empty part identifier.
-
inline constexpr Part(const Id id) noexcept
Create a part from a part identifier.
- Parameters:
id – The non-zero part identifier.
-
inline constexpr uint16_t value() const noexcept
Get the numeric identifier.
- Returns:
The numeric identifier.
-
inline constexpr bool isValid() const noexcept
Test if this identifier is non-empty.
- Returns:
trueif this part has a non-zero identifier.
-
inline constexpr std::size_t hash() const noexcept
Get a stable hash for this part identifier.
- Returns:
The hash value.
Public Static Functions
-
static inline constexpr Part custom(const int32_t id)
Create a custom part identifier.
- Parameters:
id – A stable application-defined positive identifier.
- Throws:
std::invalid_argument – If
idis not positive.std::out_of_range – If
idexceeds the supported custom identifier range.
- Returns:
The custom part identifier.
Public Static Attributes
-
using Id = Identifier<IdentifierType::Part>
-
class State
A single UI state flag used in theme selectors.
Public Functions
-
constexpr State() noexcept = default
Create an empty state flag.
-
inline explicit constexpr State(const uint8_t mask) noexcept
Create a state from a bit mask.
- Parameters:
mask – The state bit mask.
-
inline constexpr uint8_t mask() const noexcept
Get the bit mask for this state.
- Returns:
The bit mask.
-
inline constexpr bool isValid() const noexcept
Test if this state has a non-zero bit mask.
- Returns:
trueif this state is usable in a selector.
Public Static Attributes
-
constexpr State() noexcept = default
-
class States
A compact set of UI state flags used in theme selector matching.
Public Functions
-
constexpr States() noexcept = default
Create an empty state set.
-
inline constexpr States(const State state) noexcept
Create a state set containing one state.
- Parameters:
state – The initial state.
-
inline explicit constexpr States(const uint8_t bits) noexcept
Create a state set from raw bits.
- Parameters:
bits – The raw state bits.
-
States(std::initializer_list<State> states) noexcept
Create a state set from an initializer list.
- Parameters:
states – The states to add.
-
inline void remove(const State state) noexcept
Remove one state.
- Parameters:
state – The state to remove.
-
inline constexpr bool contains(const State state) const noexcept
Test if one state is present.
- Parameters:
state – The state to test.
-
inline constexpr bool containsAll(const States states) const noexcept
Test if all states from another set are present.
- Parameters:
states – The required states.
-
inline constexpr bool empty() const noexcept
Test if the set is empty.
-
inline int size() const noexcept
Get the number of states in the set.
-
inline constexpr uint8_t bits() const noexcept
Get the raw state bits.
-
inline constexpr std::size_t hash() const noexcept
Get a stable hash for this state set.
-
constexpr States() noexcept = default
-
class Tag
A theme tag bit assigned by a theme builder.
Public Functions
-
constexpr Tag() noexcept = default
Create an empty tag.
-
inline explicit constexpr Tag(const uint8_t bit) noexcept
Create a tag from a zero-based bit index.
- Parameters:
bit – The zero-based tag bit index.
-
inline constexpr uint8_t value() const noexcept
Get the one-based numeric tag value, or zero for an empty tag.
-
inline constexpr uint8_t bit() const noexcept
Get the zero-based tag bit index.
-
inline constexpr uint64_t mask() const noexcept
Get the mask for this tag.
-
inline constexpr bool isValid() const noexcept
Test if this tag is non-empty.
- Returns:
trueif this tag references a valid bit.
-
inline constexpr std::size_t hash() const noexcept
Get a stable hash for this tag.
- Returns:
The hash value.
-
constexpr Tag() noexcept = default
-
class Tags
A compact set of theme tags.
Public Functions
-
constexpr Tags() noexcept = default
Create an empty tag set.
-
inline constexpr Tags(const Tag tag) noexcept
Create a tag set containing one tag.
- Parameters:
tag – The initial tag.
-
inline explicit constexpr Tags(const uint64_t bits) noexcept
Create a tag set from raw bits.
- Parameters:
bits – The raw tag bits.
-
inline constexpr Tags(std::initializer_list<Tag> tags) noexcept
Create a tag set from an initializer list.
- Parameters:
tags – The tags to add.
-
inline constexpr void add(const Tags tags) noexcept
Add all tags from another tag set.
- Parameters:
tags – The tags to add.
-
inline constexpr void remove(const Tag tag) noexcept
Remove one tag.
- Parameters:
tag – The tag to remove.
-
inline constexpr bool contains(const Tag tag) const noexcept
Test if one tag is present.
- Parameters:
tag – The tag to test.
-
inline constexpr bool containsAll(const Tags tags) const noexcept
Test if all tags from another set are present.
- Parameters:
tags – The required tags.
-
inline constexpr bool empty() const noexcept
Test if the set is empty.
-
inline int size() const noexcept
Get the number of tags in the set.
-
inline constexpr uint64_t bits() const noexcept
Get the raw tag bits.
-
inline constexpr std::size_t hash() const noexcept
Get a stable hash for this tag set.
-
constexpr Tags() noexcept = default
-
class Selector
A selector for one theme property sheet.
Public Functions
-
constexpr Selector() noexcept = default
Create an empty selector.
-
inline explicit constexpr Selector(const Element element, const Part part = Part::None) noexcept
Create a selector for an element and optional part.
- Parameters:
element – The selected element.
part – The selected part.
-
inline constexpr Selector withElement(const Element element) const noexcept
Create a copy with a different element.
-
inline constexpr Selector withPart(const Part part) const noexcept
Create a copy with a different part.
-
inline Selector withState(const State state) const noexcept
Create a copy with additional state flags.
-
inline constexpr Selector withStates(const States states) const noexcept
Create a copy with a state set.
-
inline constexpr Selector withTag(const Tag tag) const noexcept
Create a copy with an additional tag.
-
bool matches(States state, Tags tags) const noexcept
Test if this selector matches the supplied state and tags.
-
int specificity() const noexcept
Get the selector specificity.
-
std::size_t hash() const noexcept
Get a stable hash for this selector.
-
constexpr Selector() noexcept = default
-
enum class erbsland::cterm::theme::BlockRole : uint8_t
Named roles for the sixteen themed block code points.
Values:
-
enumerator NorthWest
Top-left block.
-
enumerator North
Top edge block.
-
enumerator NorthEast
Top-right block.
-
enumerator West
Left edge block.
-
enumerator Center
Center block.
-
enumerator East
Right edge block.
-
enumerator SouthWest
Bottom-left block.
-
enumerator South
Bottom edge block.
-
enumerator SouthEast
Bottom-right block.
-
enumerator HorizontalWest
Left block for one-row rectangles.
-
enumerator HorizontalCenter
Center block for one-row rectangles.
-
enumerator HorizontalEast
Right block for one-row rectangles.
-
enumerator VerticalNorth
Top block for one-column rectangles.
-
enumerator VerticalCenter
Center block for one-column rectangles.
-
enumerator VerticalSouth
Bottom block for one-column rectangles.
-
enumerator Single
Single-cell block.
-
enumerator Main
Alias for the main block, if only one is relevant.
-
enumerator LeftPadding
Padding on the left side.
-
enumerator RightPadding
Padding on the right side.
-
enumerator LeftBracket
Left brackets.
-
enumerator MiddleBracket
Middle “brackets” (separator).
-
enumerator RightBracket
Right brackets.
-
enumerator LeftOuterPadding
Left outer padding (after left bracket).
-
enumerator RightOuterPadding
Right outer padding (before right bracket).
-
enumerator LeftInnerPadding
Left inner padding (after middle bracket).
-
enumerator RightInnerPadding
Right inner padding (before middle bracket).
-
enumerator NorthWest
-
class Properties
Authoring values for one theme property sheet.
Public Types
-
using Blocks = std::array<char32_t, cBlockCount>
The block code point table.
Public Functions
-
inline const std::optional<ColorSequence> &colorSequence() const noexcept
Access the optional color sequence.
-
inline void setColorSequence(ColorSequence colorSequence) noexcept
Replace the optional color sequence.
-
inline const std::optional<CharAttributes> &attributes() const noexcept
Access the optional attributes replacement.
-
inline void setAttributes(CharAttributes attributes) noexcept
Replace the optional attributes replacement.
-
inline const std::optional<Margins> &margins() const noexcept
Access the optional margins.
Margins are always zero or positive.
-
inline void setMargins(const Margins margins) noexcept
Replace the optional margins.
Margins are outside a themed part and stay owned by the parent surface.
-
using Blocks = std::array<char32_t, cBlockCount>
-
class PropertyEditor
Mutable editor for one property sheet while a theme is being built.
Public Functions
-
PropertyEditor() = default
Create an empty editor.
-
inline explicit PropertyEditor(Properties &properties) noexcept
Create an editor for a property sheet.
- Parameters:
properties – The edited properties. Must outlive this editor.
-
PropertyEditor &setColor(Color color) noexcept
Set the color replacement.
-
PropertyEditor &setColor(Foreground::Hue fg) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
-
PropertyEditor &setColor(Background::Hue bg) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
-
PropertyEditor &setColor(Foreground::Hue fg, Background::Hue bg) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
-
PropertyEditor &setColorSequence(ColorSequence colorSequence) noexcept
Set the color sequence.
-
PropertyEditor &setAttributes(CharAttributes attributes) noexcept
Set the “attributes” replacement.
-
PropertyEditor &setStyle(CharStyle style) noexcept
Set color and attributes in one call.
-
PropertyEditor &setBlock(BlockRole role, char32_t codePoint) noexcept
Set one block code point.
-
PropertyEditor &setInheritedBlock(BlockRole role) noexcept
Set one block to inherit from its parent.
-
PropertyEditor &setBlocks(std::u32string_view blocks)
Set a 9-block or 16-block table from UTF-32 code points.
-
PropertyEditor &setBlocks(char32_t codePoint)
Set all blocks to a given code point.
-
PropertyEditor &setInheritedBlocks() noexcept
Set all blocks to inherit from its parent.
-
PropertyEditor &setBracketBlocks(char32_t left, char32_t right, char32_t middle = U' ')
Set all bracket blocks to a given code point.
-
PropertyEditor &setMargins(Margins margins) noexcept
Set the margins.
Margins describe parent-owned space around a themed part. The part does not paint this area. Margins can never be negative. Negative margins are set to zero.
-
PropertyEditor &setPadding(Margins padding) noexcept
Set the padding.
Padding describes part-owned space inside the part. Text-focused UI elements paint this area with the part’s background block and style before drawing the text content. Padding can never be negative. Negative padding is set to zero.
-
PropertyEditor() = default
-
class PropertySheet
Effective values for one resolved theme selector.
Public Functions
-
PropertySheet() noexcept
Create the root sheet with all default values.
-
PropertySheet(const PropertySheet &base, const Properties &properties) noexcept
Create an effective sheet from a base sheet and authoring properties.
-
Color color(std::size_t animationCycle = 0) const noexcept
Resolve the color for an animation cycle.
-
inline const ColorSequence &colorSequence() const noexcept
Access the effective color sequence.
-
inline CharAttributes attributes() const noexcept
Access the effective attributes.
-
CharStyle style(std::size_t animationCycle = 0) const noexcept
Resolve the style for an animation cycle.
-
Char block(BlockRole role, std::size_t animationCycle = 0) const noexcept
Resolve a block character for a role.
-
Tile9Style tile9Style(std::size_t animationCycle = 0) const noexcept
Resolve a tile-9 style for an animation cycle.
-
PropertySheet() noexcept
-
using erbsland::cterm::theme::PropertySheetPtr = std::shared_ptr<PropertySheet>
-
using erbsland::cterm::theme::PropertySheetConstPtr = std::shared_ptr<const PropertySheet>
-
class ThemeBuilder
Builder for immutable themes.
Public Functions
-
ThemeBuilder() = default
Create an empty theme builder.
-
PropertyEditor edit(Selector selector)
Edit one property sheet.
- Parameters:
selector – The selector for the sheet.
-
ThemeConstPtr build() const
Build an immutable theme.
Public Static Functions
-
static ThemeBuilder from(const ThemeConstPtr &theme)
Create a builder from an existing theme.
-
static ThemeBuilder dark()
Create the dark default theme builder.
-
static ThemeBuilder light()
Create the light default theme builder.
-
static ThemeBuilder monochrome()
Create the monochrome default theme builder.
-
static ThemeBuilder zero()
Create the zero theme builder.
-
ThemeBuilder() = default
-
class Theme
Immutable theme built from hierarchical property sheets.
Public Types
-
using OptionalDefinition = std::optional<std::reference_wrapper<const Definition>>
An optional definition.
-
using Definitions = std::unordered_map<Selector, Definition>
The authored property sheet definitions.
Public Functions
-
explicit Theme(Definitions definitions, uint8_t registeredTagCount = 0)
Create a theme from authored property sheet definitions.
- Parameters:
definitions – The authored property sheet definitions.
registeredTagCount – The number of registered tags.
-
PropertySheetConstPtr propertySheet(Selector selector) const
Resolve an effective property sheet for a selector.
- Parameters:
selector – The selector to resolve.
-
inline uint8_t registeredTagCount() const noexcept
Get the number of registered tags.
-
inline const Definitions &definitions() const noexcept
Access the authored definitions.
Public Static Functions
-
static void registerElement(Element element, Element base)
Register a user-defined element base relationship.
- Parameters:
element – The user-defined element.
base – The direct base element.
-
static const ThemeConstPtr &dark() noexcept
Access the predefined dark theme.
-
static const ThemeConstPtr &light() noexcept
Access the predefined light theme.
-
static const ThemeConstPtr &monochrome() noexcept
Access the predefined monochrome theme.
-
static const ThemeConstPtr &zero() noexcept
Access the predefined zero theme.
The zero theme does not define any elements or styles. Use this theme for your unit tests or when you want to start from a clean slate.
-
struct Definition
One authored property sheet definition.
Public Members
-
Properties properties
The authored values.
-
uint64_t order = {}
The insertion order.
-
Properties properties
-
using OptionalDefinition = std::optional<std::reference_wrapper<const Definition>>
-
class ThemeAccessor
Read-only theme accessor for the current selector.
Public Functions
-
inline ThemeAccessor() noexcept
Create an accessor for the default theme root.
-
inline ThemeAccessor(ThemeConstPtr theme, const Selector selector) noexcept
Create an accessor.
- Parameters:
theme – The active theme. Must not be null.
selector – The selector.
-
ThemeAccessor forPart(Part part) const noexcept
Create an accessor for another part.
-
ThemeAccessor withStates(States states) const noexcept
Create an accessor with additional states.
-
ThemeAccessor withTags(Tags tags) const noexcept
Create an accessor with additional tags.
-
inline Color color(std::size_t animationCycle = 0) const noexcept
Resolve the color for an animation cycle.
-
inline const ColorSequence &colorSequence() const noexcept
Access the effective color sequence.
-
inline CharAttributes attributes() const noexcept
Access the effective attributes.
-
inline CharStyle style(const std::size_t animationCycle = 0) const noexcept
Resolve the style for an animation cycle.
-
inline Char block(const BlockRole role = BlockRole::Main, const std::size_t animationCycle = 0) const noexcept
Resolve a block character for a role.
-
inline Tile9Style tile9Style(const std::size_t animationCycle = 0) const noexcept
Resolve the tile-9 style for an animation cycle.
-
inline Margins margins() const noexcept
Access the effective parent-owned margins outside the current part.
Margins are always zero or positive.
-
inline Margins horizontalMargins() const noexcept
Access the effective horizontal margins with top and bottom set to zero.
Use this for strict one-line text where vertical margins are intentionally ignored. Margins are always zero or positive.
-
inline Margins padding() const noexcept
Access the effective part-owned padding inside the current part.
Padding is always zero or positive.
-
inline Margins horizontalPadding() const noexcept
Access the effective horizontal padding with top and bottom set to zero.
Use this for strict one-line text where vertical padding is intentionally ignored. Padding is always zero or positive.
-
inline Size extent() const noexcept
Calculate the size consumed by margins and padding.
Extent is always zero or positive.
-
inline Size horizontalExtent() const noexcept
Calculate the horizontal size consumed by margins and padding.
Use this for strict one-line text where vertical margins and padding are intentionally ignored. Extent is always zero or positive.
-
inline LayoutRectangles layout(const Rectangle outerRect) const noexcept
Resolve the themed layout rectangles for an assigned rectangle.
- Parameters:
outerRect – The assigned rectangle, including margins.
- Returns:
The resolved rectangles.
-
inline LayoutRectangles horizontalLayout(const Rectangle outerRect) const noexcept
Resolve horizontal-only themed layout rectangles for an assigned rectangle.
Use this for strict one-line text where vertical margins and padding are intentionally ignored.
- Parameters:
outerRect – The assigned rectangle, including horizontal margins.
- Returns:
The resolved rectangles.
-
inline ThemeAccessor() noexcept
-
class ThemePainter
Thin convenience painter for rendering themed blocks into a writable buffer.
Public Functions
-
ThemePainter(WritableBuffer &buffer, ThemeAccessor theme) noexcept
Create a themed painter.
- Parameters:
buffer – The target buffer.
theme – The theme accessor to render.
-
void fill(Rectangle rect) const noexcept
Fill a rectangle using a tile-9 pattern from the accessor.
- Parameters:
rect – The rectangle to fill.
-
void fillBackground(Rectangle rect) const noexcept
Fill the background using
Part::Background, and a tile-9 pattern from accessor.
-
ThemePainter(WritableBuffer &buffer, ThemeAccessor theme) noexcept