From dfdc1cdfa44bdc613e6eb1ecf5de52633a2ea346 Mon Sep 17 00:00:00 2001 From: chinboy Date: Wed, 5 Feb 2025 17:30:34 +0800 Subject: [PATCH] Fix Icon Transition bug --- packages/AtomUI/AppBuilderExtensions.cs | 1 + src/AtomUI.Controls/ThemeManagerExtensions.cs | 26 ++++++++ .../Utils/IconProviderMarkupExtension.cs | 16 +++-- src/AtomUI.IconPkg/Icon.cs | 66 ++++++++++--------- src/AtomUI.IconPkg/IconInfo.cs | 1 - 5 files changed, 70 insertions(+), 40 deletions(-) diff --git a/packages/AtomUI/AppBuilderExtensions.cs b/packages/AtomUI/AppBuilderExtensions.cs index 3f8cfe78a..a0d0b32bd 100644 --- a/packages/AtomUI/AppBuilderExtensions.cs +++ b/packages/AtomUI/AppBuilderExtensions.cs @@ -27,6 +27,7 @@ public static class AtomUIExtensions themeManager.LoadTheme(ThemeManager.DEFAULT_THEME_ID); themeManager.SetActiveTheme(ThemeManager.DEFAULT_THEME_ID); builder.Instance!.Styles.Add(themeManager); + themeManager.ThemeInitialized(); }); return builder; } diff --git a/src/AtomUI.Controls/ThemeManagerExtensions.cs b/src/AtomUI.Controls/ThemeManagerExtensions.cs index 181aa0bde..43b12095f 100644 --- a/src/AtomUI.Controls/ThemeManagerExtensions.cs +++ b/src/AtomUI.Controls/ThemeManagerExtensions.cs @@ -1,8 +1,11 @@ using AtomUI.Controls.Utils; using AtomUI.MotionScene; using AtomUI.Theme; +using AtomUI.Theme.Data; +using AtomUI.Theme.Styling; using Avalonia; using Avalonia.Animation; +using Avalonia.Media; using Avalonia.Media.Transformation; namespace AtomUI.Controls; @@ -18,4 +21,27 @@ internal static class ThemeManagerExtensions LanguageProviderRegister.Register(); return themeManager; } + + public static ThemeManager ThemeInitialized(this ThemeManager themeManager) + { + var colorTextTertiary = TokenResourceUtils.FindGlobalTokenResource(GlobalTokenResourceKey.ColorTextTertiary); + if (colorTextTertiary is IBrush defaultFilledColor) + { + IconProvider.DefaultFilledColor = defaultFilledColor; + } + + var colorInfoText = TokenResourceUtils.FindGlobalTokenResource(GlobalTokenResourceKey.ColorTextTertiary); + var colorInfoBg = TokenResourceUtils.FindGlobalTokenResource(GlobalTokenResourceKey.ColorInfoBg); + + if (colorInfoText is IBrush primaryFilledColor) + { + IconProvider.DefaultPrimaryFilledColor = primaryFilledColor; + } + + if (colorInfoBg is IBrush secondaryFilledColor) + { + IconProvider.DefaultSecondaryFilledColor = secondaryFilledColor; + } + return themeManager; + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Utils/IconProviderMarkupExtension.cs b/src/AtomUI.Controls/Utils/IconProviderMarkupExtension.cs index 76e12f761..f49f423c6 100644 --- a/src/AtomUI.Controls/Utils/IconProviderMarkupExtension.cs +++ b/src/AtomUI.Controls/Utils/IconProviderMarkupExtension.cs @@ -8,6 +8,9 @@ namespace AtomUI.Controls.Utils; public class IconProvider : MarkupExtension { + public static IBrush? DefaultFilledColor { get; set; } + public static IBrush? DefaultPrimaryFilledColor { get; set; } + public static IBrush? DefaultSecondaryFilledColor { get; set; } public string Kind { get; set; } // Filled 和 Outlined @@ -38,13 +41,12 @@ public class IconProvider : MarkupExtension { var icon = AntDesignIconPackage.Current.BuildIcon(Kind) ?? new Icon(); icon.SetCurrentValue(Icon.LoadingAnimationProperty, Animation); - icon.SetCurrentValue(Icon.NormalFilledBrushProperty, NormalFilledColor); - icon.SetCurrentValue(Icon.ActiveFilledBrushProperty, ActiveFilledColor); - icon.SetCurrentValue(Icon.SelectedFilledBrushProperty, SelectedFilledColor); - icon.SetCurrentValue(Icon.DisabledFilledBrushProperty, DisabledFilledColor); - icon.SetCurrentValue(Icon.PrimaryFilledBrushProperty, SelectedFilledColor); - icon.SetCurrentValue(Icon.DisabledFilledBrushProperty, PrimaryFilledColor); - icon.SetCurrentValue(Icon.SecondaryFilledBrushProperty, SecondaryFilledColor); + icon.SetCurrentValue(Icon.NormalFilledBrushProperty, NormalFilledColor ?? DefaultFilledColor); + icon.SetCurrentValue(Icon.ActiveFilledBrushProperty, ActiveFilledColor ?? DefaultFilledColor); + icon.SetCurrentValue(Icon.SelectedFilledBrushProperty, SelectedFilledColor ?? DefaultFilledColor); + icon.SetCurrentValue(Icon.DisabledFilledBrushProperty, DisabledFilledColor ?? DefaultFilledColor); + icon.SetCurrentValue(Icon.PrimaryFilledBrushProperty, PrimaryFilledColor ?? DefaultPrimaryFilledColor); + icon.SetCurrentValue(Icon.SecondaryFilledBrushProperty, SecondaryFilledColor ?? DefaultSecondaryFilledColor); if (!double.IsNaN(Width)) { diff --git a/src/AtomUI.IconPkg/Icon.cs b/src/AtomUI.IconPkg/Icon.cs index cd83ef2e4..a7d5b2d7f 100644 --- a/src/AtomUI.IconPkg/Icon.cs +++ b/src/AtomUI.IconPkg/Icon.cs @@ -55,7 +55,7 @@ public sealed class Icon : Control, ICustomHitTest nameof(FillAnimationDuration), TimeSpan.FromMilliseconds(300)); public static readonly StyledProperty IconModeProperty = - AvaloniaProperty.Register(nameof(IconMode)); + AvaloniaProperty.Register(nameof(IconMode), IconMode.Normal); public IconInfo? IconInfo { @@ -120,19 +120,6 @@ public sealed class Icon : Control, ICustomHitTest set => SetValue(IconModeProperty, value); } - private static readonly StyledProperty FilledBrushProperty - = AvaloniaProperty.Register( - nameof(IBrush)); - - /// - /// 当是非 TwoTone icon 的时候,填充色是支持渐变的 - /// - private IBrush? FilledBrush - { - get => GetValue(FilledBrushProperty); - set => SetValue(FilledBrushProperty, value); - } - public IconThemeType ThemeType => IconInfo?.ThemeType ?? IconThemeType.Filled; public IconAnimation LoadingAnimation @@ -152,6 +139,19 @@ public sealed class Icon : Control, ICustomHitTest get => GetValue(AngleAnimationRotateProperty); set => SetValue(AngleAnimationRotateProperty, value); } + + internal static readonly StyledProperty FilledBrushProperty + = AvaloniaProperty.Register( + nameof(FilledBrush)); + + /// + /// 当是非 TwoTone icon 的时候,填充色是支持渐变的 + /// + internal IBrush? FilledBrush + { + get => GetValue(FilledBrushProperty); + set => SetValue(FilledBrushProperty, value); + } #endregion @@ -178,12 +178,16 @@ public sealed class Icon : Control, ICustomHitTest _sourceGeometriesData = new List(); _transforms = new List(); } - + public override void ApplyTemplate() { base.ApplyTemplate(); BuildSourceRenderData(); SetupFilledBrush(); + Transitions ??= new Transitions + { + AnimationUtils.CreateTransition(FilledBrushProperty, FillAnimationDuration) + }; } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) @@ -201,17 +205,6 @@ public sealed class Icon : Control, ICustomHitTest IconMode = IconMode.Disabled; } } - else if (change.Property == NormalFilledBrushProperty || - change.Property == ActiveFilledBrushProperty || - change.Property == SelectedFilledBrushProperty || - change.Property == DisabledFilledBrushProperty || - change.Property == PrimaryFilledBrushProperty || - change.Property == SecondaryFilledBrushProperty || - change.Property == IconModeProperty || - change.Property == IconInfoProperty) - { - SetupFilledBrush(); - } else if (change.Property == AngleAnimationRotateProperty) { SetCurrentValue(RenderTransformProperty, new RotateTransform(AngleAnimationRotate)); @@ -223,6 +216,17 @@ public sealed class Icon : Control, ICustomHitTest { SetupRotateAnimation(); } + else if (change.Property == NormalFilledBrushProperty || + change.Property == ActiveFilledBrushProperty || + change.Property == SelectedFilledBrushProperty || + change.Property == DisabledFilledBrushProperty || + change.Property == PrimaryFilledBrushProperty || + change.Property == SecondaryFilledBrushProperty || + change.Property == IconModeProperty || + change.Property == IconInfoProperty) + { + SetupFilledBrush(); + } } } @@ -231,7 +235,7 @@ public sealed class Icon : Control, ICustomHitTest if (_animation is not null) { _animationCancellationTokenSource?.Cancel(); - _animation = null; + _animation = null; } if (LoadingAnimation == IconAnimation.Spin || LoadingAnimation == IconAnimation.Pulse) @@ -339,6 +343,7 @@ public sealed class Icon : Control, ICustomHitTest { return; } + foreach (var geometryData in IconInfo.Data) { _sourceGeometriesData.Add(Geometry.Parse(geometryData.PathData)); @@ -383,17 +388,13 @@ public sealed class Icon : Control, ICustomHitTest _sourceGeometriesData[i] = cloned; } - _viewBox = combined!.Bounds; + _viewBox = combined.Bounds; } } protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { base.OnAttachedToLogicalTree(e); - Transitions ??= new Transitions() - { - AnimationUtils.CreateTransition(FilledBrushProperty, FillAnimationDuration) - }; SetupRotateAnimation(); } @@ -490,6 +491,7 @@ public sealed class Icon : Control, ICustomHitTest { fillBrush = FilledBrush; } + using var state = context.PushTransform(_transforms[i]); context.DrawGeometry(fillBrush, null, renderedGeometry); } diff --git a/src/AtomUI.IconPkg/IconInfo.cs b/src/AtomUI.IconPkg/IconInfo.cs index 97c5dc2fe..6108cdc1e 100644 --- a/src/AtomUI.IconPkg/IconInfo.cs +++ b/src/AtomUI.IconPkg/IconInfo.cs @@ -1,5 +1,4 @@ using System.ComponentModel; -using AtomUI.Media; using Avalonia; using Avalonia.Media;