using System; using System.Collections.Generic; 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. /// /// /// See also: . /// /// [JsonConverter (typeof (ColorSchemeJsonConverter))] public class ColorScheme : IEquatable { readonly Attribute _disabled = Attribute.Default; readonly Attribute _focus = Attribute.Default; readonly Attribute _hotFocus = Attribute.Default; readonly Attribute _hotNormal = Attribute.Default; readonly Attribute _normal = Attribute.Default; /// /// 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 == 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 foreground and background color for text when the view is not focused, hot, or disabled. /// public Attribute Normal { get => _normal; init => _normal = 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 text in a non-focused view that indicates a . /// public Attribute HotNormal { get => _hotNormal; init => _hotNormal = 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 default foreground and background color for text when the view is disabled. /// public Attribute Disabled { get => _disabled; init => _disabled = value; } /// /// Compares two objects for equality. /// /// /// true if the two objects are equal public bool Equals (ColorScheme other) => other != null && 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) => Equals (obj is ColorScheme ? (ColorScheme)obj : default); /// /// Returns a hashcode for this instance. /// /// hashcode for this instance public override int GetHashCode () { var 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) => 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) => !(left == right); } /// /// 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 (comparer: new SchemeNameComparerIgnoreCase ()) { { "TopLevel", new ColorScheme () }, { "Base", new ColorScheme () }, { "Dialog", new ColorScheme () }, { "Menu", new ColorScheme () }, { "Error", new ColorScheme () }, }; 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) => obj.ToLowerInvariant ().GetHashCode (); } }