Table of Contents

Class Scheme

Namespace
Terminal.Gui.Drawing
Assembly
Terminal.Gui.dll

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()

Creates a new instance set to the default attributes (see Default).

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.

EqualityContract
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

Equals(object?)
Equals(Scheme?)
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.

GetHashCode()
PrintMembers(StringBuilder)
ToString()
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.

Explicit Interface Implementations

operator ==(Scheme?, Scheme?)
operator !=(Scheme?, Scheme?)