#nullable enable
using System.Numerics;
using System.Text.Json.Serialization;
namespace Terminal.Gui.Drawing;
///
/// Represents the visual styling for a UI element, including foreground and background color and text style.
///
///
///
/// is a lightweight, immutable struct used to define how visual elements are rendered
/// in a terminal UI. It wraps color and style information in a platform-independent way and is used
/// extensively in , , and theming infrastructure.
///
///
///
///
///
///
[JsonConverter (typeof (AttributeJsonConverter))]
public readonly record struct Attribute : IEqualityOperators
{
/// Default empty attribute.
[JsonIgnore]
public static Attribute Default => new (Color.White, Color.Black);
///
/// Gets the foreground used to render text.
///
[JsonConverter (typeof (ColorJsonConverter))]
public Color Foreground { get; init; }
///
/// Gets the background used behind text.
///
[JsonConverter (typeof (ColorJsonConverter))]
public Color Background { get; init; }
// TODO: Add constructors which permit including a Style.
///
/// Gets the (e.g., bold, underline, italic) applied to text.
///
public TextStyle Style { get; init; } = TextStyle.None;
///
/// Initializes a new instance of the struct with default values.
///
public Attribute () { this = Default; }
///
/// Initializes a new from an existing instance, preserving explicit state.
///
public Attribute (in Attribute attr) { this = attr; }
///
/// Initializes an instance using two named colors.
///
public Attribute (in Color foreground, in Color background)
{
Foreground = foreground;
Background = background;
Style = TextStyle.None;
}
///
/// Initializes a new instance with foreground, background, and .
///
public Attribute (in Color foreground, in Color background, in TextStyle style)
{
Foreground = foreground;
Background = background;
Style = style;
}
///
/// Initializes a new instance of the struct from string representations of colors and style.
///
/// Foreground color as a string (name, hex, or rgb).
/// Background color as a string (name, hex, or rgb).
/// Optional style as a string (e.g., "Bold,Underline").
/// Thrown if color parsing fails.
public Attribute (in string foreground, in string background, in string? style = null)
{
Foreground = Color.Parse (foreground);
Background = Color.Parse (background);
Style = style is { } && Enum.TryParse (style, true, out TextStyle parsedStyle)
? parsedStyle
: TextStyle.None;
}
///
/// Initializes a new instance of the struct from string representations of colors and style.
///
/// Foreground color as a string (name, hex, or rgb).
/// Background color as a string (name, hex, or rgb).
/// Optional style as a string (e.g., "Bold,Underline").
/// Thrown if color parsing fails.
public Attribute (in string foreground, in string background, in TextStyle style)
{
Foreground = Color.Parse (foreground);
Background = Color.Parse (background);
Style = style;
}
///
/// INTERNAL: Initializes a new instance with a value. Both and
/// will be set to the specified color.
///
/// Value.
internal Attribute (in ColorName16 color16Name) : this (in color16Name, in color16Name) { }
///
/// Initializes a new instance with foreground and background colors.
///
public Attribute (in ColorName16 foreground16Name, in ColorName16 background16Name)
: this (new Color (in foreground16Name), new Color (in background16Name))
{ }
///
/// Initializes a new instance with foreground and background colors.
///
public Attribute (in ColorName16 foreground16Name, in Color background) : this (new Color (in foreground16Name), in background) { }
///
/// Initializes a new instance with foreground and background colors.
///
public Attribute (in Color foreground, in ColorName16 background16Name) : this (in foreground, new Color (in background16Name)) { }
///
/// INTERNAL: Initializes a new instance with a value. Both and
/// will be set to the specified color.
///
/// Value.
internal Attribute (in StandardColor standardColor) : this (in standardColor, in standardColor) { }
///
/// Initializes a new instance with foreground and background colors.
///
public Attribute (in StandardColor foreground, in StandardColor background)
: this (new Color (in foreground), new Color (in background))
{ }
///
/// Initializes a new instance with foreground and background colors.
///
public Attribute (in StandardColor foreground, in Color background) : this (new Color (in foreground), in background) { }
///
/// Initializes a new instance with foreground and background colors.
///
public Attribute (in Color foreground, in StandardColor background) : this (in foreground, new Color (in background)) { }
///
/// Initializes an instance using a single color for both foreground and background.
///
public Attribute (in Color color) : this (color, color) { }
///
/// Initializes a new instance with foreground and background colors and a .
///
public Attribute (in StandardColor foreground, in StandardColor background, in TextStyle style) : this (
new (in foreground),
new Color (in background),
style)
{ }
///
public bool Equals (Attribute other)
{
return Foreground.Equals (other.Foreground)
&& Background.Equals (other.Background)
&& Style == other.Style;
}
///
public override int GetHashCode () { return HashCode.Combine (Foreground, Background, Style); }
///
public override string ToString ()
{
// Note: Unit tests are dependent on this format
return $"[{Foreground},{Background},{Style}]";
}
}