From cd32818e85a460734319b01c9f500f197e92ea89 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Fri, 28 Jul 2023 01:44:42 +0800 Subject: [PATCH 1/4] feat: initialize control. --- .../Controls/KeyGestureInput.axaml | 26 ++++++ src/Ursa.Themes.Semi/Controls/_index.axaml | 1 + src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj | 6 +- src/Ursa/Controls/KeyGestureInput.cs | 83 +++++++++++++++++++ src/Ursa/Ursa.csproj | 4 +- 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml create mode 100644 src/Ursa/Controls/KeyGestureInput.cs diff --git a/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml b/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml new file mode 100644 index 0000000..7a72b5d --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index bbf2752..7444554 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -6,6 +6,7 @@ + diff --git a/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj b/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj index 5bb0d73..88fc18f 100644 --- a/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj +++ b/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj @@ -1,6 +1,6 @@ - + netstandard2.0 @@ -13,11 +13,11 @@ - + - + diff --git a/src/Ursa/Controls/KeyGestureInput.cs b/src/Ursa/Controls/KeyGestureInput.cs new file mode 100644 index 0000000..af43eb3 --- /dev/null +++ b/src/Ursa/Controls/KeyGestureInput.cs @@ -0,0 +1,83 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Converters; +using Avalonia.Controls.Primitives; +using Avalonia.Input; + +namespace Ursa.Controls; + +public class KeyGestureInput: TemplatedControl +{ + static KeyGestureInput() + { + InputElement.FocusableProperty.OverrideDefaultValue(true); + } + + public static readonly StyledProperty GestureProperty = AvaloniaProperty.Register( + nameof(Gesture)); + + public KeyGesture Gesture + { + get => GetValue(GestureProperty); + set => SetValue(GestureProperty, value); + } + + public static readonly StyledProperty> AcceptableKeysProperty = AvaloniaProperty.Register>( + nameof(AcceptableKeys)); + + public IList AcceptableKeys + { + get => GetValue(AcceptableKeysProperty); + set => SetValue(AcceptableKeysProperty, value); + } + + public static readonly StyledProperty ConsiderKeyModifiersProperty = AvaloniaProperty.Register( + nameof(ConsiderKeyModifiers)); + + public bool ConsiderKeyModifiers + { + get => GetValue(ConsiderKeyModifiersProperty); + set => SetValue(ConsiderKeyModifiersProperty, value); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + // base.OnKeyDown(e); + if (!AcceptableKeys.Contains(e.Key)) + { + return; + } + + if (!ConsiderKeyModifiers) + { + if(e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl || e.Key == Key.LeftAlt || e.Key == Key.RightAlt || e.Key == Key.LeftShift || e.Key == Key.RightShift || e.Key == Key.LWin || e.Key == Key.RWin) + { + return; + } + Gesture = new KeyGesture(e.Key); + } + KeyGesture gesture; + if (e.KeyModifiers == KeyModifiers.Control && (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)) + { + gesture = new KeyGesture(e.Key); + } + else if (e.KeyModifiers == KeyModifiers.Alt && (e.Key == Key.LeftAlt || e.Key == Key.RightAlt)) + { + gesture = new KeyGesture(e.Key); + } + else if (e.KeyModifiers == KeyModifiers.Shift && (e.Key == Key.LeftShift || e.Key == Key.RightShift)) + { + gesture = new KeyGesture(e.Key); + } + else if (e.KeyModifiers == KeyModifiers.Meta && (e.Key == Key.LWin || e.Key == Key.RWin)) + { + gesture = new KeyGesture(e.Key); + } + else + { + gesture = new KeyGesture(e.Key, e.KeyModifiers); + } + Gesture = gesture; + e.Handled = true; + } +} \ No newline at end of file diff --git a/src/Ursa/Ursa.csproj b/src/Ursa/Ursa.csproj index 01a32db..a6c5201 100644 --- a/src/Ursa/Ursa.csproj +++ b/src/Ursa/Ursa.csproj @@ -1,6 +1,6 @@ - + netstandard2.0 @@ -13,7 +13,7 @@ - + From 87090f2d3290de1d72a61dc758c538783f59df86 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sun, 30 Jul 2023 22:26:38 +0800 Subject: [PATCH 2/4] feat: improve style. add demo. --- demo/Ursa.Demo/Models/MenuKeys.cs | 2 ++ .../Ursa.Demo/Pages/KeyGestureInputDemo.axaml | 15 +++++++++ .../Pages/KeyGestureInputDemo.axaml.cs | 18 +++++++++++ demo/Ursa.Demo/Ursa.Demo.csproj | 16 +++++----- .../KeyGestureInputDemoViewModel.cs | 8 +++++ .../Ursa.Demo/ViewModels/MainViewViewModel.cs | 1 + demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 1 + .../Controls/KeyGestureInput.axaml | 32 +++++++++++++++---- .../Themes/Dark/KeyGestureInput.axaml | 9 ++++++ src/Ursa.Themes.Semi/Themes/Dark/_index.axaml | 1 + .../Themes/Light/KeyGestureInput.axaml | 9 ++++++ .../Themes/Light/_index.axaml | 1 + .../Themes/Shared/KeyGestureInput.axaml | 6 ++++ .../Themes/Shared/_index.axaml | 1 + src/Ursa/Controls/KeyGestureInput.cs | 30 ++++++++++++++--- 15 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml create mode 100644 demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml.cs create mode 100644 demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs create mode 100644 src/Ursa.Themes.Semi/Themes/Dark/KeyGestureInput.axaml create mode 100644 src/Ursa.Themes.Semi/Themes/Light/KeyGestureInput.axaml create mode 100644 src/Ursa.Themes.Semi/Themes/Shared/KeyGestureInput.axaml diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs index 5a76eb9..3717625 100644 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -7,9 +7,11 @@ public static class MenuKeys public const string MenuKeyButtonGroup = "ButtonGroup"; public const string MenuKeyDivider = "Divider"; public const string MenuKeyIpBox = "IPv4Box"; + public const string MenuKeyKeyGestureInput = "KeyGestureInput"; public const string MenuKeyLoading = "Loading"; public const string MenuKeyNavigation = "Navigation"; public const string MenuKeyPagination = "Pagination"; public const string MenuKeyTagInput = "TagInput"; public const string MenuKeyTimeline = "Timeline"; + } \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml new file mode 100644 index 0000000..e84ba5e --- /dev/null +++ b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml @@ -0,0 +1,15 @@ + + + + + + diff --git a/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml.cs b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml.cs new file mode 100644 index 0000000..f213756 --- /dev/null +++ b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml.cs @@ -0,0 +1,18 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class KeyGestureInputDemo : UserControl +{ + public KeyGestureInputDemo() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Ursa.Demo.csproj b/demo/Ursa.Demo/Ursa.Demo.csproj index 4f0188d..d11b6e7 100644 --- a/demo/Ursa.Demo/Ursa.Demo.csproj +++ b/demo/Ursa.Demo/Ursa.Demo.csproj @@ -7,23 +7,23 @@ - + - + - + - - - + + + - - + + diff --git a/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs new file mode 100644 index 0000000..4a89729 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs @@ -0,0 +1,8 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public class KeyGestureInputDemoViewModel: ObservableObject +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 6641f1f..919e6db 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -29,6 +29,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(), MenuKeys.MenuKeyDivider => new DividerDemoViewModel(), MenuKeys.MenuKeyIpBox => new IPv4BoxDemoViewModel(), + MenuKeys.MenuKeyKeyGestureInput => new KeyGestureInputDemoViewModel(), MenuKeys.MenuKeyLoading => new LoadingDemoViewModel(), MenuKeys.MenuKeyNavigation => new NavigationMenuDemoViewModel(), MenuKeys.MenuKeyPagination => new PaginationDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index 9351ad9..315c31c 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -16,6 +16,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "ButtonGroup", Key = MenuKeys.MenuKeyButtonGroup }, new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider }, new() { MenuHeader = "IPv4Box", Key = MenuKeys.MenuKeyIpBox }, + new() { MenuHeader = "KeyGestureInput", Key = MenuKeys.MenuKeyKeyGestureInput }, new() { MenuHeader = "Loading", Key = MenuKeys.MenuKeyLoading }, new() { MenuHeader = "Navigation", Key = MenuKeys.MenuKeyNavigation }, new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination }, diff --git a/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml b/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml index 7a72b5d..56aab72 100644 --- a/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml +++ b/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml @@ -7,20 +7,40 @@ + + + - + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="{DynamicResource KeyGestureInputBackground}" + BorderBrush="Transparent" + BorderThickness="1" + CornerRadius="{TemplateBinding CornerRadius}"> + + + + diff --git a/src/Ursa.Themes.Semi/Themes/Dark/KeyGestureInput.axaml b/src/Ursa.Themes.Semi/Themes/Dark/KeyGestureInput.axaml new file mode 100644 index 0000000..ed7c331 --- /dev/null +++ b/src/Ursa.Themes.Semi/Themes/Dark/KeyGestureInput.axaml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml index c9f2bea..340a2ba 100644 --- a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml +++ b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml @@ -6,6 +6,7 @@ + diff --git a/src/Ursa.Themes.Semi/Themes/Light/KeyGestureInput.axaml b/src/Ursa.Themes.Semi/Themes/Light/KeyGestureInput.axaml new file mode 100644 index 0000000..490e1a4 --- /dev/null +++ b/src/Ursa.Themes.Semi/Themes/Light/KeyGestureInput.axaml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml index c9f2bea..340a2ba 100644 --- a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml +++ b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml @@ -6,6 +6,7 @@ + diff --git a/src/Ursa.Themes.Semi/Themes/Shared/KeyGestureInput.axaml b/src/Ursa.Themes.Semi/Themes/Shared/KeyGestureInput.axaml new file mode 100644 index 0000000..ee22a40 --- /dev/null +++ b/src/Ursa.Themes.Semi/Themes/Shared/KeyGestureInput.axaml @@ -0,0 +1,6 @@ + + + 80 + 32 + 3 + diff --git a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml index 777a0a4..7be0bef 100644 --- a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml +++ b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml @@ -6,6 +6,7 @@ + diff --git a/src/Ursa/Controls/KeyGestureInput.cs b/src/Ursa/Controls/KeyGestureInput.cs index af43eb3..38dd28c 100644 --- a/src/Ursa/Controls/KeyGestureInput.cs +++ b/src/Ursa/Controls/KeyGestureInput.cs @@ -3,6 +3,7 @@ using Avalonia.Controls; using Avalonia.Controls.Converters; using Avalonia.Controls.Primitives; using Avalonia.Input; +using Avalonia.Layout; namespace Ursa.Controls; @@ -22,17 +23,17 @@ public class KeyGestureInput: TemplatedControl set => SetValue(GestureProperty, value); } - public static readonly StyledProperty> AcceptableKeysProperty = AvaloniaProperty.Register>( + public static readonly StyledProperty?> AcceptableKeysProperty = AvaloniaProperty.Register?>( nameof(AcceptableKeys)); - public IList AcceptableKeys + public IList? AcceptableKeys { get => GetValue(AcceptableKeysProperty); set => SetValue(AcceptableKeysProperty, value); } public static readonly StyledProperty ConsiderKeyModifiersProperty = AvaloniaProperty.Register( - nameof(ConsiderKeyModifiers)); + nameof(ConsiderKeyModifiers), true); public bool ConsiderKeyModifiers { @@ -40,10 +41,31 @@ public class KeyGestureInput: TemplatedControl set => SetValue(ConsiderKeyModifiersProperty, value); } + public static readonly StyledProperty HorizontalContentAlignmentProperty = + ContentControl.HorizontalContentAlignmentProperty.AddOwner( + new StyledPropertyMetadata(HorizontalAlignment.Center)); + + public HorizontalAlignment HorizontalContentAlignment + { + get => GetValue(HorizontalContentAlignmentProperty); + set => SetValue(HorizontalContentAlignmentProperty, value); + } + + public static readonly StyledProperty VerticalContentAlignmentProperty = + ContentControl.VerticalContentAlignmentProperty.AddOwner( + new StyledPropertyMetadata(VerticalAlignment.Center)); + + public VerticalAlignment VerticalContentAlignment + { + get => GetValue(VerticalContentAlignmentProperty); + set => SetValue(VerticalContentAlignmentProperty, value); + } + + protected override void OnKeyDown(KeyEventArgs e) { // base.OnKeyDown(e); - if (!AcceptableKeys.Contains(e.Key)) + if (AcceptableKeys is not null && !AcceptableKeys.Contains(e.Key)) { return; } From 5165933ffabd7e3be381cc5c19a6cf7928e0f550 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sun, 30 Jul 2023 22:34:07 +0800 Subject: [PATCH 3/4] misc: add AcceptableKeys demo. --- demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml | 7 ++++++- demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml index e84ba5e..e828758 100644 --- a/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml +++ b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml @@ -5,11 +5,16 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:u="https://irihi.tech/ursa" + xmlns:vm="clr-namespace:Ursa.Demo.ViewModels;assembly=Ursa.Demo" d:DesignHeight="450" d:DesignWidth="800" + x:CompileBindings="True" + x:DataType="vm:KeyGestureInputDemoViewModel" mc:Ignorable="d"> + - + + diff --git a/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs index 4a89729..b69f20c 100644 --- a/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/KeyGestureInputDemoViewModel.cs @@ -1,8 +1,13 @@ +using System.Collections.Generic; +using Avalonia.Input; using CommunityToolkit.Mvvm.ComponentModel; namespace Ursa.Demo.ViewModels; public class KeyGestureInputDemoViewModel: ObservableObject { - + public List AcceptableKeys { get; set; } = new List() + { + Key.A, Key.B, Key.C, + }; } \ No newline at end of file From 20a0152b76c746346733a37fb0aeb6c8498eef7b Mon Sep 17 00:00:00 2001 From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com> Date: Sat, 5 Aug 2023 00:40:30 +0800 Subject: [PATCH 4/4] fix: extract template property. --- .../Ursa.Demo/Pages/KeyGestureInputDemo.axaml | 6 ++-- .../Controls/KeyGestureInput.axaml | 11 ++++--- .../Themes/Shared/KeyGestureInput.axaml | 1 + src/Ursa/Controls/KeyGestureInput.cs | 30 +++++++------------ 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml index e828758..406c353 100644 --- a/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml +++ b/demo/Ursa.Demo/Pages/KeyGestureInputDemo.axaml @@ -13,8 +13,8 @@ mc:Ignorable="d"> - + - + - + \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml b/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml index 56aab72..2bbbd31 100644 --- a/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml +++ b/src/Ursa.Themes.Semi/Controls/KeyGestureInput.axaml @@ -3,22 +3,25 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="using:Avalonia.Controls.Converters" xmlns:u="https://irihi.tech/ursa"> - + + + + 80 32 3 + 1 diff --git a/src/Ursa/Controls/KeyGestureInput.cs b/src/Ursa/Controls/KeyGestureInput.cs index 38dd28c..5c4e535 100644 --- a/src/Ursa/Controls/KeyGestureInput.cs +++ b/src/Ursa/Controls/KeyGestureInput.cs @@ -72,32 +72,24 @@ public class KeyGestureInput: TemplatedControl if (!ConsiderKeyModifiers) { - if(e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl || e.Key == Key.LeftAlt || e.Key == Key.RightAlt || e.Key == Key.LeftShift || e.Key == Key.RightShift || e.Key == Key.LWin || e.Key == Key.RWin) + if(e.Key is Key.LeftCtrl or Key.RightCtrl or Key.LeftAlt or Key.RightAlt or Key.LeftShift or Key.RightShift or Key.LWin or Key.RWin) { return; } Gesture = new KeyGesture(e.Key); } KeyGesture gesture; - if (e.KeyModifiers == KeyModifiers.Control && (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)) + switch (e.KeyModifiers) { - gesture = new KeyGesture(e.Key); - } - else if (e.KeyModifiers == KeyModifiers.Alt && (e.Key == Key.LeftAlt || e.Key == Key.RightAlt)) - { - gesture = new KeyGesture(e.Key); - } - else if (e.KeyModifiers == KeyModifiers.Shift && (e.Key == Key.LeftShift || e.Key == Key.RightShift)) - { - gesture = new KeyGesture(e.Key); - } - else if (e.KeyModifiers == KeyModifiers.Meta && (e.Key == Key.LWin || e.Key == Key.RWin)) - { - gesture = new KeyGesture(e.Key); - } - else - { - gesture = new KeyGesture(e.Key, e.KeyModifiers); + case KeyModifiers.Control when e.Key is Key.LeftCtrl or Key.RightCtrl: + case KeyModifiers.Alt when e.Key is Key.LeftAlt or Key.RightAlt: + case KeyModifiers.Shift when e.Key is Key.LeftShift or Key.RightShift: + case KeyModifiers.Meta when e.Key is Key.LWin or Key.RWin: + gesture = new KeyGesture(e.Key); + break; + default: + gesture = new KeyGesture(e.Key, e.KeyModifiers); + break; } Gesture = gesture; e.Handled = true;