using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Media; using Avalonia.Styling; using Ursa.Common; namespace Ursa.Controls; [TemplatePart(PART_BadgeContainer, typeof(Border))] public class Badge : HeaderedContentControl { public const string PART_ContentPresenter = "PART_ContentPresenter"; public const string PART_BadgeContainer = "PART_BadgeContainer"; public const string PART_HeaderPresenter = "PART_HeaderPresenter"; private Border? _badgeContainer; public static readonly StyledProperty BadgeThemeProperty = AvaloniaProperty.Register(nameof(BadgeTheme)); public ControlTheme BadgeTheme { get => GetValue(BadgeThemeProperty); set => SetValue(BadgeThemeProperty, value); } public static readonly StyledProperty DotProperty = AvaloniaProperty.Register(nameof(Dot)); public bool Dot { get => GetValue(DotProperty); set => SetValue(DotProperty, value); } public static readonly StyledProperty CornerPositionProperty = AvaloniaProperty.Register(nameof(CornerPosition)); public CornerPosition CornerPosition { get => GetValue(CornerPositionProperty); set => SetValue(CornerPositionProperty, value); } public static readonly StyledProperty OverflowCountProperty = AvaloniaProperty.Register(nameof(OverflowCount)); public int OverflowCount { get => GetValue(OverflowCountProperty); set => SetValue(OverflowCountProperty, value); } public static readonly StyledProperty BadgeFontSizeProperty = AvaloniaProperty.Register(nameof(BadgeFontSize)); public double BadgeFontSize { get => GetValue(BadgeFontSizeProperty); set => SetValue(BadgeFontSizeProperty, value); } static Badge() { CornerPositionProperty.Changed.AddClassHandler((badge, _) => badge.UpdateBadgePosition()); DotProperty.Changed.AddClassHandler((badge, _) => badge.UpdateBadgePosition()); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); _badgeContainer = e.NameScope.Find(PART_BadgeContainer); _badgeContainer?.AddHandler(SizeChangedEvent, (_, _) => UpdateBadgePosition()); } private void UpdateBadgePosition() { var vertical = CornerPosition is CornerPosition.BottomLeft or CornerPosition.BottomRight ? 1 : -1; var horizontal = CornerPosition is CornerPosition.TopRight or CornerPosition.BottomRight ? 1 : -1; if (_badgeContainer is not null && Presenter?.Child is not null) { _badgeContainer.RenderTransform = new TransformGroup { Children = [ new TranslateTransform( horizontal * _badgeContainer.Bounds.Width / 2, vertical * _badgeContainer.Bounds.Height / 2) ] }; } } }