diff --git a/controlgallery/AtomUIGallery/ShowCases/Views/General/FloatButtonShowCase.axaml b/controlgallery/AtomUIGallery/ShowCases/Views/General/FloatButtonShowCase.axaml
index dcdb60c65..9ee4103db 100644
--- a/controlgallery/AtomUIGallery/ShowCases/Views/General/FloatButtonShowCase.axaml
+++ b/controlgallery/AtomUIGallery/ShowCases/Views/General/FloatButtonShowCase.axaml
@@ -9,121 +9,135 @@
Title="Basic"
Description="The most basic usage.">
-
-
-
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
-
+
-
+
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -132,74 +146,110 @@
VerticalAlignment="Top"
IsChecked="{Binding IsOpened, Mode=TwoWay}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ Description="Customize animation placement, providing four preset placement: top, right, bottom, left, the top position by default.">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AtomUI.Desktop.Controls/Badge/BadgeColorUtils.cs b/src/AtomUI.Desktop.Controls/Badge/BadgeColorUtils.cs
new file mode 100644
index 000000000..2f2d8c12e
--- /dev/null
+++ b/src/AtomUI.Desktop.Controls/Badge/BadgeColorUtils.cs
@@ -0,0 +1,30 @@
+using AtomUI.Theme.Palette;
+using Avalonia.Media;
+
+namespace AtomUI.Desktop.Controls;
+
+internal static class BadgeColorUtils
+{
+ internal static IBrush? CalculateColor(string? colorStr)
+ {
+ if (string.IsNullOrEmpty(colorStr))
+ {
+ return null;
+ }
+ colorStr = colorStr.Trim().ToLower();
+
+ foreach (var presetColor in PresetPrimaryColor.AllColorTypes())
+ {
+ if (presetColor.Type.ToString().ToLower() == colorStr)
+ {
+ return new SolidColorBrush(presetColor.Color());
+ }
+ }
+
+ if (Color.TryParse(colorStr, out var color))
+ {
+ return new SolidColorBrush(color);
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/AtomUI.Desktop.Controls/Badge/CountBadge.cs b/src/AtomUI.Desktop.Controls/Badge/CountBadge.cs
index d958ceb78..3078194ca 100644
--- a/src/AtomUI.Desktop.Controls/Badge/CountBadge.cs
+++ b/src/AtomUI.Desktop.Controls/Badge/CountBadge.cs
@@ -2,12 +2,10 @@
using AtomUI.Controls;
using AtomUI.Data;
using AtomUI.Theme;
-using AtomUI.Theme.Palette;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
-using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.VisualTree;
@@ -147,7 +145,7 @@ public class CountBadge : Control,
HandleDecoratedTargetChanged();
if (BadgeColor is not null)
{
- SetupBadgeColor(BadgeColor);
+ ConfigureDotColor(BadgeColor);
}
}
@@ -275,7 +273,7 @@ public class CountBadge : Control,
if (change.Property == BadgeColorProperty)
{
- SetupBadgeColor(change.GetNewValue());
+ ConfigureDotColor(change.GetNewValue());
}
}
@@ -297,23 +295,9 @@ public class CountBadge : Control,
BadgeIsVisible = true;
}
}
-
- private void SetupBadgeColor(string colorStr)
+
+ private void ConfigureDotColor(string colorStr)
{
- colorStr = colorStr.Trim().ToLower();
-
- foreach (var presetColor in PresetPrimaryColor.AllColorTypes())
- {
- if (presetColor.Type.ToString().ToLower() == colorStr)
- {
- _badgeAdorner!.BadgeColor = new SolidColorBrush(presetColor.Color());
- return;
- }
- }
-
- if (Color.TryParse(colorStr, out var color))
- {
- _badgeAdorner!.BadgeColor = new SolidColorBrush(color);
- }
+ _badgeAdorner!.BadgeColor = BadgeColorUtils.CalculateColor(colorStr);
}
}
\ No newline at end of file
diff --git a/src/AtomUI.Desktop.Controls/Badge/DotBadge.cs b/src/AtomUI.Desktop.Controls/Badge/DotBadge.cs
index 64776cc07..e1ea86d50 100644
--- a/src/AtomUI.Desktop.Controls/Badge/DotBadge.cs
+++ b/src/AtomUI.Desktop.Controls/Badge/DotBadge.cs
@@ -2,13 +2,11 @@
using AtomUI.Controls;
using AtomUI.Data;
using AtomUI.Theme;
-using AtomUI.Theme.Palette;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Layout;
-using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.VisualTree;
@@ -29,17 +27,16 @@ public class DotBadge : Control,
{
#region 公共属性定义
- public static readonly StyledProperty DotColorProperty
- = AvaloniaProperty.Register(
+ public static readonly StyledProperty DotColorProperty =
+ AvaloniaProperty.Register(
nameof(DotColor));
- public static readonly StyledProperty StatusProperty
- = AvaloniaProperty.Register(
+ public static readonly StyledProperty StatusProperty =
+ AvaloniaProperty.Register(
nameof(Status));
- public static readonly StyledProperty TextProperty
- = AvaloniaProperty.Register(
- nameof(Text));
+ public static readonly StyledProperty TextProperty =
+ AvaloniaProperty.Register(nameof(Text));
public static readonly StyledProperty DecoratedTargetProperty =
AvaloniaProperty.Register(nameof(DecoratedTarget));
@@ -132,7 +129,7 @@ public class DotBadge : Control,
HandleDecoratedTargetChanged();
if (DotColor is not null)
{
- SetupDotColor(DotColor);
+ ConfigureDotColor(DotColor);
}
}
@@ -256,27 +253,14 @@ public class DotBadge : Control,
if (change.Property == DotColorProperty)
{
- SetupDotColor(change.GetNewValue());
+ ConfigureDotColor(change.GetNewValue());
}
}
}
- private void SetupDotColor(string colorStr)
+ private void ConfigureDotColor(string colorStr)
{
- colorStr = colorStr.Trim().ToLower();
-
- foreach (var presetColor in PresetPrimaryColor.AllColorTypes())
- {
- if (presetColor.Type.ToString().ToLower() == colorStr)
- {
- _dotBadgeAdorner!.BadgeDotColor = new SolidColorBrush(presetColor.Color());
- return;
- }
- }
-
- if (Color.TryParse(colorStr, out var color))
- {
- _dotBadgeAdorner!.BadgeDotColor = new SolidColorBrush(color);
- }
+ _dotBadgeAdorner!.BadgeDotColor = BadgeColorUtils.CalculateColor(colorStr);
}
+
}
\ No newline at end of file
diff --git a/src/AtomUI.Desktop.Controls/FloatButton/FloatButton.cs b/src/AtomUI.Desktop.Controls/FloatButton/FloatButton.cs
index b62c887d3..6265aca37 100644
--- a/src/AtomUI.Desktop.Controls/FloatButton/FloatButton.cs
+++ b/src/AtomUI.Desktop.Controls/FloatButton/FloatButton.cs
@@ -7,6 +7,7 @@ using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
+using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Media;
@@ -66,6 +67,26 @@ public class FloatButton : AvaloniaButton,
public static readonly StyledProperty IsMotionEnabledProperty =
MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner();
+ public static readonly StyledProperty IsBadgeEnabledProperty =
+ AvaloniaProperty.Register(nameof(IsBadgeEnabled));
+
+ public static readonly StyledProperty IsDotBadgeProperty =
+ AvaloniaProperty.Register(nameof(IsDotBadge));
+
+ public static readonly StyledProperty BadgeCountProperty =
+ AvaloniaProperty.Register(nameof(BadgeCount));
+
+ public static readonly StyledProperty BadgeColorProperty =
+ AvaloniaProperty.Register(
+ nameof(BadgeColor));
+
+ public static readonly StyledProperty BadgeOffsetProperty =
+ AvaloniaProperty.Register(nameof(BadgeOffset));
+
+ public static readonly StyledProperty BadgeOverflowCountProperty =
+ AvaloniaProperty.Register(nameof(BadgeOverflowCount), 99,
+ coerce: (o, v) => Math.Max(0, v));
+
public FloatButtonPlacement Placement
{
get => GetValue(PlacementProperty);
@@ -131,7 +152,42 @@ public class FloatButton : AvaloniaButton,
get => GetValue(IsMotionEnabledProperty);
set => SetValue(IsMotionEnabledProperty, value);
}
+
+ public bool IsBadgeEnabled
+ {
+ get => GetValue(IsBadgeEnabledProperty);
+ set => SetValue(IsBadgeEnabledProperty, value);
+ }
+ public bool IsDotBadge
+ {
+ get => GetValue(IsDotBadgeProperty);
+ set => SetValue(IsDotBadgeProperty, value);
+ }
+
+ public int BadgeCount
+ {
+ get => GetValue(BadgeCountProperty);
+ set => SetValue(BadgeCountProperty, value);
+ }
+
+ public string? BadgeColor
+ {
+ get => GetValue(BadgeColorProperty);
+ set => SetValue(BadgeColorProperty, value);
+ }
+
+ public Point BadgeOffset
+ {
+ get => GetValue(BadgeOffsetProperty);
+ set => SetValue(BadgeOffsetProperty, value);
+ }
+
+ public int BadgeOverflowCount
+ {
+ get => GetValue(BadgeOverflowCountProperty);
+ set => SetValue(BadgeOverflowCountProperty, value);
+ }
#endregion
#region 内部属性定义
@@ -140,6 +196,10 @@ public class FloatButton : AvaloniaButton,
nameof(IsEmbedMode),
o => o.IsEmbedMode,
(o, v) => o.IsEmbedMode = v);
+
+ internal static readonly StyledProperty BadgeEffectiveColorProperty =
+ AvaloniaProperty.Register(
+ nameof(BadgeEffectiveColor));
private bool _isEmbedMode;
@@ -149,12 +209,20 @@ public class FloatButton : AvaloniaButton,
set => SetAndRaise(IsEmbedModeProperty, ref _isEmbedMode, value);
}
+ internal IBrush? BadgeEffectiveColor
+ {
+ get => GetValue(BadgeEffectiveColorProperty);
+ set => SetValue(BadgeEffectiveColorProperty, value);
+ }
+
Control IControlSharedTokenResourcesHost.HostControl => this;
string IControlSharedTokenResourcesHost.TokenId => FloatButtonToken.ID;
#endregion
- ScopeAwareOverlayLayer? _overlayLayer;
+ private ScopeAwareOverlayLayer? _overlayLayer;
+ private Canvas? _badgeLayout;
+ private Control? _badge;
public FloatButton()
{
@@ -174,6 +242,14 @@ public class FloatButton : AvaloniaButton,
{
CalculatePosition(this, _overlayLayer.Bounds.Size, Placement, FloatOffsetX, FloatOffsetY);
}
+ CalculateBadgePosition();
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+ _badgeLayout = e.NameScope.Find