From e4ef5a9b59367eae00527bbaa7b501d63deef1e1 Mon Sep 17 00:00:00 2001 From: polarboy Date: Mon, 22 Jul 2024 11:49:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=20DotBadge=20=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AtomUI.Controls/Badge/CountBadge.cs | 70 +++-- .../Badge/CountBadgeAdorner.cs | 58 ++-- .../Badge/CountBadgeProperties.cs | 17 -- src/AtomUI.Controls/Badge/DotBadge.cs | 84 +++--- src/AtomUI.Controls/Badge/DotBadgeAdorner.cs | 268 ++++++++++-------- .../Badge/DotBadgeAdornerProperties.cs | 90 ------ .../Badge/DotBadgeProperties.cs | 17 -- 7 files changed, 260 insertions(+), 344 deletions(-) delete mode 100644 src/AtomUI.Controls/Badge/CountBadgeProperties.cs delete mode 100644 src/AtomUI.Controls/Badge/DotBadgeAdornerProperties.cs delete mode 100644 src/AtomUI.Controls/Badge/DotBadgeProperties.cs diff --git a/src/AtomUI.Controls/Badge/CountBadge.cs b/src/AtomUI.Controls/Badge/CountBadge.cs index 6d78aa2..fb8b0d5 100644 --- a/src/AtomUI.Controls/Badge/CountBadge.cs +++ b/src/AtomUI.Controls/Badge/CountBadge.cs @@ -49,6 +49,10 @@ public partial class CountBadge : Control, IControlCustomStyle public static readonly StyledProperty BadgeIsVisibleProperty = AvaloniaProperty.Register(nameof(BadgeIsVisible)); + internal static readonly StyledProperty MotionDurationProperty = + AvaloniaProperty.Register( + nameof(MotionDuration)); + public string? BadgeColor { get => GetValue(BadgeColorProperty); @@ -98,7 +102,12 @@ public partial class CountBadge : Control, IControlCustomStyle set => SetValue(BadgeIsVisibleProperty, value); } - private bool _initialized = false; + public TimeSpan MotionDuration + { + get => GetValue(MotionDurationProperty); + set => SetValue(MotionDurationProperty, value); + } + private IControlCustomStyle _customStyle; private CountBadgeAdorner? _badgeAdorner; private AdornerLayer? _adornerLayer; @@ -118,38 +127,37 @@ public partial class CountBadge : Control, IControlCustomStyle AffectsRender(BadgeColorProperty, OffsetProperty); } - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) + public sealed override void ApplyTemplate() { - base.OnAttachedToLogicalTree(e); - if (!_initialized) { - _customStyle.HandleAttachedToLogicalTree(e); - _initialized = true; - } + base.ApplyTemplate(); + CreateBadgeAdorner(); } - void IControlCustomStyle.HandleAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) + private void CreateBadgeAdorner() { - _badgeAdorner = new CountBadgeAdorner(); - _customStyle.SetupTokenBindings(); - HandleDecoratedTargetChanged(); - if (BadgeColor is not null) { - SetupBadgeColor(BadgeColor); + if (_badgeAdorner is null) { + _badgeAdorner = new CountBadgeAdorner(); + _customStyle.SetupTokenBindings(); + HandleDecoratedTargetChanged(); + if (BadgeColor is not null) { + SetupBadgeColor(BadgeColor); + } } } private void PrepareAdorner() { - if (_adornerLayer is null && - DecoratedTarget is not null && - _badgeAdorner is not null) { + if (_adornerLayer is null && DecoratedTarget is not null) { + CreateBadgeAdorner(); + var badgeAdorner = _badgeAdorner!; _adornerLayer = AdornerLayer.GetAdornerLayer(this); // 这里需要抛出异常吗? if (_adornerLayer == null) { return; } - AdornerLayer.SetAdornedElement(_badgeAdorner, this); - AdornerLayer.SetIsClipEnabled(_badgeAdorner, false); - _adornerLayer.Children.Add(_badgeAdorner); + AdornerLayer.SetAdornedElement(badgeAdorner, this); + AdornerLayer.SetIsClipEnabled(badgeAdorner, false); + _adornerLayer.Children.Add(badgeAdorner); } } @@ -167,14 +175,14 @@ public partial class CountBadge : Control, IControlCustomStyle var adorner = _badgeAdorner!; if (DecoratedTarget is not null) { var countBadgeZoomBadgeIn = new CountBadgeZoomBadgeIn(); - countBadgeZoomBadgeIn.ConfigureOpacity(_motionDurationSlow); - countBadgeZoomBadgeIn.ConfigureRenderTransform(_motionDurationSlow); + countBadgeZoomBadgeIn.ConfigureOpacity(MotionDuration); + countBadgeZoomBadgeIn.ConfigureRenderTransform(MotionDuration); motion = countBadgeZoomBadgeIn; adorner.AnimationRenderTransformOrigin = motion.MotionRenderTransformOrigin; } else { var countBadgeNoWrapperZoomBadgeIn = new CountBadgeNoWrapperZoomBadgeIn(); - countBadgeNoWrapperZoomBadgeIn.ConfigureOpacity(_motionDurationSlow); - countBadgeNoWrapperZoomBadgeIn.ConfigureRenderTransform(_motionDurationSlow); + countBadgeNoWrapperZoomBadgeIn.ConfigureOpacity(MotionDuration); + countBadgeNoWrapperZoomBadgeIn.ConfigureRenderTransform(MotionDuration); motion = countBadgeNoWrapperZoomBadgeIn; } @@ -209,14 +217,14 @@ public partial class CountBadge : Control, IControlCustomStyle var adorner = _badgeAdorner!; if (DecoratedTarget is not null) { var countBadgeZoomBadgeOut = new CountBadgeZoomBadgeOut(); - countBadgeZoomBadgeOut.ConfigureOpacity(_motionDurationSlow); - countBadgeZoomBadgeOut.ConfigureRenderTransform(_motionDurationSlow); + countBadgeZoomBadgeOut.ConfigureOpacity(MotionDuration); + countBadgeZoomBadgeOut.ConfigureRenderTransform(MotionDuration); motion = countBadgeZoomBadgeOut; adorner.AnimationRenderTransformOrigin = motion.MotionRenderTransformOrigin; } else { var countBadgeNoWrapperZoomBadgeOut = new CountBadgeNoWrapperZoomBadgeOut(); - countBadgeNoWrapperZoomBadgeOut.ConfigureOpacity(_motionDurationSlow); - countBadgeNoWrapperZoomBadgeOut.ConfigureRenderTransform(_motionDurationSlow); + countBadgeNoWrapperZoomBadgeOut.ConfigureOpacity(MotionDuration); + countBadgeNoWrapperZoomBadgeOut.ConfigureRenderTransform(MotionDuration); motion = countBadgeNoWrapperZoomBadgeOut; } @@ -251,20 +259,20 @@ public partial class CountBadge : Control, IControlCustomStyle BindUtils.RelayBind(this, OverflowCountProperty, _badgeAdorner, CountBadgeAdorner.OverflowCountProperty); BindUtils.RelayBind(this, CountProperty, _badgeAdorner, CountBadgeAdorner.CountProperty); } - BindUtils.CreateTokenBinding(this, MotionDurationSlowTokenProperty, GlobalResourceKey.MotionDurationSlow); + BindUtils.CreateTokenBinding(this, MotionDurationProperty, GlobalResourceKey.MotionDurationSlow); } private void HandleDecoratedTargetChanged() { if (_badgeAdorner is not null) { if (DecoratedTarget is null) { + ((ISetLogicalParent)_badgeAdorner).SetParent(this); VisualChildren.Add(_badgeAdorner); - LogicalChildren.Add(_badgeAdorner); _badgeAdorner.IsAdornerMode = false; } else if (DecoratedTarget is not null) { _badgeAdorner.IsAdornerMode = true; + ((ISetLogicalParent)DecoratedTarget).SetParent(this); VisualChildren.Add(DecoratedTarget); - LogicalChildren.Add(DecoratedTarget); } } } @@ -293,7 +301,7 @@ public partial class CountBadge : Control, IControlCustomStyle HideAdornerWithMotion(); } } - if (_initialized) { + if (VisualRoot is not null) { if (e.Property == DecoratedTargetProperty) { HandleDecoratedTargetChanged(); } diff --git a/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs b/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs index 24a27fc..cd14512 100644 --- a/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs +++ b/src/AtomUI.Controls/Badge/CountBadgeAdorner.cs @@ -1,8 +1,6 @@ using System.Globalization; -using AtomUI.Data; using AtomUI.Media; using AtomUI.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Documents; @@ -14,7 +12,7 @@ using Avalonia.Styling; namespace AtomUI.Controls; -internal partial class CountBadgeAdorner : Control, IControlCustomStyle +internal class CountBadgeAdorner : Control, IControlCustomStyle { public static readonly StyledProperty BadgeColorProperty = AvaloniaProperty.Register( @@ -38,22 +36,22 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle internal static readonly StyledProperty FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(); - + internal static readonly StyledProperty TextFontWeightProperty = TextElement.FontWeightProperty.AddOwner(); - + internal static readonly StyledProperty BadgeShadowColorProperty = AvaloniaProperty.Register( nameof(BadgeShadowColor)); - + internal static readonly StyledProperty BadgeShadowSizeProperty = AvaloniaProperty.Register( nameof(BadgeShadowSize)); - + internal static readonly StyledProperty PaddingInlineProperty = AvaloniaProperty.Register( nameof(PaddingInline)); - + public IBrush? BadgeColor { get => GetValue(BadgeColorProperty); @@ -83,51 +81,59 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle get => GetValue(CountProperty); set => SetValue(CountProperty, value); } - + internal FontFamily FontFamily { get => GetValue(FontFamilyProperty); set => SetValue(FontFamilyProperty, value); } - + internal FontWeight TextFontWeight { get => GetValue(TextFontWeightProperty); set => SetValue(TextFontWeightProperty, value); } - + internal IBrush? BadgeShadowColor { get => GetValue(BadgeShadowColorProperty); set => SetValue(BadgeShadowColorProperty, value); } - + internal double BadgeShadowSize { get => GetValue(BadgeShadowSizeProperty); set => SetValue(BadgeShadowSizeProperty, value); } - + internal double PaddingInline { get => GetValue(PaddingInlineProperty); set => SetValue(PaddingInlineProperty, value); } - internal bool IsAdornerMode { get; set; } + internal static readonly DirectProperty IsAdornerModeProperty = + AvaloniaProperty.RegisterDirect( + nameof(IsAdornerMode), + o => o.IsAdornerMode, + (o, v) => o.IsAdornerMode = v); - public static readonly DirectProperty OffsetProperty = - AvaloniaProperty.RegisterDirect( - nameof(Offset), - o => o.Offset, - (o, v) => o.Offset = v); + private bool _isAdornerMode = false; - private Point _offset; + internal bool IsAdornerMode + { + get => _isAdornerMode; + set => SetAndRaise(IsAdornerModeProperty, ref _isAdornerMode, value); + } + + internal static readonly StyledProperty OffsetProperty = + AvaloniaProperty.Register( + nameof(Offset)); public Point Offset { - get => _offset; - set => SetAndRaise(OffsetProperty, ref _offset, value); + get => GetValue(OffsetProperty); + set => SetValue(OffsetProperty, value); } public static readonly DirectProperty OverflowCountProperty = @@ -166,7 +172,8 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle { AffectsMeasure(OverflowCountProperty, SizeProperty, - CountProperty); + CountProperty, + IsAdornerModeProperty); AffectsRender(BadgeColorProperty, OffsetProperty); } @@ -201,18 +208,17 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle commonStyle.Add(BadgeTextColorProperty, BadgeResourceKey.BadgeTextColor); commonStyle.Add(PaddingInlineProperty, GlobalResourceKey.PaddingXS); Styles.Add(commonStyle); - + var defaultSizeStyle = new Style(selector => selector.PropertyEquals(SizeProperty, CountBadgeSize.Default)); defaultSizeStyle.Add(TextFontSizeProperty, BadgeResourceKey.TextFontSize); defaultSizeStyle.Add(IndicatorHeightProperty, BadgeResourceKey.IndicatorHeight); Styles.Add(defaultSizeStyle); - + var smallSizeStyle = new Style(selector => selector.PropertyEquals(SizeProperty, CountBadgeSize.Small)); smallSizeStyle.Add(TextFontSizeProperty, BadgeResourceKey.TextFontSizeSM); smallSizeStyle.Add(IndicatorHeightProperty, BadgeResourceKey.IndicatorHeightSM); Styles.Add(smallSizeStyle); - } public override void ApplyTemplate() diff --git a/src/AtomUI.Controls/Badge/CountBadgeProperties.cs b/src/AtomUI.Controls/Badge/CountBadgeProperties.cs deleted file mode 100644 index ca5e6ad..0000000 --- a/src/AtomUI.Controls/Badge/CountBadgeProperties.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Avalonia; - -namespace AtomUI.Controls; - -public partial class CountBadge -{ - #region Control token 值绑定属性定义 - private TimeSpan _motionDurationSlow; - - private static readonly DirectProperty MotionDurationSlowTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_motionDurationSlow), - o => o._motionDurationSlow, - (o, v) => o._motionDurationSlow = v); - - #endregion -} \ No newline at end of file diff --git a/src/AtomUI.Controls/Badge/DotBadge.cs b/src/AtomUI.Controls/Badge/DotBadge.cs index 606a54d..8bf04bc 100644 --- a/src/AtomUI.Controls/Badge/DotBadge.cs +++ b/src/AtomUI.Controls/Badge/DotBadge.cs @@ -46,6 +46,10 @@ public partial class DotBadge : Control, IControlCustomStyle public static readonly StyledProperty BadgeIsVisibleProperty = AvaloniaProperty.Register(nameof(BadgeIsVisible)); + internal static readonly StyledProperty MotionDurationProperty = + AvaloniaProperty.Register( + nameof(MotionDuration)); + public string? DotColor { get => GetValue(DotColorProperty); @@ -83,6 +87,12 @@ public partial class DotBadge : Control, IControlCustomStyle set => SetValue(BadgeIsVisibleProperty, value); } + public TimeSpan MotionDuration + { + get => GetValue(MotionDurationProperty); + set => SetValue(MotionDurationProperty, value); + } + private bool _initialized = false; private IControlCustomStyle _customStyle; private DotBadgeAdorner? _dotBadgeAdorner; @@ -96,19 +106,9 @@ public partial class DotBadge : Control, IControlCustomStyle static DotBadge() { - AffectsMeasure(DecoratedTargetProperty, - TextProperty); + AffectsMeasure(DecoratedTargetProperty, TextProperty); AffectsRender(DotColorProperty, StatusProperty); } - - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - base.OnAttachedToLogicalTree(e); - if (!_initialized) { - _customStyle.SetupUI(); - _initialized = true; - } - } protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { @@ -116,19 +116,31 @@ public partial class DotBadge : Control, IControlCustomStyle PrepareAdorner(); } + private void CreateDotBadgeAdorner() + { + if (_dotBadgeAdorner is null) { + _dotBadgeAdorner = new DotBadgeAdorner(); + _customStyle.SetupTokenBindings(); + HandleDecoratedTargetChanged(); + if (DotColor is not null) { + SetupDotColor(DotColor); + } + } + } + private void PrepareAdorner() { - if (_adornerLayer is null && - DecoratedTarget is not null && - _dotBadgeAdorner is not null) { + if (_adornerLayer is null && DecoratedTarget is not null) { + CreateDotBadgeAdorner(); + var dotBadgeAdorner = _dotBadgeAdorner!; _adornerLayer = AdornerLayer.GetAdornerLayer(this); // 这里需要抛出异常吗? if (_adornerLayer == null) { return; } - AdornerLayer.SetAdornedElement(_dotBadgeAdorner, this); - AdornerLayer.SetIsClipEnabled(_dotBadgeAdorner, false); - _adornerLayer.Children.Add(_dotBadgeAdorner); + AdornerLayer.SetAdornedElement(dotBadgeAdorner, this); + AdornerLayer.SetIsClipEnabled(dotBadgeAdorner, false); + _adornerLayer.Children.Add(dotBadgeAdorner); } } @@ -142,8 +154,8 @@ public partial class DotBadge : Control, IControlCustomStyle _animating = true; var director = Director.Instance; var motion = new CountBadgeZoomBadgeIn(); - motion.ConfigureOpacity(_motionDurationSlow); - motion.ConfigureRenderTransform(_motionDurationSlow); + motion.ConfigureOpacity(MotionDuration); + motion.ConfigureRenderTransform(MotionDuration); _dotBadgeAdorner!.AnimationRenderTransformOrigin = motion.MotionRenderTransformOrigin; var motionActor = new MotionActor(_dotBadgeAdorner, motion); motionActor.DispatchInSceneLayer = false; @@ -174,8 +186,8 @@ public partial class DotBadge : Control, IControlCustomStyle _animating = true; var director = Director.Instance; var motion = new CountBadgeZoomBadgeOut(); - motion.ConfigureOpacity(_motionDurationSlow); - motion.ConfigureRenderTransform(_motionDurationSlow); + motion.ConfigureOpacity(MotionDuration); + motion.ConfigureRenderTransform(MotionDuration); _dotBadgeAdorner!.AnimationRenderTransformOrigin = motion.MotionRenderTransformOrigin; var motionActor = new MotionActor(_dotBadgeAdorner, motion); motionActor.DispatchInSceneLayer = false; @@ -195,16 +207,6 @@ public partial class DotBadge : Control, IControlCustomStyle HideAdorner(); } - void IControlCustomStyle.SetupUI() - { - _dotBadgeAdorner = new DotBadgeAdorner(); - _customStyle.SetupTokenBindings(); - HandleDecoratedTargetChanged(); - if (DotColor is not null) { - SetupDotColor(DotColor); - } - } - void IControlCustomStyle.SetupTokenBindings() { if (_dotBadgeAdorner is not null) { @@ -212,24 +214,30 @@ public partial class DotBadge : Control, IControlCustomStyle BindUtils.RelayBind(this, TextProperty, _dotBadgeAdorner, DotBadgeAdorner.TextProperty); BindUtils.RelayBind(this, OffsetProperty, _dotBadgeAdorner, DotBadgeAdorner.OffsetProperty); } - BindUtils.CreateTokenBinding(this, MotionDurationSlowTokenProperty, GlobalResourceKey.MotionDurationSlow); + BindUtils.CreateTokenBinding(this, MotionDurationProperty, GlobalResourceKey.MotionDurationSlow); } private void HandleDecoratedTargetChanged() { if (_dotBadgeAdorner is not null) { if (DecoratedTarget is null) { - VisualChildren.Add(_dotBadgeAdorner); - LogicalChildren.Add(_dotBadgeAdorner); _dotBadgeAdorner.IsAdornerMode = false; + ((ISetLogicalParent)_dotBadgeAdorner).SetParent(this); + VisualChildren.Add(_dotBadgeAdorner); } else if (DecoratedTarget is not null) { _dotBadgeAdorner.IsAdornerMode = true; VisualChildren.Add(DecoratedTarget); - LogicalChildren.Add(DecoratedTarget); + ((ISetLogicalParent)DecoratedTarget).SetParent(this); } } } - + + public sealed override void ApplyTemplate() + { + base.ApplyTemplate(); + CreateDotBadgeAdorner(); + } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { base.OnPropertyChanged(e); @@ -281,12 +289,12 @@ public partial class DotBadge : Control, IControlCustomStyle foreach (var presetColor in PresetPrimaryColor.AllColorTypes()) { if (presetColor.Type.ToString().ToLower() == colorStr) { - _dotBadgeAdorner!.DotColor = new SolidColorBrush(presetColor.Color()); + _dotBadgeAdorner!.BadgeDotColor = new SolidColorBrush(presetColor.Color()); return; } } if (Color.TryParse(colorStr, out Color color)) { - _dotBadgeAdorner!.DotColor = new SolidColorBrush(color); + _dotBadgeAdorner!.BadgeDotColor = new SolidColorBrush(color); } } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs b/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs index c40ed46..439d93f 100644 --- a/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs +++ b/src/AtomUI.Controls/Badge/DotBadgeAdorner.cs @@ -5,24 +5,12 @@ using Avalonia.Controls; using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Media; +using Avalonia.Styling; namespace AtomUI.Controls; internal partial class DotBadgeAdorner : Control, IControlCustomStyle { - public static readonly DirectProperty DotColorProperty = - AvaloniaProperty.RegisterDirect( - nameof(DotColor), - o => o.DotColor, - (o, v) => o.DotColor = v); - - private IBrush? _dotColor; - public IBrush? DotColor - { - get => _dotColor; - set => SetAndRaise(DotColorProperty, ref _dotColor, value); - } - public static readonly DirectProperty StatusProperty = AvaloniaProperty.RegisterDirect( nameof(Status), @@ -54,7 +42,35 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle nameof(IsAdornerMode), o => o.IsAdornerMode, (o, v) => o.IsAdornerMode = v); - + + internal static readonly StyledProperty BadgeDotColorProperty = + AvaloniaProperty.Register( + nameof(BadgeDotColor)); + + internal static readonly StyledProperty DotSizeProperty = + AvaloniaProperty.Register( + nameof(DotSize)); + + internal static readonly StyledProperty StatusSizeProperty = + AvaloniaProperty.Register( + nameof(StatusSize)); + + internal static readonly StyledProperty BadgeShadowColorProperty = + AvaloniaProperty.Register( + nameof(BadgeShadowColor)); + + private static readonly StyledProperty BadgeShadowSizeProperty = + AvaloniaProperty.Register( + nameof(BadgeShadowSize)); + + private static readonly StyledProperty BadgeTextMarginInlineProperty = + AvaloniaProperty.Register( + nameof(BadgeTextMarginInline)); + + public static readonly StyledProperty OffsetProperty = + AvaloniaProperty.Register( + nameof(Offset)); + private bool _isAdornerMode = false; public bool IsAdornerMode { @@ -62,33 +78,46 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle set => SetAndRaise(IsAdornerModeProperty, ref _isAdornerMode, value); } - public static readonly DirectProperty EffectiveDotColorProperty = - AvaloniaProperty.RegisterDirect( - nameof(EffectiveDotColor), - o => o.EffectiveDotColor, - (o, v) => o.EffectiveDotColor = v); - - private IBrush? _effectiveDotColor; - - // 当前有效的颜色 - public IBrush? EffectiveDotColor - { - get => _effectiveDotColor; - set => SetAndRaise(EffectiveDotColorProperty, ref _effectiveDotColor, value); - } - - public static readonly DirectProperty OffsetProperty = - AvaloniaProperty.RegisterDirect( - nameof(Offset), - o => o.Offset, - (o, v) => o.Offset = v); - - private Point _offset; - public Point Offset { - get => _offset; - set => SetAndRaise(OffsetProperty, ref _offset, value); + get => GetValue(OffsetProperty); + set => SetValue(OffsetProperty,value); + } + + public double DotSize + { + get => GetValue(DotSizeProperty); + set => SetValue(DotSizeProperty, value); + } + + public double StatusSize + { + get => GetValue(StatusSizeProperty); + set => SetValue(StatusSizeProperty, value); + } + + internal IBrush? BadgeDotColor + { + get => GetValue(BadgeDotColorProperty); + set => SetValue(BadgeDotColorProperty, value); + } + + internal IBrush? BadgeShadowColor + { + get => GetValue(BadgeShadowColorProperty); + set => SetValue(BadgeShadowColorProperty, value); + } + + public double BadgeShadowSize + { + get => GetValue(BadgeShadowSizeProperty); + set => SetValue(BadgeShadowSizeProperty, value); + } + + public double BadgeTextMarginInline + { + get => GetValue(BadgeTextMarginInlineProperty); + set => SetValue(BadgeTextMarginInlineProperty, value); } private bool _initialized = false; @@ -102,84 +131,79 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle static DotBadgeAdorner() { AffectsMeasure(TextProperty, IsAdornerModeProperty); - AffectsRender(EffectiveDotColorProperty, OffsetProperty); + AffectsRender(BadgeDotColorProperty, OffsetProperty); } public DotBadgeAdorner() { _customStyle = this; } - - void IControlCustomStyle.SetupUI() - { - _textLabel = new Label - { - Content = Text, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Center, - HorizontalContentAlignment = HorizontalAlignment.Center, - VerticalContentAlignment = VerticalAlignment.Center, - Padding = new Thickness(0), - }; - - LogicalChildren.Add(_textLabel); - VisualChildren.Add(_textLabel); - _customStyle.SetupTokenBindings(); - SetupEffectiveDotColor(); - BuildBoxShadow(); - } - void IControlCustomStyle.SetupTokenBindings() + public sealed override void ApplyTemplate() { - BindUtils.CreateTokenBinding(this, ColorTextPlaceholderTokenProperty, GlobalResourceKey.ColorTextPlaceholder); - BindUtils.CreateTokenBinding(this, ColorErrorTokenProperty, GlobalResourceKey.ColorError); - BindUtils.CreateTokenBinding(this, ColorWarningTokenProperty, GlobalResourceKey.ColorWarning); - BindUtils.CreateTokenBinding(this, ColorSuccessTokenProperty, GlobalResourceKey.ColorSuccess); - BindUtils.CreateTokenBinding(this, ColorInfoTokenProperty, GlobalResourceKey.ColorInfo); - BindUtils.CreateTokenBinding(this, MarginXSTokenProperty, GlobalResourceKey.MarginXS); - - BindUtils.CreateTokenBinding(this, DotSizeTokenProperty, BadgeResourceKey.DotSize); - BindUtils.CreateTokenBinding(this, StatusSizeTokenProperty, BadgeResourceKey.StatusSize); - BindUtils.CreateTokenBinding(this, BadgeColorTokenProperty, BadgeResourceKey.BadgeColor); - BindUtils.CreateTokenBinding(this, BadgeShadowSizeTokenProperty, BadgeResourceKey.BadgeShadowSize); - BindUtils.CreateTokenBinding(this, BadgeShadowColorTokenProperty, BadgeResourceKey.BadgeShadowColor); - } - - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - base.OnAttachedToLogicalTree(e); + base.ApplyTemplate(); if (!_initialized) { - _customStyle.SetupUI(); + _textLabel = new Label + { + Content = Text, + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Center, + HorizontalContentAlignment = HorizontalAlignment.Center, + VerticalContentAlignment = VerticalAlignment.Center, + Padding = new Thickness(0), + }; + + ((ISetLogicalParent)_textLabel).SetParent(this); + VisualChildren.Add(_textLabel); + BuildBoxShadow(); _initialized = true; } } - private IBrush? GetStatusColor(DotBadgeStatus status) + protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { - if (status == DotBadgeStatus.Error) { - return _colorErrorToken; - } else if (status == DotBadgeStatus.Processing) { - return _colorInfoToken; - } else if (status == DotBadgeStatus.Success) { - return _colorSuccessToken; - } else if (status == DotBadgeStatus.Warning) { - return _colorWarningToken; - } else { - return _colorTextPlaceholderToken; + base.OnAttachedToLogicalTree(e); + _customStyle.BuildStyles(); + } + + void IControlCustomStyle.BuildStyles() + { + if (Styles.Count == 0) { + BuildBadgeColorStyle(); } } - private void SetupEffectiveDotColor() + private void BuildBadgeColorStyle() { - if (_dotColor is not null) { - EffectiveDotColor = _dotColor; - } else if (Status.HasValue) { - EffectiveDotColor = GetStatusColor(Status.Value); - } + var commonStyle = new Style(selector => selector.OfType()); + commonStyle.Add(BadgeTextMarginInlineProperty, GlobalResourceKey.MarginXS); + commonStyle.Add(BadgeDotColorProperty, BadgeResourceKey.BadgeColor); + commonStyle.Add(DotSizeProperty, BadgeResourceKey.DotSize); + commonStyle.Add(StatusSizeProperty, BadgeResourceKey.StatusSize); + commonStyle.Add(BadgeShadowSizeProperty, BadgeResourceKey.BadgeShadowSize); + commonStyle.Add(BadgeShadowColorProperty, BadgeResourceKey.BadgeShadowColor); - if (EffectiveDotColor is null) { - EffectiveDotColor = _badgeColorToken; - } + var errorStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(DotBadgeAdorner.StatusProperty, DotBadgeStatus.Error)); + errorStatusStyle.Add(DotBadgeAdorner.BadgeDotColorProperty, GlobalResourceKey.ColorError); + commonStyle.Add(errorStatusStyle); + + var successStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(DotBadgeAdorner.StatusProperty, DotBadgeStatus.Success)); + successStatusStyle.Add(DotBadgeAdorner.BadgeDotColorProperty, GlobalResourceKey.ColorSuccess); + commonStyle.Add(successStatusStyle); + + var warningStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(DotBadgeAdorner.StatusProperty, DotBadgeStatus.Warning)); + warningStatusStyle.Add(DotBadgeAdorner.BadgeDotColorProperty, GlobalResourceKey.ColorWarning); + commonStyle.Add(warningStatusStyle); + + var defaultStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(DotBadgeAdorner.StatusProperty, DotBadgeStatus.Default)); + defaultStatusStyle.Add(DotBadgeAdorner.BadgeDotColorProperty, GlobalResourceKey.ColorTextPlaceholder); + commonStyle.Add(defaultStatusStyle); + + var processingStatusStyle = new Style(selector => selector.Nesting().PropertyEquals(DotBadgeAdorner.StatusProperty, DotBadgeStatus.Processing)); + processingStatusStyle.Add(DotBadgeAdorner.BadgeDotColorProperty, GlobalResourceKey.ColorInfo); + commonStyle.Add(processingStatusStyle); + + Styles.Add(commonStyle); } protected override Size MeasureOverride(Size availableSize) @@ -191,11 +215,11 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle targetHeight = availableSize.Height; } else { var textSize = base.MeasureOverride(availableSize); - targetWidth += _statusSizeToken; + targetWidth += StatusSize; targetWidth += textSize.Width; - targetHeight += Math.Max(textSize.Height, _statusSizeToken); + targetHeight += Math.Max(textSize.Height, StatusSize); if (textSize.Width > 0) { - targetWidth += _marginXSToken; + targetWidth += BadgeTextMarginInline; } } return new Size(targetWidth, targetHeight); @@ -206,12 +230,12 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle if (!IsAdornerMode) { double textOffsetX = 0; if (IsAdornerMode) { - textOffsetX += _dotSizeToken; + textOffsetX += DotSize; } else { - textOffsetX += _statusSizeToken; + textOffsetX += StatusSize; } - textOffsetX += _marginXSToken; + textOffsetX += BadgeTextMarginInline; var textRect = new Rect(new Point(textOffsetX, 0), _textLabel!.DesiredSize); _textLabel.Arrange(textRect); } @@ -226,26 +250,19 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle if (_textLabel is not null) { _textLabel.IsVisible = !newValue; } - } else if (e.Property == BadgeShadowSizeTokenProperty || - e.Property == BadgeShadowColorTokenProperty) { + } else if (e.Property == BadgeShadowSizeProperty || + e.Property == BadgeShadowColorProperty) { BuildBoxShadow(); } - - if (_initialized) { - if (e.Property == StatusProperty || - e.Property == DotColorProperty) { - SetupEffectiveDotColor(); - } - } } public override void Render(DrawingContext context) { var dotSize = 0d; if (IsAdornerMode) { - dotSize = _dotSizeToken; + dotSize = DotSize; } else { - dotSize = _statusSizeToken; + dotSize = StatusSize; } var offsetX = 0d; @@ -273,19 +290,20 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle var renderTransform = (-offset) * RenderTransform.Value * (offset); context.PushTransform(renderTransform); } - - context.DrawRectangle(EffectiveDotColor, null, dotRect, dotSize, dotSize, _boxShadows); + context.DrawRectangle(BadgeDotColor, null, dotRect, dotSize, dotSize, _boxShadows); } private void BuildBoxShadow() { - _boxShadows = new BoxShadows(new BoxShadow() - { - OffsetX = 0, - OffsetY = 0, - Blur = 0, - Spread = _badgeShadowSizeToken, - Color = ((SolidColorBrush)_badgeShadowColorToken!).Color - }); + if (IsSet(BadgeShadowSizeProperty) && IsSet(BadgeShadowColorProperty)) { + _boxShadows = new BoxShadows(new BoxShadow() + { + OffsetX = 0, + OffsetY = 0, + Blur = 0, + Spread = BadgeShadowSize, + Color = ((SolidColorBrush)BadgeShadowColor!).Color + }); + } } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Badge/DotBadgeAdornerProperties.cs b/src/AtomUI.Controls/Badge/DotBadgeAdornerProperties.cs deleted file mode 100644 index 9418d91..0000000 --- a/src/AtomUI.Controls/Badge/DotBadgeAdornerProperties.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Avalonia; -using Avalonia.Media; - -namespace AtomUI.Controls; - -internal partial class DotBadgeAdorner -{ - #region Control token 值绑定属性定义 - private IBrush? _colorTextPlaceholderToken; - - private static readonly DirectProperty ColorTextPlaceholderTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_colorTextPlaceholderToken), - o => o._colorTextPlaceholderToken, - (o, v) => o._colorTextPlaceholderToken = v); - - private IBrush? _colorErrorToken; - - private static readonly DirectProperty ColorErrorTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_colorErrorToken), - o => o._colorErrorToken, - (o, v) => o._colorErrorToken = v); - - private IBrush? _colorWarningToken; - private static readonly DirectProperty ColorWarningTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_colorWarningToken), - o => o._colorWarningToken, - (o, v) => o._colorWarningToken = v); - - private IBrush? _colorSuccessToken; - private static readonly DirectProperty ColorSuccessTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_colorSuccessToken), - o => o._colorSuccessToken, - (o, v) => o._colorSuccessToken = v); - - private IBrush? _colorInfoToken; - private static readonly DirectProperty ColorInfoTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_colorInfoToken), - o => o._colorInfoToken, - (o, v) => o._colorInfoToken = v); - - private double _dotSizeToken; - private static readonly DirectProperty DotSizeTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_dotSizeToken), - o => o._dotSizeToken, - (o, v) => o._dotSizeToken = v); - - private double _statusSizeToken; - private static readonly DirectProperty StatusSizeTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_statusSizeToken), - o => o._statusSizeToken, - (o, v) => o._statusSizeToken = v); - - private double _marginXSToken; - private static readonly DirectProperty MarginXSTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_marginXSToken), - o => o._marginXSToken, - (o, v) => o._marginXSToken = v); - - private IBrush? _badgeColorToken; - private static readonly DirectProperty BadgeColorTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_badgeColorToken), - o => o._badgeColorToken, - (o, v) => o._badgeColorToken = v); - - private IBrush? _badgeShadowColorToken; - private static readonly DirectProperty BadgeShadowColorTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_badgeShadowColorToken), - o => o._badgeShadowColorToken, - (o, v) => o._badgeShadowColorToken = v); - - - private double _badgeShadowSizeToken; - private static readonly DirectProperty BadgeShadowSizeTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_badgeShadowSizeToken), - o => o._badgeShadowSizeToken, - (o, v) => o._badgeShadowSizeToken = v); - - #endregion -} \ No newline at end of file diff --git a/src/AtomUI.Controls/Badge/DotBadgeProperties.cs b/src/AtomUI.Controls/Badge/DotBadgeProperties.cs deleted file mode 100644 index d64c0a0..0000000 --- a/src/AtomUI.Controls/Badge/DotBadgeProperties.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Avalonia; - -namespace AtomUI.Controls; - -public partial class DotBadge -{ - #region Control token 值绑定属性定义 - private TimeSpan _motionDurationSlow; - - private static readonly DirectProperty MotionDurationSlowTokenProperty = - AvaloniaProperty.RegisterDirect( - nameof(_motionDurationSlow), - o => o._motionDurationSlow, - (o, v) => o._motionDurationSlow = v); - - #endregion -} \ No newline at end of file