GGUI::StyleTable class

StyleTable: tokens and layered rules.

styles.Token("accent", GGColor::Hex(0x8B5CF6FF));
styles.Rule("button",         { .Fill = Grey, .Radius = 5 });
styles.Rule("button:hover",   { .Fill = LightGrey });          // radius carries over
styles.Rule("button primary", { .Fill = Token("accent") });

Selectors and rule precedence are described in UIStyle.h. State priority, highest last: checked, hovered, focused, pressed, disabled.

Set() is the older form: a complete style for a class in a state, replacing whatever was there.

styles.Set("button", StateHovered, { .Fill = LightGrey, .Radius = 5 });

Threading: fill it before the UI update uses it, and change it only while none of its documents is updating. During updates it is read-only; documents sharing a table update in parallel, each with its own GGLooks. Changes are picked up at the next paint: what looks different is repainted and no component re-runs.

Public static functions

static void ScopesOf(uint64_t classKey, std::span<const GGStyleScopes*const> sets, std::vector<const GGStyleScope*>& out)
The scopes of sets an element with this class key is in, lowest rank first.
static auto BuiltInSheet() -> std::string_view
Source text of the built-in sheet: the built-in widgets' styles and the tokens a theme changes.

Public functions

void Token(std::string_view name, GGColor value)
Define or replace a colour token.
void Token(std::string_view name, float value)
Define or replace a number token.
void Token(std::string_view name, GGToken same)
Alias one token to another.
auto FindToken(std::string_view name, GGColor& out) const -> bool
A colour token's value. False if there is no such token or it is a number.
auto FindToken(std::string_view name, float& out) const -> bool
A number token's value. False if there is no such token or it is a colour.
auto FindToken(std::string_view name, GGColor& out, std::span<const GGStyleScope*const> scopes) const -> bool
A colour token as seen by an element in scopes (lowest rank first; see ScopesOf).
auto FindToken(std::string_view name, float& out, std::span<const GGStyleScope*const> scopes) const -> bool
A number token as seen by an element in scopes.
auto Rule(std::string_view selector, const GGStyle& style) -> bool
Add a rule (see UIStyle.h). Returns false, and adds nothing, if the selector doesn't parse.
auto SetSheet(std::string_view name, std::string_view text, GGSheetError* error = nullptr) -> bool
Load a sheet from text (syntax in UIStyle.h). Setting the same name again replaces that sheet. On a parse error nothing changes, false is returned, and error says where and why.
auto RemoveSheet(std::string_view name) -> bool
Remove the sheet of that name. False if there is none.
auto HasSheet(std::string_view name) const -> bool
Whether there is a sheet of that name.
void Explain(uint64_t classKey, uint8_t state, std::vector<GGStyleOrigin>& out) const
For tools: every resolved property of a class and state, with the rule that set it.
void Explain(uint64_t classKey, uint8_t state, std::vector<GGStyleOrigin>& out, std::span<const GGStyleScopes*const> sets, const PaintStyle* shown) const
The same, for an element in scopes of sets, whose look is shown (null: the table's).
void ListTokens(std::vector<GGTokenInfo>& out) const
For tools: every token, sorted by name.
void OverrideToken(std::string_view name, GGColor value) const
For tools: override a token above everything else until cleared.
void OverrideToken(std::string_view name, float value) const
The same, for a number token.
void ClearOverrides() const
Drop every override at the next ApplyOverrides. Thread-safe.
auto ApplyOverrides() const -> bool
Apply pending OverrideToken / ClearOverrides calls. Returns true if there were any. Like any table change, call it only while no document using the table is updating (UIHost does).
auto OverridesWaiting() const -> bool
True if overrides are pending. Thread-safe.
auto HasOverrides() const -> bool
True if overrides are applied.
void Set(std::string_view className, const PaintStyle& style)
Set the whole style of className with no state (the older form; see above).
void Set(std::string_view className, uint8_t states, const PaintStyle& style)
Set the whole style of className in states (NodeState bits).
void Set(uint64_t classID, uint8_t states, const PaintStyle& style)
The same, by the class's ID.
auto Has(std::string_view selector) const -> bool
True if any rule targets exactly these classes and part ("button", "textfield::text"), in any state. Used to decide whether a default applies.
auto LookOf(uint64_t classKey, uint8_t state, PaintStyle& look, std::span<const GGStyleScopes*const> sets = {}) const -> bool
Layer every matching rule onto look, which must start as the default style: the table's, then those of each scope in sets the class key is in, by rank.
auto Find(uint64_t classKey, uint8_t state = 0) const -> const PaintStyle&
Convenience lookup through the table's own cache, for tools and tests. Serialised between callers. Documents use GGLooks instead.
auto ChangedAt(uint64_t classKey, uint8_t state = 0) const -> uint64_t
As GGLooks::ChangedAt, through the table's own cache.
auto LayoutChangedAt(uint64_t classKey) const -> uint64_t
As GGLooks::LayoutChangedAt, through the table's own cache.
auto Revision() const -> uint64_t
Bumped on every change.
auto RuleCount() const -> size_t
How many rules it has.
void AddDefaults()
Add the built-in sheet as the bottom layer: styles for the built-in widget classes in every state, so an unstyled document is still usable.

Function documentation

bool GGUI::StyleTable::SetSheet(std::string_view name, std::string_view text, GGSheetError* error = nullptr)

Load a sheet from text (syntax in UIStyle.h). Setting the same name again replaces that sheet. On a parse error nothing changes, false is returned, and error says where and why.

Layering, bottom to top: the built-in sheet (AddDefaults), sheets in the order their names were first set, then code (Token, Rule, Set).

void GGUI::StyleTable::OverrideToken(std::string_view name, GGColor value) const

For tools: override a token above everything else until cleared.

The table's own values are untouched and overrides aren't saved. Thread-safe, even during updates: the override takes effect at the next ApplyOverrides.

bool GGUI::StyleTable::LookOf(uint64_t classKey, uint8_t state, PaintStyle& look, std::span<const GGStyleScopes*const> sets = {}) const

Layer every matching rule onto look, which must start as the default style: the table's, then those of each scope in sets the class key is in, by rank.

A token is the highest scope's that defines it, else the table's. False if nothing matches. Read-only and thread-safe.

void GGUI::StyleTable::AddDefaults()

Add the built-in sheet as the bottom layer: styles for the built-in widget classes in every state, so an unstyled document is still usable.

Sheets and code layer over it regardless of call order; a whole-style Set replaces the built-in style for that class and state.