using System; using System.Collections.Generic; using MLEM.Ui.Elements; namespace MLEM.Ui.Style { /// /// A struct used by to store style properties. /// This is a helper struct that allows default style settings from to be overridden by custom user settings easily. /// Note that T implicitly converts to StyleProp{T} and vice versa. /// /// The type of style setting that this property stores public readonly struct StyleProp : IEquatable> { /// /// The empty style property, with no and a priority of 0. /// public static StyleProp None => default; /// /// The currently applied style /// public readonly T Value; private readonly byte priority; /// /// Creates a new style property with the given custom style and a priority of . /// To create a style property with a lower priority, use on an existing priority, or use . /// /// The custom style to apply public StyleProp(T value) : this(value, byte.MaxValue) {} private StyleProp(T value, byte priority) { this.Value = value; this.priority = priority; } /// /// Creates a copy of this style property and sets its value and marks it as being set by a if it doesn't have a custom value yet. /// This allows this property to be overridden by custom style settings using or a higher . /// /// The style to apply /// The priority that the style value has. Higher priority style values will override lower priority style values. /// The style with the higher priority public StyleProp OrStyle(T value, byte priority = 0) { return this.OrStyle(new StyleProp(value, priority)); } /// /// Chooses and returns the style property with the higher priority, out of this value and . /// This allows this property to be overridden by custom style settings using or a higher priority. /// /// The style property to compare with /// The style property with the higher priority public StyleProp OrStyle(StyleProp other) { return other.priority >= this.priority ? other : this; } /// /// Returns the current style value or, if is false, the given default value. /// /// The default to return if this style property has no value /// The current value, or the default public T OrDefault(T def) { return this.HasValue() ? this.Value : def; } /// /// Returns whether this style property has a value assigned to it using or . /// /// Whether this style property has a value public bool HasValue() { return !EqualityComparer.Default.Equals(this.Value, default); } /// Indicates whether the current object is equal to another object of the same type. /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. [Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")] public bool Equals(StyleProp other) { return EqualityComparer.Default.Equals(this.Value, other.Value); } /// Indicates whether this instance and a specified object are equal. /// The object to compare with the current instance. /// true if obj and this instance are the same type and represent the same value; otherwise, false. [Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")] #pragma warning disable CS0809 public override bool Equals(object obj) { return obj is StyleProp other && this.Equals(other); } /// Returns the hash code for this instance. /// A 32-bit signed integer that is the hash code for this instance. [Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")] public override int GetHashCode() { return EqualityComparer.Default.GetHashCode(this.Value); } #pragma warning restore CS0809 /// Returns the fully qualified type name of this instance. /// The fully qualified type name. public override string ToString() { return this.Value?.ToString(); } /// /// Implicitly converts a style property to its value. /// /// The property to convert /// The style that the style property holds public static implicit operator T(StyleProp prop) { return prop.Value; } /// /// Implicitly converts a style to a style property. /// /// The property to convert /// A style property with the given style value public static implicit operator StyleProp(T prop) { return new StyleProp(prop); } /// /// Compares the two style properties and returns whether they are equal using . /// /// The left style property. /// The right style property. /// Whether the two style properties are equal. [Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")] public static bool operator ==(StyleProp left, StyleProp right) { return left.Equals(right); } /// /// Compares the two style properties and returns whether they are not equal using . /// /// The left style property. /// The right style property. /// Whether the two style properties are not equal. [Obsolete("StyleProp equality is ambiguous as it is not clear whether priority is taken into account. Compare Values instead.")] public static bool operator !=(StyleProp left, StyleProp right) { return !left.Equals(right); } } }