diff --git a/TestGame/Resources/default.style.toml b/TestGame/Resources/default.style.toml index cb4c8f8..f588d3f 100644 --- a/TestGame/Resources/default.style.toml +++ b/TestGame/Resources/default.style.toml @@ -1,12 +1,9 @@ [Button] BackgroundColor = "#0f62fe" +CornerRadius = 16.0 TextColor = "#ffffff" Padding = 16.0 -# Creates an empty rule for Button.Normal. -# This will inherit style from Button, this is a temporary workaround. -[Button.Normal] - [Button.Hovered] BackgroundColor = "#0353e9" diff --git a/Voile/Source/UI/Style.cs b/Voile/Source/UI/Style.cs index 5988c43..b8aa70c 100644 --- a/Voile/Source/UI/Style.cs +++ b/Voile/Source/UI/Style.cs @@ -11,7 +11,7 @@ namespace Voile.UI; /// public class Style { - public enum AnimationType + public enum TransitionType { Linear, EaseIn, @@ -20,7 +20,7 @@ public class Style } public float TransitionDuration = 0f; - public AnimationType TransitionType = AnimationType.Linear; + public TransitionType Transition = TransitionType.Linear; public Style() { } @@ -35,17 +35,39 @@ public class Style /// Merges this with a different one.
/// Properties that are not set for this will be inherited from . /// - /// + /// /// A merged . - public Style Merge(Style overrideStyle) + public Style Merge(Style other) { return new Style { - BackgroundColor = overrideStyle.BackgroundColor != default ? overrideStyle.BackgroundColor : BackgroundColor, - TextColor = overrideStyle.TextColor != default ? overrideStyle.TextColor : TextColor, - Padding = overrideStyle.Padding != default ? overrideStyle.Padding : Padding, - BorderSize = overrideStyle.BorderSize != default ? overrideStyle.BorderSize : BorderSize, - BorderColor = overrideStyle.BorderColor != default ? overrideStyle.BorderColor : BorderColor, + Padding = + other.Padding ?? Padding, + + BackgroundColor = + other.BackgroundColor ?? BackgroundColor, + + BorderSize = + other.BorderSize ?? BorderSize, + + BorderColor = + other.BorderColor ?? BorderColor, + + TextColor = + other.TextColor ?? TextColor, + + CornerRadius = + other.CornerRadius != default + ? other.CornerRadius + : CornerRadius, + + TransitionDuration = + other.TransitionDuration != default + ? other.TransitionDuration + : TransitionDuration, + + Transition = + other.Transition }; } } @@ -88,12 +110,12 @@ public class StyleSheetLoader : ResourceLoader { var style = new Style(); - string easingName = reader.GetString("TransitionType", "Linear"); + string transitionName = reader.GetString("TransitionType", "Linear"); - if (!Enum.TryParse(easingName, true, out var easing)) - easing = Style.AnimationType.Linear; + if (!Enum.TryParse(transitionName, true, out var transition)) + throw new ArgumentException($"\"{transitionName}\" is not a valid TransitionType."); - style.TransitionType = easing; + style.Transition = transition; if (reader.HasKey("BackgroundColor")) @@ -147,9 +169,13 @@ public class StyleSheet : Resource public void Add(string key, Style style) => _styles.Add(key, style); - public bool TryGet(string styleName, [NotNullWhen(true)] out Style? style) + public bool TryGet( + string styleName, + [NotNullWhen(true)] out Style? style) { - return _styles.TryGetValue(styleName, out style); + style = Resolve(styleName); + + return style != null; } public static StyleSheet Default => new(new Dictionary() @@ -226,5 +252,29 @@ public class StyleSheet : Resource }}, }); + private Style? Resolve(string fullKey) + { + var parts = fullKey.Split('.'); + + Style? merged = null; + + for (int i = 1; i <= parts.Length; i++) + { + var subKey = string.Join('.', + parts.Take(i)); + + if (_styles.TryGetValue( + subKey, + out var style)) + { + merged ??= new Style(); + + merged = merged.Merge(style); + } + } + + return merged; + } + private Dictionary _styles = new(); } \ No newline at end of file diff --git a/Voile/Source/UI/StyleAnimator.cs b/Voile/Source/UI/StyleAnimator.cs index e6e981c..48836e9 100644 --- a/Voile/Source/UI/StyleAnimator.cs +++ b/Voile/Source/UI/StyleAnimator.cs @@ -13,14 +13,14 @@ public class StyleAnimator _elapsed = 0f; } - public static float Ease(float t, Style.AnimationType type) + public static float Ease(float t, Style.TransitionType type) { return type switch { - Style.AnimationType.Linear => t, - Style.AnimationType.EaseIn => t * t, - Style.AnimationType.EaseOut => t * (2 - t), - Style.AnimationType.EaseInOut => t < 0.5f + Style.TransitionType.Linear => t, + Style.TransitionType.EaseIn => t * t, + Style.TransitionType.EaseOut => t * (2 - t), + Style.TransitionType.EaseInOut => t < 0.5f ? 2 * t * t : -1 + (4 - 2 * t) * t, _ => t @@ -31,7 +31,7 @@ public class StyleAnimator { _elapsed = MathF.Min(_elapsed + deltaTime, _duration); float t = _duration == 0 ? 1 : _elapsed / _duration; - float easedT = Ease(t, _to.TransitionType); + float easedT = Ease(t, _to.Transition); return LerpStyle(_from, _to, easedT); } @@ -45,7 +45,7 @@ public class StyleAnimator Padding = MathUtils.LerpSize(from.Padding ?? Size.Zero, to.Padding ?? Size.Zero, t), BorderColor = MathUtils.LerpColor(from.BorderColor ?? Color.Transparent, to.BorderColor ?? Color.Transparent, t), BorderSize = MathUtils.LerpSize(from.BorderSize ?? Size.Zero, to.BorderSize ?? Size.Zero, t), - TransitionType = to.TransitionType + Transition = to.Transition }; return result;