diff --git a/demo/Ursa.Demo/Pages/AvatarDemo.axaml b/demo/Ursa.Demo/Pages/AvatarDemo.axaml
new file mode 100644
index 0000000..be6ed45
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/AvatarDemo.axaml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Pages/AvatarDemo.axaml.cs b/demo/Ursa.Demo/Pages/AvatarDemo.axaml.cs
new file mode 100644
index 0000000..5bc2485
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/AvatarDemo.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace Ursa.Demo.Pages;
+
+public partial class AvatarDemo : UserControl
+{
+ public AvatarDemo()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/AvatarDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/AvatarDemoViewModel.cs
new file mode 100644
index 0000000..cf968aa
--- /dev/null
+++ b/demo/Ursa.Demo/ViewModels/AvatarDemoViewModel.cs
@@ -0,0 +1,6 @@
+namespace Ursa.Demo.ViewModels;
+
+public class AvatarDemoViewModel: ViewModelBase
+{
+
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
index 1baf568..d995db0 100644
--- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
@@ -25,6 +25,7 @@ public class MainViewViewModel : ViewModelBase
Content = s switch
{
MenuKeys.MenuKeyIntroduction => new IntroductionDemoViewModel(),
+ MenuKeys.MenuKeyAvatar => new AvatarDemoViewModel(),
MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(),
MenuKeys.MenuKeyBanner => new BannerDemoViewModel(),
MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(),
diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
index e196a85..c839bfb 100644
--- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
@@ -12,6 +12,7 @@ public class MenuViewModel: ViewModelBase
{
new() { MenuHeader = "Introduction", Key = MenuKeys.MenuKeyIntroduction, IsSeparator = false },
new() { MenuHeader = "Controls", IsSeparator = true },
+ new() { MenuHeader = "Avatar", Key = MenuKeys.MenuKeyAvatar, Status = "WIP"},
new() { MenuHeader = "Badge", Key = MenuKeys.MenuKeyBadge },
new() { MenuHeader = "Banner", Key = MenuKeys.MenuKeyBanner },
new() { MenuHeader = "Breadcrumb", Key = MenuKeys.MenuKeyBreadcrumb },
@@ -59,6 +60,7 @@ public class MenuViewModel: ViewModelBase
public static class MenuKeys
{
public const string MenuKeyIntroduction = "Introduction";
+ public const string MenuKeyAvatar = "Avatar";
public const string MenuKeyBadge = "Badge";
public const string MenuKeyBanner = "Banner";
public const string MenuKeyButtonGroup = "ButtonGroup";
diff --git a/src/Ursa.Themes.Semi/Controls/Avatar.axaml b/src/Ursa.Themes.Semi/Controls/Avatar.axaml
new file mode 100644
index 0000000..5324a77
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/Avatar.axaml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml
index 4d7ae82..9e4a4ba 100644
--- a/src/Ursa.Themes.Semi/Controls/_index.axaml
+++ b/src/Ursa.Themes.Semi/Controls/_index.axaml
@@ -1,6 +1,7 @@
+
diff --git a/src/Ursa.Themes.Semi/Themes/Dark/Avatar.axaml b/src/Ursa.Themes.Semi/Themes/Dark/Avatar.axaml
new file mode 100644
index 0000000..c9ef25a
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Dark/Avatar.axaml
@@ -0,0 +1,2 @@
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
index 86727f2..cf02f07 100644
--- a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
+++ b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
@@ -1,6 +1,7 @@
+
diff --git a/src/Ursa.Themes.Semi/Themes/Light/Avatar.axaml b/src/Ursa.Themes.Semi/Themes/Light/Avatar.axaml
new file mode 100644
index 0000000..c9ef25a
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Light/Avatar.axaml
@@ -0,0 +1,2 @@
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
index 86727f2..cf02f07 100644
--- a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
+++ b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
@@ -1,6 +1,7 @@
+
diff --git a/src/Ursa.Themes.Semi/Themes/Shared/Avatar.axaml b/src/Ursa.Themes.Semi/Themes/Shared/Avatar.axaml
new file mode 100644
index 0000000..c9ef25a
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Shared/Avatar.axaml
@@ -0,0 +1,2 @@
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml
index 5350d09..a11acac 100644
--- a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml
+++ b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml
@@ -1,6 +1,7 @@
+
diff --git a/src/Ursa/Controls/Avatar/Avatar.cs b/src/Ursa/Controls/Avatar/Avatar.cs
new file mode 100644
index 0000000..d10361e
--- /dev/null
+++ b/src/Ursa/Controls/Avatar/Avatar.cs
@@ -0,0 +1,38 @@
+using Avalonia;
+using Avalonia.Controls;
+
+namespace Ursa.Controls;
+
+public class Avatar : Button
+{
+ public const string PART_TopPresenter = "PART_TopPresenter";
+ public const string PART_BottomPresenter = "PART_BottomPresenter";
+ public const string PART_HoverMask = "PART_HoverMask";
+
+ public static readonly StyledProperty ContentMotionProperty = AvaloniaProperty.Register(
+ nameof(ContentMotion));
+
+ public static readonly StyledProperty GapProperty = AvaloniaProperty.Register(
+ nameof(Gap));
+
+ public static readonly StyledProperty SourceProperty = AvaloniaProperty.Register(
+ nameof(Source));
+
+ public bool ContentMotion
+ {
+ get => GetValue(ContentMotionProperty);
+ set => SetValue(ContentMotionProperty, value);
+ }
+
+ public double Gap
+ {
+ get => GetValue(GapProperty);
+ set => SetValue(GapProperty, value);
+ }
+
+ public string Source
+ {
+ get => GetValue(SourceProperty);
+ set => SetValue(SourceProperty, value);
+ }
+}
\ No newline at end of file
diff --git a/src/Ursa/Controls/Avatar/AvatarGroup.cs b/src/Ursa/Controls/Avatar/AvatarGroup.cs
new file mode 100644
index 0000000..60e86b7
--- /dev/null
+++ b/src/Ursa/Controls/Avatar/AvatarGroup.cs
@@ -0,0 +1,33 @@
+using Avalonia;
+using Avalonia.Controls;
+
+namespace Ursa.Controls;
+
+public class AvatarGroup : ItemsControl
+{
+ public const string PART_RenderMore = "PART_RenderMore";
+
+ public static readonly StyledProperty MaxCountProperty = AvaloniaProperty.Register(
+ nameof(MaxCount));
+
+ public static readonly StyledProperty OverlapFromProperty = AvaloniaProperty.Register(
+ nameof(OverlapFrom));
+
+ public int MaxCount
+ {
+ get => GetValue(MaxCountProperty);
+ set => SetValue(MaxCountProperty, value);
+ }
+
+ public OverlapFromType OverlapFrom
+ {
+ get => GetValue(OverlapFromProperty);
+ set => SetValue(OverlapFromProperty, value);
+ }
+}
+
+public enum OverlapFromType
+{
+ Start,
+ End
+}
\ No newline at end of file