Class Scheme
Represents a theme definition that maps each VisualRole (such as Focus, Disabled, etc.) to an Attribute describing its foreground color, background color, and text style.
A Scheme enables consistent, semantic theming of UI elements by associating each visual state with a specific style. Each property (e.g., Normal, Focus, Disabled) is an Attribute. If a property is not explicitly set, its value is derived from other roles (typically Normal) using well-defined inheritance rules.
Scheme objects are immutable. To update a scheme, create a new instance with the desired values. Use SchemeManager to manage available schemes and apply them to views.
See https://gui-cs.github.io/Terminal.Gui/docs/drawing.html for more information.
[JsonConverter(typeof(SchemeJsonConverter))]
public record Scheme : IEqualityOperators<Scheme, Scheme, bool>, IEquatable<Scheme>
- Inheritance
-
Scheme
- Implements
- Inherited Members
Remarks
Immutability: Scheme objects are immutable. Once constructed, their properties cannot be changed. To modify a Scheme, create a new instance with the desired values (e.g., using the Scheme constructor).
Attribute Resolution Algorithm:
Each Scheme property corresponds to a VisualRole and is an Attribute.
The Normal attribute must always be set.
All other attributes are optional. If an attribute for a given VisualRole is not explicitly set,
its value is derived using the following rules:
<ol><li><b>Normal:</b> Must always be explicitly set.</li><li>
<b>Focus:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> by swapping foreground and background
colors. Any <xref href="Terminal.Gui.Drawing.Color.None" data-throw-if-not-resolved="false"></xref> values are resolved to the terminal's actual default colors
(queried via OSC 10/11) before swapping.
</li><li>
<b>Active:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Focus" data-throw-if-not-resolved="false"></xref> by:
<ul><li>
Setting <code>Foreground</code> to <xref href="Terminal.Gui.Drawing.Scheme.Focus" data-throw-if-not-resolved="false"></xref>'s foreground with
<xref href="Terminal.Gui.Drawing.Color.GetBrighterColor(System.Double%2cSystem.Nullable%7bSystem.Boolean%7d)" data-throw-if-not-resolved="false"></xref>, passing whether the
<xref href="Terminal.Gui.Drawing.Scheme.Focus" data-throw-if-not-resolved="false"></xref> background is dark or light.
</li><li>
Setting <code>Background</code> to <xref href="Terminal.Gui.Drawing.Scheme.Focus" data-throw-if-not-resolved="false"></xref>'s background with
<xref href="Terminal.Gui.Drawing.Color.GetDimmerColor(System.Double%2cSystem.Nullable%7bSystem.Boolean%7d)" data-throw-if-not-resolved="false"></xref>, passing the same dark/light context.
</li><li>Adding <xref href="Terminal.Gui.Drawing.TextStyle.Bold" data-throw-if-not-resolved="false"></xref> to the style.</li></ul>
</li><li>
<b>Highlight:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> by:
<ul><li>
Setting <code>Foreground</code> to <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref>'s background with
<xref href="Terminal.Gui.Drawing.Color.GetBrighterColor(System.Double%2cSystem.Nullable%7bSystem.Boolean%7d)" data-throw-if-not-resolved="false"></xref>, using the
<xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> background's dark/light context.
</li><li>Setting <code>Background</code> to <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref>'s background.</li><li>
Setting <code>Style</code> to <xref href="Terminal.Gui.Drawing.Scheme.Editable" data-throw-if-not-resolved="false"></xref>'s style with
<xref href="Terminal.Gui.Drawing.TextStyle.Italic" data-throw-if-not-resolved="false"></xref> added.
</li></ul>
</li><li>
<b>Editable:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> by:
<ul><li>
Setting <code>Foreground</code> to <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref>'s foreground (resolved).
</li><li>
Setting <code>Background</code> to <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref>'s foreground with
<xref href="Terminal.Gui.Drawing.Color.GetDimmerColor(System.Double%2cSystem.Nullable%7bSystem.Boolean%7d)" data-throw-if-not-resolved="false"></xref> at 50%, using the
<xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> background's dark/light context.
</li></ul>
</li><li>
<b>ReadOnly:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Editable" data-throw-if-not-resolved="false"></xref> by dimming
the foreground with <xref href="Terminal.Gui.Drawing.Color.GetDimmerColor(System.Double%2cSystem.Nullable%7bSystem.Boolean%7d)" data-throw-if-not-resolved="false"></xref> at 5%,
using the <xref href="Terminal.Gui.Drawing.Scheme.Editable" data-throw-if-not-resolved="false"></xref> background's dark/light context.
</li><li>
<b>Disabled:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> by dimming
the foreground with <xref href="Terminal.Gui.Drawing.Color.GetDimmerColor(System.Double%2cSystem.Nullable%7bSystem.Boolean%7d)" data-throw-if-not-resolved="false"></xref> at 5%,
using the <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> background's dark/light context.
</li><li>
<b>HotNormal:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Normal" data-throw-if-not-resolved="false"></xref> by adding
<xref href="Terminal.Gui.Drawing.TextStyle.Underline" data-throw-if-not-resolved="false"></xref> to the style.
</li><li>
<b>HotFocus:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Focus" data-throw-if-not-resolved="false"></xref> by adding
<xref href="Terminal.Gui.Drawing.TextStyle.Underline" data-throw-if-not-resolved="false"></xref> to the style.
</li><li>
<b>HotActive:</b> If not set, derived from <xref href="Terminal.Gui.Drawing.Scheme.Active" data-throw-if-not-resolved="false"></xref> by adding
<xref href="Terminal.Gui.Drawing.TextStyle.Underline" data-throw-if-not-resolved="false"></xref> to the style.
</li></ol>
This algorithm ensures that every <xref href="Terminal.Gui.Drawing.VisualRole" data-throw-if-not-resolved="false"></xref> always resolves to a valid <xref href="Terminal.Gui.Drawing.Attribute" data-throw-if-not-resolved="false"></xref>,
either explicitly set or derived.
Dark/Light Background Awareness:
When deriving roles that use color math (GetBrighterColor(double, bool?) and
GetDimmerColor(double, bool?)), the algorithm determines whether the relevant background
is dark or light via IsDarkColor(). This ensures correct visual results regardless
of whether the terminal has a dark or light background. For example, "dimming" a color on a light background
increases lightness (washing out toward white) rather than decreasing it.
None Resolution:
Before performing color math, any None values are resolved to the terminal's actual
default colors (detected via OSC 10/11 queries at startup). If the terminal's colors are not available,
the fallback is White for foreground and Black for background.
Constructors
- Scheme(Attribute)
Creates a new instance, initialized with the values from
attribute.
- Scheme(Scheme?)
Creates a new instance, initialized with the values from
scheme.
Properties
- Active
The visual role for elements that are active or selected (e.g., selected item in a ListView). Also used for headers in, HexView, CharMap and TabView. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- Disabled
The visual role for elements that are disabled and not interactable. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- Editable
The visual role for elements that are editable (e.g., TextField and TextView). If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- Focus
The visual role when the element is focused. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- Highlight
The visual role for elements that are highlighted (e.g., when the mouse is inside a Button). If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- HotActive
The visual role for Active elements with a HotKey indicator. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- HotFocus
The visual role for Focus elements with a HotKey indicator. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- HotNormal
The visual role for Normal elements with a HotKey indicator. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
- Normal
The default visual role for unfocused, unselected, enabled elements. The Normal attribute must always be set. All other attributes are optional, and if not explicitly set, will be automatically generated. See the description for Scheme for details on the algorithm used.
- ReadOnly
The visual role for elements that are normally editable but currently read-only. If not explicitly set, will be a derived value. See the description for Scheme for details on the algorithm used.
Methods
- GetAttributeForRole(string)
Gets the Attribute associated with a specified VisualRole string.
- GetAttributeForRole(VisualRole, Attribute?)
Gets the Attribute associated with a specified VisualRole, applying inheritance rules for attributes not explicitly set.
- TryGetExplicitlySetAttributeForRole(VisualRole, out Attribute?)
Attempts to get the Attribute associated with a specified VisualRole. If the role is not explicitly set, it will return false and the out parameter will be null.