mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-27 04:09:37 +08:00
Refactor CountBadge
Add IAnimationAwareControl Support
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Theme;
|
||||
using AtomUI.Theme.Data;
|
||||
using AtomUI.Theme.Palette;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
@@ -16,7 +18,9 @@ public enum CountBadgeSize
|
||||
Small
|
||||
}
|
||||
|
||||
public class CountBadge : Control
|
||||
public class CountBadge : Control,
|
||||
IControlSharedTokenResourcesHost,
|
||||
IAnimationAwareControl
|
||||
{
|
||||
#region 公共属性定义
|
||||
|
||||
@@ -47,6 +51,12 @@ public class CountBadge : Control
|
||||
public static readonly StyledProperty<bool> BadgeIsVisibleProperty =
|
||||
AvaloniaProperty.Register<CountBadge, bool>(nameof(BadgeIsVisible), true);
|
||||
|
||||
public static readonly StyledProperty<bool> IsMotionEnabledProperty
|
||||
= AvaloniaProperty.Register<CountBadge, bool>(nameof(IsMotionEnabled), true);
|
||||
|
||||
public static readonly StyledProperty<bool> IsWaveAnimationEnabledProperty
|
||||
= AvaloniaProperty.Register<CountBadge, bool>(nameof(IsWaveAnimationEnabled), true);
|
||||
|
||||
public string? BadgeColor
|
||||
{
|
||||
get => GetValue(BadgeColorProperty);
|
||||
@@ -96,6 +106,18 @@ public class CountBadge : Control
|
||||
set => SetValue(BadgeIsVisibleProperty, value);
|
||||
}
|
||||
|
||||
public bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
|
||||
public bool IsWaveAnimationEnabled
|
||||
{
|
||||
get => GetValue(IsWaveAnimationEnabledProperty);
|
||||
set => SetValue(IsWaveAnimationEnabledProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
@@ -109,6 +131,10 @@ public class CountBadge : Control
|
||||
get => GetValue(MotionDurationProperty);
|
||||
set => SetValue(MotionDurationProperty, value);
|
||||
}
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => BadgeToken.ID;
|
||||
Control IAnimationAwareControl.PropertyBindTarget => this;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -124,6 +150,12 @@ public class CountBadge : Control
|
||||
SizeProperty);
|
||||
AffectsRender<CountBadge>(BadgeColorProperty, OffsetProperty);
|
||||
}
|
||||
|
||||
public CountBadge()
|
||||
{
|
||||
this.RegisterResources();
|
||||
this.BindAnimationProperties(IsMotionEnabledProperty, IsWaveAnimationEnabledProperty);
|
||||
}
|
||||
|
||||
public sealed override void ApplyTemplate()
|
||||
{
|
||||
@@ -172,6 +204,10 @@ public class CountBadge : Control
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DecoratedTarget is null)
|
||||
{
|
||||
IsVisible = true;
|
||||
}
|
||||
badgeAdorner.ApplyToTarget(null, this);
|
||||
}
|
||||
}
|
||||
@@ -184,6 +220,13 @@ public class CountBadge : Control
|
||||
return;
|
||||
}
|
||||
_badgeAdorner.DetachFromTarget(_adornerLayer, enableMotion);
|
||||
if (!enableMotion)
|
||||
{
|
||||
if (DecoratedTarget is null)
|
||||
{
|
||||
IsVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
@@ -209,6 +252,8 @@ public class CountBadge : Control
|
||||
BindUtils.RelayBind(this, SizeProperty, _badgeAdorner, CountBadgeAdorner.SizeProperty);
|
||||
BindUtils.RelayBind(this, OverflowCountProperty, _badgeAdorner, CountBadgeAdorner.OverflowCountProperty);
|
||||
BindUtils.RelayBind(this, CountProperty, _badgeAdorner, CountBadgeAdorner.CountProperty);
|
||||
BindUtils.RelayBind(this, IsMotionEnabledProperty, _badgeAdorner, CountBadgeAdorner.IsMotionEnabledProperty);
|
||||
BindUtils.RelayBind(this, IsWaveAnimationEnabledProperty, _badgeAdorner, CountBadgeAdorner.IsWaveAnimationEnabledProperty);
|
||||
}
|
||||
|
||||
TokenResourceBinder.CreateTokenBinding(this, MotionDurationProperty, SharedTokenKey.MotionDurationSlow);
|
||||
@@ -245,7 +290,7 @@ public class CountBadge : Control
|
||||
}
|
||||
else
|
||||
{
|
||||
HideAdorner(true);
|
||||
HideAdorner(IsMotionEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using AtomUI.Theme.Styling;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
@@ -27,18 +28,6 @@ internal class CountBadgeAdorner : TemplatedControl
|
||||
public static readonly StyledProperty<CountBadgeSize> SizeProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, CountBadgeSize>(
|
||||
nameof(Size));
|
||||
|
||||
internal static readonly StyledProperty<int> CountProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, int>(
|
||||
nameof(Count));
|
||||
|
||||
internal static readonly StyledProperty<IBrush?> BadgeShadowColorProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, IBrush?>(
|
||||
nameof(BadgeShadowColor));
|
||||
|
||||
internal static readonly StyledProperty<double> BadgeShadowSizeProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, double>(
|
||||
nameof(BadgeShadowSize));
|
||||
|
||||
public IBrush? BadgeColor
|
||||
{
|
||||
@@ -70,18 +59,6 @@ internal class CountBadgeAdorner : TemplatedControl
|
||||
set => SetValue(CountProperty, value);
|
||||
}
|
||||
|
||||
public IBrush? BadgeShadowColor
|
||||
{
|
||||
get => GetValue(BadgeShadowColorProperty);
|
||||
set => SetValue(BadgeShadowColorProperty, value);
|
||||
}
|
||||
|
||||
public double BadgeShadowSize
|
||||
{
|
||||
get => GetValue(BadgeShadowSizeProperty);
|
||||
set => SetValue(BadgeShadowSizeProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
@@ -110,6 +87,24 @@ internal class CountBadgeAdorner : TemplatedControl
|
||||
o => o.MotionDuration,
|
||||
(o, v) => o.MotionDuration = v);
|
||||
|
||||
internal static readonly StyledProperty<int> CountProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, int>(
|
||||
nameof(Count));
|
||||
|
||||
internal static readonly StyledProperty<IBrush?> BadgeShadowColorProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, IBrush?>(
|
||||
nameof(BadgeShadowColor));
|
||||
|
||||
internal static readonly StyledProperty<double> BadgeShadowSizeProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, double>(
|
||||
nameof(BadgeShadowSize));
|
||||
|
||||
internal static readonly StyledProperty<bool> IsMotionEnabledProperty
|
||||
= AvaloniaProperty.Register<CountBadgeAdorner, bool>(nameof(IsMotionEnabled), true);
|
||||
|
||||
internal static readonly StyledProperty<bool> IsWaveAnimationEnabledProperty
|
||||
= AvaloniaProperty.Register<CountBadgeAdorner, bool>(nameof(IsWaveAnimationEnabled), true);
|
||||
|
||||
private bool _isAdornerMode;
|
||||
|
||||
internal bool IsAdornerMode
|
||||
@@ -119,25 +114,49 @@ internal class CountBadgeAdorner : TemplatedControl
|
||||
}
|
||||
|
||||
private BoxShadows _boxShadow;
|
||||
public BoxShadows BoxShadow
|
||||
internal BoxShadows BoxShadow
|
||||
{
|
||||
get => _boxShadow;
|
||||
set => SetAndRaise(BoxShadowProperty, ref _boxShadow, value);
|
||||
}
|
||||
|
||||
private string? _countText;
|
||||
public string? CountText
|
||||
internal string? CountText
|
||||
{
|
||||
get => _countText;
|
||||
set => SetAndRaise(CountTextProperty, ref _countText, value);
|
||||
}
|
||||
|
||||
private TimeSpan _motionDuration;
|
||||
public TimeSpan MotionDuration
|
||||
internal TimeSpan MotionDuration
|
||||
{
|
||||
get => _motionDuration;
|
||||
set => SetAndRaise(MotionDurationProperty, ref _motionDuration, value);
|
||||
}
|
||||
|
||||
internal IBrush? BadgeShadowColor
|
||||
{
|
||||
get => GetValue(BadgeShadowColorProperty);
|
||||
set => SetValue(BadgeShadowColorProperty, value);
|
||||
}
|
||||
|
||||
internal double BadgeShadowSize
|
||||
{
|
||||
get => GetValue(BadgeShadowSizeProperty);
|
||||
set => SetValue(BadgeShadowSizeProperty, value);
|
||||
}
|
||||
|
||||
internal bool IsMotionEnabled
|
||||
{
|
||||
get => GetValue(IsMotionEnabledProperty);
|
||||
set => SetValue(IsMotionEnabledProperty, value);
|
||||
}
|
||||
|
||||
internal bool IsWaveAnimationEnabled
|
||||
{
|
||||
get => GetValue(IsWaveAnimationEnabledProperty);
|
||||
set => SetValue(IsWaveAnimationEnabledProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -157,16 +176,21 @@ internal class CountBadgeAdorner : TemplatedControl
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
TokenResourceBinder.CreateTokenBinding(this, BadgeShadowSizeProperty, BadgeTokenKey.BadgeShadowSize);
|
||||
TokenResourceBinder.CreateTokenBinding(this, BadgeShadowColorProperty, BadgeTokenKey.BadgeShadowColor);
|
||||
TokenResourceBinder.CreateTokenBinding(this, MotionDurationProperty, SharedTokenKey.MotionDurationMid);
|
||||
TokenResourceBinder.CreateTokenBinding(this, BadgeColorProperty, BadgeTokenKey.BadgeColor);
|
||||
_indicatorMotionActor = e.NameScope.Get<MotionActorControl>(CountBadgeAdornerTheme.IndicatorMotionActorPart);
|
||||
if (_needInitialHide)
|
||||
{
|
||||
_indicatorMotionActor.IsVisible = false;
|
||||
_needInitialHide = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
TokenResourceBinder.CreateTokenBinding(this, BadgeShadowSizeProperty, BadgeTokenKey.BadgeShadowSize);
|
||||
TokenResourceBinder.CreateTokenBinding(this, BadgeShadowColorProperty, BadgeTokenKey.BadgeShadowColor);
|
||||
TokenResourceBinder.CreateTokenBinding(this, MotionDurationProperty, SharedTokenKey.MotionDurationMid);
|
||||
TokenResourceBinder.CreateTokenBinding(this, BadgeColorProperty, BadgeTokenKey.BadgeColor);
|
||||
BuildBoxShadow();
|
||||
BuildCountText();
|
||||
}
|
||||
@@ -267,10 +291,20 @@ internal class CountBadgeAdorner : TemplatedControl
|
||||
adornerLayer.Children.Add(this);
|
||||
}
|
||||
|
||||
_motionCancellationTokenSource?.Cancel();
|
||||
_motionCancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
ApplyShowMotion();
|
||||
if (IsMotionEnabled)
|
||||
{
|
||||
_motionCancellationTokenSource?.Cancel();
|
||||
_motionCancellationTokenSource = new CancellationTokenSource();
|
||||
ApplyShowMotion();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_indicatorMotionActor is not null)
|
||||
{
|
||||
_indicatorMotionActor.IsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal void DetachFromTarget(AdornerLayer? adornerLayer, bool enableMotion = true)
|
||||
|
||||
Reference in New Issue
Block a user