diff --git a/src/AtomUI.Controls/Badge/CountBadge.cs b/src/AtomUI.Controls/Badge/CountBadge.cs index fa72b11d2..485514780 100644 --- a/src/AtomUI.Controls/Badge/CountBadge.cs +++ b/src/AtomUI.Controls/Badge/CountBadge.cs @@ -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 BadgeIsVisibleProperty = AvaloniaProperty.Register(nameof(BadgeIsVisible), true); + public static readonly StyledProperty IsMotionEnabledProperty + = AvaloniaProperty.Register(nameof(IsMotionEnabled), true); + + public static readonly StyledProperty IsWaveAnimationEnabledProperty + = AvaloniaProperty.Register(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(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); } } diff --git a/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs b/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs index 44c0a27b4..0f1d77b62 100644 --- a/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs +++ b/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs @@ -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 SizeProperty = AvaloniaProperty.Register( nameof(Size)); - - internal static readonly StyledProperty CountProperty = - AvaloniaProperty.Register( - nameof(Count)); - - internal static readonly StyledProperty BadgeShadowColorProperty = - AvaloniaProperty.Register( - nameof(BadgeShadowColor)); - - internal static readonly StyledProperty BadgeShadowSizeProperty = - AvaloniaProperty.Register( - 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 CountProperty = + AvaloniaProperty.Register( + nameof(Count)); + + internal static readonly StyledProperty BadgeShadowColorProperty = + AvaloniaProperty.Register( + nameof(BadgeShadowColor)); + + internal static readonly StyledProperty BadgeShadowSizeProperty = + AvaloniaProperty.Register( + nameof(BadgeShadowSize)); + + internal static readonly StyledProperty IsMotionEnabledProperty + = AvaloniaProperty.Register(nameof(IsMotionEnabled), true); + + internal static readonly StyledProperty IsWaveAnimationEnabledProperty + = AvaloniaProperty.Register(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(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)