#nullable enable using System.Globalization; using System.Text.Json.Serialization; namespace Terminal.Gui; /// Defines a standard set of s for common visible elements in a . /// /// /// ColorScheme objects are immutable. Once constructed, the properties cannot be changed. To change a /// ColorScheme, create a new one with the desired values, using the /// constructor. /// /// [JsonConverter (typeof (ColorSchemeJsonConverter))] public class ColorScheme : IEquatable { private readonly Attribute _disabled; private readonly Attribute _focus; private readonly Attribute _hotFocus; private readonly Attribute _hotNormal; private readonly Attribute _normal; /// Creates a new instance set to the default colors (see ). public ColorScheme () : this (Attribute.Default) { } /// Creates a new instance, initialized with the values from . /// The scheme to initialize the new instance with. public ColorScheme (ColorScheme scheme) { if (scheme is null) { throw new ArgumentNullException (nameof (scheme)); } _normal = scheme.Normal; _focus = scheme.Focus; _hotNormal = scheme.HotNormal; _disabled = scheme.Disabled; _hotFocus = scheme.HotFocus; } /// Creates a new instance, initialized with the values from . /// The attribute to initialize the new instance with. public ColorScheme (Attribute attribute) { _normal = attribute; _focus = attribute; _hotNormal = attribute; _disabled = attribute; _hotFocus = attribute; } /// The default foreground and background color for text when the view is disabled. public Attribute Disabled { get => _disabled; init => _disabled = value; } /// The foreground and background color for text when the view has the focus. public Attribute Focus { get => _focus; init => _focus = value; } /// The foreground and background color for for text in a focused view that indicates a . public Attribute HotFocus { get => _hotFocus; init => _hotFocus = value; } /// The foreground and background color for text in a non-focused view that indicates a . public Attribute HotNormal { get => _hotNormal; init => _hotNormal = value; } /// The foreground and background color for text when the view is not focused, hot, or disabled. public Attribute Normal { get => _normal; init => _normal = value; } /// Compares two objects for equality. /// /// true if the two objects are equal public bool Equals (ColorScheme? other) { return other is { } && EqualityComparer.Default.Equals (_normal, other._normal) && EqualityComparer.Default.Equals (_focus, other._focus) && EqualityComparer.Default.Equals (_hotNormal, other._hotNormal) && EqualityComparer.Default.Equals (_hotFocus, other._hotFocus) && EqualityComparer.Default.Equals (_disabled, other._disabled); } /// Compares two objects for equality. /// /// true if the two objects are equal public override bool Equals (object? obj) { return Equals (obj as ColorScheme); } /// Returns a hashcode for this instance. /// hashcode for this instance public override int GetHashCode () { int hashCode = -1242460230; hashCode = hashCode * -1521134295 + _normal.GetHashCode (); hashCode = hashCode * -1521134295 + _focus.GetHashCode (); hashCode = hashCode * -1521134295 + _hotNormal.GetHashCode (); hashCode = hashCode * -1521134295 + _hotFocus.GetHashCode (); hashCode = hashCode * -1521134295 + _disabled.GetHashCode (); return hashCode; } /// Compares two objects for equality. /// /// /// true if the two objects are equivalent public static bool operator == (ColorScheme left, ColorScheme right) { return EqualityComparer.Default.Equals (left, right); } /// Compares two objects for inequality. /// /// /// true if the two objects are not equivalent public static bool operator != (ColorScheme left, ColorScheme right) { return !(left == right); } /// public override string ToString () { return $"Normal: {Normal}; Focus: {Focus}; HotNormal: {HotNormal}; HotFocus: {HotFocus}; Disabled: {Disabled}"; } } /// /// Holds the s that define the s that are used by views to render /// themselves. /// public static class Colors { static Colors () { Reset (); } /// Gets a dictionary of defined objects. /// /// /// The dictionary includes the following keys, by default: /// /// /// Built-in Color Scheme Description /// /// /// Base The base color scheme used for most Views. /// /// /// TopLevel /// The application Toplevel color scheme; used for the View. /// /// /// Dialog /// /// The dialog color scheme; used for , , and /// other views dialog-like views. /// /// /// /// Menu /// /// The menu color scheme; used for , , and /// . /// /// /// /// Error /// /// The color scheme for showing errors, such as in /// . /// /// /// /// /// Changing the values of an entry in this dictionary will affect all views that use the scheme. /// /// can be used to override the default values for these schemes and add /// additional schemes. See . /// /// [SerializableConfigurationProperty (Scope = typeof (ThemeScope), OmitClassName = true)] [JsonConverter (typeof (DictionaryJsonConverter))] public static Dictionary ColorSchemes { get; private set; } // Serialization requires this to have a setter (private set;) /// Resets the dictionary to the default values. public static Dictionary Reset () { ColorSchemes ??= new Dictionary ( 5, CultureInfo.InvariantCulture.CompareInfo .GetStringComparer ( CompareOptions.IgnoreCase ) ); ColorSchemes.Clear (); ColorSchemes.Add ("TopLevel", new ColorScheme ()); ColorSchemes.Add ("Base", new ColorScheme ()); ColorSchemes.Add ("Dialog", new ColorScheme ()); ColorSchemes.Add ("Menu", new ColorScheme ()); ColorSchemes.Add ("Error", new ColorScheme ()); return ColorSchemes; } private class SchemeNameComparerIgnoreCase : IEqualityComparer { public bool Equals (string x, string y) { if (x != null && y != null) { return string.Equals (x, y, StringComparison.InvariantCultureIgnoreCase); } return false; } public int GetHashCode (string obj) { return obj.ToLowerInvariant ().GetHashCode (); } } }