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.
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.
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.
public override int GetHashCode() {
return EqualityComparer.Default.GetHashCode(this.Value);
}
/// 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.
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.
public static bool operator !=(StyleProp left, StyleProp right) {
return !left.Equals(right);
}
}
}