mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-30 02:47:45 +08:00
完成 DotBadge 改造
This commit is contained in:
parent
fa9c19574a
commit
e4ef5a9b59
@ -49,6 +49,10 @@ public partial class CountBadge : Control, IControlCustomStyle
|
||||
public static readonly StyledProperty<bool> BadgeIsVisibleProperty =
|
||||
AvaloniaProperty.Register<CountBadge, bool>(nameof(BadgeIsVisible));
|
||||
|
||||
internal static readonly StyledProperty<TimeSpan> MotionDurationProperty =
|
||||
AvaloniaProperty.Register<CountBadge, TimeSpan>(
|
||||
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,17 +127,15 @@ public partial class CountBadge : Control, IControlCustomStyle
|
||||
AffectsRender<CountBadge>(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()
|
||||
{
|
||||
if (_badgeAdorner is null) {
|
||||
_badgeAdorner = new CountBadgeAdorner();
|
||||
_customStyle.SetupTokenBindings();
|
||||
HandleDecoratedTargetChanged();
|
||||
@ -136,20 +143,21 @@ public partial class CountBadge : Control, IControlCustomStyle
|
||||
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();
|
||||
}
|
||||
|
@ -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<IBrush?> BadgeColorProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, IBrush?>(
|
||||
@ -114,20 +112,28 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle
|
||||
set => SetValue(PaddingInlineProperty, value);
|
||||
}
|
||||
|
||||
internal bool IsAdornerMode { get; set; }
|
||||
internal static readonly DirectProperty<DotBadgeAdorner, bool> IsAdornerModeProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, bool>(
|
||||
nameof(IsAdornerMode),
|
||||
o => o.IsAdornerMode,
|
||||
(o, v) => o.IsAdornerMode = v);
|
||||
|
||||
public static readonly DirectProperty<CountBadgeAdorner, Point> OffsetProperty =
|
||||
AvaloniaProperty.RegisterDirect<CountBadgeAdorner, Point>(
|
||||
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<Point> OffsetProperty =
|
||||
AvaloniaProperty.Register<CountBadgeAdorner, Point>(
|
||||
nameof(Offset));
|
||||
|
||||
public Point Offset
|
||||
{
|
||||
get => _offset;
|
||||
set => SetAndRaise(OffsetProperty, ref _offset, value);
|
||||
get => GetValue(OffsetProperty);
|
||||
set => SetValue(OffsetProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DirectProperty<CountBadgeAdorner, int> OverflowCountProperty =
|
||||
@ -166,7 +172,8 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle
|
||||
{
|
||||
AffectsMeasure<CountBadgeAdorner>(OverflowCountProperty,
|
||||
SizeProperty,
|
||||
CountProperty);
|
||||
CountProperty,
|
||||
IsAdornerModeProperty);
|
||||
AffectsRender<CountBadgeAdorner>(BadgeColorProperty, OffsetProperty);
|
||||
}
|
||||
|
||||
@ -212,7 +219,6 @@ internal partial class CountBadgeAdorner : Control, IControlCustomStyle
|
||||
smallSizeStyle.Add(TextFontSizeProperty, BadgeResourceKey.TextFontSizeSM);
|
||||
smallSizeStyle.Add(IndicatorHeightProperty, BadgeResourceKey.IndicatorHeightSM);
|
||||
Styles.Add(smallSizeStyle);
|
||||
|
||||
}
|
||||
|
||||
public override void ApplyTemplate()
|
||||
|
@ -1,17 +0,0 @@
|
||||
using Avalonia;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public partial class CountBadge
|
||||
{
|
||||
#region Control token 值绑定属性定义
|
||||
private TimeSpan _motionDurationSlow;
|
||||
|
||||
private static readonly DirectProperty<CountBadge, TimeSpan> MotionDurationSlowTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<CountBadge, TimeSpan>(
|
||||
nameof(_motionDurationSlow),
|
||||
o => o._motionDurationSlow,
|
||||
(o, v) => o._motionDurationSlow = v);
|
||||
|
||||
#endregion
|
||||
}
|
@ -46,6 +46,10 @@ public partial class DotBadge : Control, IControlCustomStyle
|
||||
public static readonly StyledProperty<bool> BadgeIsVisibleProperty =
|
||||
AvaloniaProperty.Register<DotBadge, bool>(nameof(BadgeIsVisible));
|
||||
|
||||
internal static readonly StyledProperty<TimeSpan> MotionDurationProperty =
|
||||
AvaloniaProperty.Register<CountBadge, TimeSpan>(
|
||||
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,39 +106,41 @@ public partial class DotBadge : Control, IControlCustomStyle
|
||||
|
||||
static DotBadge()
|
||||
{
|
||||
AffectsMeasure<DotBadge>(DecoratedTargetProperty,
|
||||
TextProperty);
|
||||
AffectsMeasure<DotBadge>(DecoratedTargetProperty, TextProperty);
|
||||
AffectsRender<DotBadge>(DotColorProperty, StatusProperty);
|
||||
}
|
||||
|
||||
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
if (!_initialized) {
|
||||
_customStyle.SetupUI();
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<DotBadgeAdorner, IBrush?> DotColorProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
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<DotBadgeAdorner, DotBadgeStatus?> StatusProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, DotBadgeStatus?>(
|
||||
nameof(Status),
|
||||
@ -55,6 +43,34 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle
|
||||
o => o.IsAdornerMode,
|
||||
(o, v) => o.IsAdornerMode = v);
|
||||
|
||||
internal static readonly StyledProperty<IBrush?> BadgeDotColorProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, IBrush?>(
|
||||
nameof(BadgeDotColor));
|
||||
|
||||
internal static readonly StyledProperty<double> DotSizeProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, double>(
|
||||
nameof(DotSize));
|
||||
|
||||
internal static readonly StyledProperty<double> StatusSizeProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, double>(
|
||||
nameof(StatusSize));
|
||||
|
||||
internal static readonly StyledProperty<IBrush?> BadgeShadowColorProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, IBrush?>(
|
||||
nameof(BadgeShadowColor));
|
||||
|
||||
private static readonly StyledProperty<double> BadgeShadowSizeProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, double>(
|
||||
nameof(BadgeShadowSize));
|
||||
|
||||
private static readonly StyledProperty<double> BadgeTextMarginInlineProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, double>(
|
||||
nameof(BadgeTextMarginInline));
|
||||
|
||||
public static readonly StyledProperty<Point> OffsetProperty =
|
||||
AvaloniaProperty.Register<DotBadgeAdorner, Point>(
|
||||
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<DotBadgeAdorner, IBrush?> EffectiveDotColorProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
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<DotBadgeAdorner, Point> OffsetProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, Point>(
|
||||
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,7 +131,7 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle
|
||||
static DotBadgeAdorner()
|
||||
{
|
||||
AffectsMeasure<DotBadge>(TextProperty, IsAdornerModeProperty);
|
||||
AffectsRender<DotBadge>(EffectiveDotColorProperty, OffsetProperty);
|
||||
AffectsRender<DotBadge>(BadgeDotColorProperty, OffsetProperty);
|
||||
}
|
||||
|
||||
public DotBadgeAdorner()
|
||||
@ -110,8 +139,10 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle
|
||||
_customStyle = this;
|
||||
}
|
||||
|
||||
void IControlCustomStyle.SetupUI()
|
||||
public sealed override void ApplyTemplate()
|
||||
{
|
||||
base.ApplyTemplate();
|
||||
if (!_initialized) {
|
||||
_textLabel = new Label
|
||||
{
|
||||
Content = Text,
|
||||
@ -122,64 +153,57 @@ internal partial class DotBadgeAdorner : Control, IControlCustomStyle
|
||||
Padding = new Thickness(0),
|
||||
};
|
||||
|
||||
LogicalChildren.Add(_textLabel);
|
||||
((ISetLogicalParent)_textLabel).SetParent(this);
|
||||
VisualChildren.Add(_textLabel);
|
||||
_customStyle.SetupTokenBindings();
|
||||
SetupEffectiveDotColor();
|
||||
BuildBoxShadow();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void IControlCustomStyle.SetupTokenBindings()
|
||||
{
|
||||
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);
|
||||
if (!_initialized) {
|
||||
_customStyle.SetupUI();
|
||||
_initialized = true;
|
||||
}
|
||||
_customStyle.BuildStyles();
|
||||
}
|
||||
|
||||
private IBrush? GetStatusColor(DotBadgeStatus status)
|
||||
void IControlCustomStyle.BuildStyles()
|
||||
{
|
||||
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;
|
||||
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<DotBadgeAdorner>());
|
||||
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()
|
||||
{
|
||||
if (IsSet(BadgeShadowSizeProperty) && IsSet(BadgeShadowColorProperty)) {
|
||||
_boxShadows = new BoxShadows(new BoxShadow()
|
||||
{
|
||||
OffsetX = 0,
|
||||
OffsetY = 0,
|
||||
Blur = 0,
|
||||
Spread = _badgeShadowSizeToken,
|
||||
Color = ((SolidColorBrush)_badgeShadowColorToken!).Color
|
||||
Spread = BadgeShadowSize,
|
||||
Color = ((SolidColorBrush)BadgeShadowColor!).Color
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -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<DotBadgeAdorner, IBrush?> ColorTextPlaceholderTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_colorTextPlaceholderToken),
|
||||
o => o._colorTextPlaceholderToken,
|
||||
(o, v) => o._colorTextPlaceholderToken = v);
|
||||
|
||||
private IBrush? _colorErrorToken;
|
||||
|
||||
private static readonly DirectProperty<DotBadgeAdorner, IBrush?> ColorErrorTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_colorErrorToken),
|
||||
o => o._colorErrorToken,
|
||||
(o, v) => o._colorErrorToken = v);
|
||||
|
||||
private IBrush? _colorWarningToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, IBrush?> ColorWarningTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_colorWarningToken),
|
||||
o => o._colorWarningToken,
|
||||
(o, v) => o._colorWarningToken = v);
|
||||
|
||||
private IBrush? _colorSuccessToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, IBrush?> ColorSuccessTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_colorSuccessToken),
|
||||
o => o._colorSuccessToken,
|
||||
(o, v) => o._colorSuccessToken = v);
|
||||
|
||||
private IBrush? _colorInfoToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, IBrush?> ColorInfoTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_colorInfoToken),
|
||||
o => o._colorInfoToken,
|
||||
(o, v) => o._colorInfoToken = v);
|
||||
|
||||
private double _dotSizeToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, double> DotSizeTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, double>(
|
||||
nameof(_dotSizeToken),
|
||||
o => o._dotSizeToken,
|
||||
(o, v) => o._dotSizeToken = v);
|
||||
|
||||
private double _statusSizeToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, double> StatusSizeTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, double>(
|
||||
nameof(_statusSizeToken),
|
||||
o => o._statusSizeToken,
|
||||
(o, v) => o._statusSizeToken = v);
|
||||
|
||||
private double _marginXSToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, double> MarginXSTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, double>(
|
||||
nameof(_marginXSToken),
|
||||
o => o._marginXSToken,
|
||||
(o, v) => o._marginXSToken = v);
|
||||
|
||||
private IBrush? _badgeColorToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, IBrush?> BadgeColorTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_badgeColorToken),
|
||||
o => o._badgeColorToken,
|
||||
(o, v) => o._badgeColorToken = v);
|
||||
|
||||
private IBrush? _badgeShadowColorToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, IBrush?> BadgeShadowColorTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, IBrush?>(
|
||||
nameof(_badgeShadowColorToken),
|
||||
o => o._badgeShadowColorToken,
|
||||
(o, v) => o._badgeShadowColorToken = v);
|
||||
|
||||
|
||||
private double _badgeShadowSizeToken;
|
||||
private static readonly DirectProperty<DotBadgeAdorner, double> BadgeShadowSizeTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadgeAdorner, double>(
|
||||
nameof(_badgeShadowSizeToken),
|
||||
o => o._badgeShadowSizeToken,
|
||||
(o, v) => o._badgeShadowSizeToken = v);
|
||||
|
||||
#endregion
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using Avalonia;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
public partial class DotBadge
|
||||
{
|
||||
#region Control token 值绑定属性定义
|
||||
private TimeSpan _motionDurationSlow;
|
||||
|
||||
private static readonly DirectProperty<DotBadge, TimeSpan> MotionDurationSlowTokenProperty =
|
||||
AvaloniaProperty.RegisterDirect<DotBadge, TimeSpan>(
|
||||
nameof(_motionDurationSlow),
|
||||
o => o._motionDurationSlow,
|
||||
(o, v) => o._motionDurationSlow = v);
|
||||
|
||||
#endregion
|
||||
}
|
Loading…
Reference in New Issue
Block a user