Fix Icon Transition bug

This commit is contained in:
chinboy
2025-02-05 17:30:34 +08:00
parent 4ec441d920
commit dfdc1cdfa4
5 changed files with 70 additions and 40 deletions
+1
View File
@@ -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;
}
@@ -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;
}
}
@@ -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))
{
+34 -32
View File
@@ -55,7 +55,7 @@ public sealed class Icon : Control, ICustomHitTest
nameof(FillAnimationDuration), TimeSpan.FromMilliseconds(300));
public static readonly StyledProperty<IconMode> IconModeProperty =
AvaloniaProperty.Register<Icon, IconMode>(nameof(IconMode));
AvaloniaProperty.Register<Icon, IconMode>(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<IBrush?> FilledBrushProperty
= AvaloniaProperty.Register<ToggleSwitch, IBrush?>(
nameof(IBrush));
/// <summary>
/// 当是非 TwoTone icon 的时候,填充色是支持渐变的
/// </summary>
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<IBrush?> FilledBrushProperty
= AvaloniaProperty.Register<Icon, IBrush?>(
nameof(FilledBrush));
/// <summary>
/// 当是非 TwoTone icon 的时候,填充色是支持渐变的
/// </summary>
internal IBrush? FilledBrush
{
get => GetValue(FilledBrushProperty);
set => SetValue(FilledBrushProperty, value);
}
#endregion
@@ -178,12 +178,16 @@ public sealed class Icon : Control, ICustomHitTest
_sourceGeometriesData = new List<Geometry>();
_transforms = new List<Matrix>();
}
public override void ApplyTemplate()
{
base.ApplyTemplate();
BuildSourceRenderData();
SetupFilledBrush();
Transitions ??= new Transitions
{
AnimationUtils.CreateTransition<SolidColorBrushTransition>(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<SolidColorBrushTransition>(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);
}
-1
View File
@@ -1,5 +1,4 @@
using System.ComponentModel;
using AtomUI.Media;
using Avalonia;
using Avalonia.Media;