From ccc883d5f80702697d9d43d42996de79cb7b954b Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sat, 27 Jan 2024 03:47:54 +0800 Subject: [PATCH 1/2] feat: add two tone icon. --- demo/Ursa.Demo/Models/MenuKeys.cs | 1 + .../Ursa.Demo/Pages/TwoTonePathIconDemo.axaml | 18 ++++ .../Pages/TwoTonePathIconDemo.axaml.cs | 13 +++ .../Ursa.Demo/ViewModels/MainViewViewModel.cs | 1 + demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 1 + .../TwoTonePathIconDemoViewModel.cs | 8 ++ .../Controls/TwoTonePathIcon.axaml | 38 ++++++++ src/Ursa.Themes.Semi/Controls/_index.axaml | 1 + src/Ursa/Controls/Icons/TwoTonePathIcon.cs | 92 +++++++++++++++++++ 9 files changed, 173 insertions(+) create mode 100644 demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml create mode 100644 demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs create mode 100644 demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs create mode 100644 src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml create mode 100644 src/Ursa/Controls/Icons/TwoTonePathIcon.cs diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs index b0eaf2f..17714e1 100644 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -21,5 +21,6 @@ public static class MenuKeys public const string MenuKeyRangeSlider = "RangeSlider"; public const string MenuKeyTagInput = "TagInput"; public const string MenuKeyTimeline = "Timeline"; + public const string MenuKeyTwoTonePathIcon = "TwoTonePathIcon"; } \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml new file mode 100644 index 0000000..ae22c4b --- /dev/null +++ b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs new file mode 100644 index 0000000..72e0a25 --- /dev/null +++ b/demo/Ursa.Demo/Pages/TwoTonePathIconDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class TwoTonePathIconDemo : UserControl +{ + public TwoTonePathIconDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 8ebf182..be51f3b 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -43,6 +43,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyRangeSlider => new RangeSliderDemoViewModel(), MenuKeys.MenuKeyTagInput => new TagInputDemoViewModel(), MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(), + MenuKeys.MenuKeyTwoTonePathIcon => new TwoTonePathIconDemoViewModel(), }; } } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index 95ac6f9..fa35634 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -30,6 +30,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider, Status = "New"}, new() { MenuHeader = "TagInput", Key = MenuKeys.MenuKeyTagInput }, new() { MenuHeader = "Timeline", Key = MenuKeys.MenuKeyTimeline, Status = "Updated" }, + new() { MenuHeader = "TwoTonePathIcon", Key = MenuKeys.MenuKeyTwoTonePathIcon, Status = "New"}, }; } } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs new file mode 100644 index 0000000..d2112a1 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/TwoTonePathIconDemoViewModel.cs @@ -0,0 +1,8 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public class TwoTonePathIconDemoViewModel:ObservableObject +{ + +} \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml b/src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml new file mode 100644 index 0000000..1fe4731 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/TwoTonePathIcon.axaml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index 9f871de..fc8eba7 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -19,5 +19,6 @@ + diff --git a/src/Ursa/Controls/Icons/TwoTonePathIcon.cs b/src/Ursa/Controls/Icons/TwoTonePathIcon.cs new file mode 100644 index 0000000..d44ad7c --- /dev/null +++ b/src/Ursa/Controls/Icons/TwoTonePathIcon.cs @@ -0,0 +1,92 @@ +using System.ComponentModel; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Metadata; +using Avalonia.Controls.Primitives; +using Avalonia.Data; +using Avalonia.Media; + +namespace Ursa.Controls; + +[PseudoClasses(PC_Active)] +public class TwoTonePathIcon: TemplatedControl +{ + public const string PC_Active = ":active"; + + public static readonly StyledProperty StrokeBrushProperty = AvaloniaProperty.Register( + nameof(StrokeBrush)); + + public IBrush? StrokeBrush + { + get => GetValue(StrokeBrushProperty); + set => SetValue(StrokeBrushProperty, value); + } + + public static readonly StyledProperty DataProperty = AvaloniaProperty.Register( + nameof(Data)); + + public Geometry Data + { + get => GetValue(DataProperty); + set => SetValue(DataProperty, value); + } + + public static readonly StyledProperty IsActiveProperty = AvaloniaProperty.Register( + nameof(IsActive), defaultBindingMode: BindingMode.TwoWay); + + public bool IsActive + { + get => GetValue(IsActiveProperty); + set => SetValue(IsActiveProperty, value); + } + + public static readonly StyledProperty ActiveForegroundProperty = AvaloniaProperty.Register( + nameof(ActiveForeground)); + + public IBrush? ActiveForeground + { + get => GetValue(ActiveForegroundProperty); + set => SetValue(ActiveForegroundProperty, value); + } + + public static readonly StyledProperty ActiveStrokeBrushProperty = AvaloniaProperty.Register( + nameof(ActiveStrokeBrush)); + + public IBrush? ActiveStrokeBrush + { + get => GetValue(ActiveStrokeBrushProperty); + set => SetValue(ActiveStrokeBrushProperty, value); + } + + public static readonly StyledProperty StrokeThicknessProperty = + AvaloniaProperty.Register( + nameof(StrokeThickness)); + public double StrokeThickness + { + get => GetValue(StrokeThicknessProperty); + set => SetValue(StrokeThicknessProperty, value); + } + + static TwoTonePathIcon() + { + AffectsRender( + DataProperty, + StrokeBrushProperty, + ForegroundProperty, + ActiveForegroundProperty, + ActiveStrokeBrushProperty); + IsActiveProperty.Changed.AddClassHandler((o, e) => o.OnIsActiveChanged(e)); + } + + private void OnIsActiveChanged(AvaloniaPropertyChangedEventArgs args) + { + var newValue = args.NewValue.Value; + PseudoClasses.Set(PC_Active, newValue); + } + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + PseudoClasses.Set(PC_Active, IsActive); + } +} \ No newline at end of file From 25c36c941c1ddefb4ef30254ee5af2c66b475d6f Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sat, 27 Jan 2024 14:03:39 +0800 Subject: [PATCH 2/2] feat: improve button group demo. --- demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml index 3026968..4081616 100644 --- a/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml +++ b/demo/Ursa.Demo/Pages/ButtonGroupDemo.axaml @@ -18,7 +18,10 @@ ItemsSource="{Binding Items}" > - + + + +