From ff666cafdcfa205b2d850fe58760bfbd628fd964 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Wed, 31 Jul 2024 14:11:16 +0800 Subject: [PATCH] feat: rename to PinCode, add styles for size. --- demo/Ursa.Demo/Pages/PinCodeDemo.axaml | 25 ++++++++ ...CodeDemo.axaml.cs => PinCodeDemo.axaml.cs} | 6 +- .../Pages/VerificationCodeDemo.axaml | 17 ----- .../Ursa.Demo/ViewModels/MainViewViewModel.cs | 2 +- demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 4 +- ...moViewModel.cs => PinCodeDemoViewModel.cs} | 4 +- src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs | 3 +- .../{VerificationCode.axaml => PinCode.axaml} | 54 +++++++++------- src/Ursa.Themes.Semi/Controls/_index.axaml | 2 +- src/Ursa.Themes.Semi/Styles/PinCode.axaml | 33 ++++++++++ src/Ursa.Themes.Semi/Styles/_index.axaml | 1 + .../PinCode.cs} | 62 ++++++++++--------- .../PinCodeCollection.cs} | 6 +- .../PinCode/PinCodeCompleteEventArgs.cs | 8 +++ .../PinCodeItem.cs} | 6 +- .../PinCodeMode.cs} | 2 +- .../VerificationCodeCompleteEventArgs.cs | 8 --- 17 files changed, 149 insertions(+), 94 deletions(-) create mode 100644 demo/Ursa.Demo/Pages/PinCodeDemo.axaml rename demo/Ursa.Demo/Pages/{VerificationCodeDemo.axaml.cs => PinCodeDemo.axaml.cs} (55%) delete mode 100644 demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml rename demo/Ursa.Demo/ViewModels/{VerificationCodeDemoViewModel.cs => PinCodeDemoViewModel.cs} (86%) rename src/Ursa.Themes.Semi/Controls/{VerificationCode.axaml => PinCode.axaml} (57%) create mode 100644 src/Ursa.Themes.Semi/Styles/PinCode.axaml rename src/Ursa/Controls/{VerificationCode/VerificationCode.cs => PinCode/PinCode.cs} (68%) rename src/Ursa/Controls/{VerificationCode/VerificationCodeCollection.cs => PinCode/PinCodeCollection.cs} (69%) create mode 100644 src/Ursa/Controls/PinCode/PinCodeCompleteEventArgs.cs rename src/Ursa/Controls/{VerificationCode/VerificationCodeItem.cs => PinCode/PinCodeItem.cs} (78%) rename src/Ursa/Controls/{VerificationCode/VerificationCodeMode.cs => PinCode/PinCodeMode.cs} (67%) delete mode 100644 src/Ursa/Controls/VerificationCode/VerificationCodeCompleteEventArgs.cs diff --git a/demo/Ursa.Demo/Pages/PinCodeDemo.axaml b/demo/Ursa.Demo/Pages/PinCodeDemo.axaml new file mode 100644 index 0000000..74b28d9 --- /dev/null +++ b/demo/Ursa.Demo/Pages/PinCodeDemo.axaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml.cs b/demo/Ursa.Demo/Pages/PinCodeDemo.axaml.cs similarity index 55% rename from demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml.cs rename to demo/Ursa.Demo/Pages/PinCodeDemo.axaml.cs index 23f9bb0..1b98293 100644 --- a/demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml.cs +++ b/demo/Ursa.Demo/Pages/PinCodeDemo.axaml.cs @@ -3,14 +3,14 @@ using Ursa.Controls; namespace Ursa.Demo.Pages; -public partial class VerificationCodeDemo : UserControl +public partial class PinCodeDemo : UserControl { - public VerificationCodeDemo() + public PinCodeDemo() { InitializeComponent(); } - private async void VerificationCode_OnComplete(object? _, VerificationCodeCompleteEventArgs e) + private async void VerificationCode_OnComplete(object? _, PinCodeCompleteEventArgs e) { var text = string.Join(string.Empty, e.Code); await MessageBox.ShowOverlayAsync(text); diff --git a/demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml b/demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml deleted file mode 100644 index 77c7cd6..0000000 --- a/demo/Ursa.Demo/Pages/VerificationCodeDemo.axaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 6d34758..3397a9d 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -67,7 +67,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyThemeToggler => new ThemeTogglerDemoViewModel(), MenuKeys.MenuKeyToolBar => new ToolBarDemoViewModel(), MenuKeys.MenuKeyTimeBox => new TimeBoxDemoViewModel(), - MenuKeys.MenuKeyVerificationCode => new VerificationCodeDemoViewModel(), + MenuKeys.MenuKeyPinCode => new PinCodeDemoViewModel(), _ => throw new ArgumentOutOfRangeException(nameof(s), s, null) }; } diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index 231dd0d..494489e 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -40,6 +40,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "Numeric UpDown", Key = MenuKeys.MenuKeyNumericUpDown }, new() { MenuHeader = "NumPad", Key = MenuKeys.MenuKeyNumPad }, new() { MenuHeader = "Pagination", Key = MenuKeys.MenuKeyPagination }, + new() { MenuHeader = "PinCode", Key = MenuKeys.MenuKeyPinCode}, new() { MenuHeader = "RangeSlider", Key = MenuKeys.MenuKeyRangeSlider }, new() { MenuHeader = "Rating", Key = MenuKeys.MenuKeyRating, Status = "New"}, new() { MenuHeader = "Scroll To", Key = MenuKeys.MenuKeyScrollToButton }, @@ -53,7 +54,6 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "TwoTonePathIcon", Key = MenuKeys.MenuKeyTwoTonePathIcon}, new() { MenuHeader = "ToolBar", Key = MenuKeys.MenuKeyToolBar }, new() { MenuHeader = "Time Box", Key = MenuKeys.MenuKeyTimeBox }, - new() { MenuHeader = "Verification Code", Key = MenuKeys.MenuKeyVerificationCode}, }; } } @@ -101,7 +101,7 @@ public static class MenuKeys public const string MenuKeyThemeToggler = "ThemeToggler"; public const string MenuKeyTreeComboBox = "TreeComboBox"; public const string MenuKeyToolBar = "ToolBar"; - public const string MenuKeyVerificationCode = "VerificationCode"; + public const string MenuKeyPinCode = "PinCode"; public const string MenuKeyTimeBox = "TimeBox"; } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/VerificationCodeDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/PinCodeDemoViewModel.cs similarity index 86% rename from demo/Ursa.Demo/ViewModels/VerificationCodeDemoViewModel.cs rename to demo/Ursa.Demo/ViewModels/PinCodeDemoViewModel.cs index 2b5cc51..f658c19 100644 --- a/demo/Ursa.Demo/ViewModels/VerificationCodeDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/PinCodeDemoViewModel.cs @@ -8,12 +8,12 @@ using Ursa.Controls; namespace Ursa.Demo.ViewModels; -public partial class VerificationCodeDemoViewModel: ObservableObject +public partial class PinCodeDemoViewModel: ObservableObject { public ICommand CompleteCommand { get; set; } [ObservableProperty] private List? _error; - public VerificationCodeDemoViewModel() + public PinCodeDemoViewModel() { CompleteCommand = new AsyncRelayCommand>(OnComplete); Error = [new Exception("Invalid verification code")]; diff --git a/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs b/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs index 22e11c2..04b7c36 100644 --- a/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs +++ b/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs @@ -17,7 +17,8 @@ internal class ClassHelper: AvaloniaObject private static void OnClassesChanged(StyledElement sender, AvaloniaPropertyChangedEventArgs value) { - string classes = value.GetNewValue(); + string? classes = value.GetNewValue(); + if (classes is null) return; sender.Classes.Clear(); sender.Classes.Add(classes); } diff --git a/src/Ursa.Themes.Semi/Controls/VerificationCode.axaml b/src/Ursa.Themes.Semi/Controls/PinCode.axaml similarity index 57% rename from src/Ursa.Themes.Semi/Controls/VerificationCode.axaml rename to src/Ursa.Themes.Semi/Controls/PinCode.axaml index ae38a54..b8d87e4 100644 --- a/src/Ursa.Themes.Semi/Controls/VerificationCode.axaml +++ b/src/Ursa.Themes.Semi/Controls/PinCode.axaml @@ -3,24 +3,23 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:u="https://irihi.tech/ursa"> - + - - - + - - - - + + + + + + + - + - + - + + - + - - + + - + - - - - - + + + + + - - + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index 0345044..6ab88a9 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -48,6 +48,6 @@ - + diff --git a/src/Ursa.Themes.Semi/Styles/PinCode.axaml b/src/Ursa.Themes.Semi/Styles/PinCode.axaml new file mode 100644 index 0000000..f08fe81 --- /dev/null +++ b/src/Ursa.Themes.Semi/Styles/PinCode.axaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Styles/_index.axaml b/src/Ursa.Themes.Semi/Styles/_index.axaml index 868fad8..8de34d2 100644 --- a/src/Ursa.Themes.Semi/Styles/_index.axaml +++ b/src/Ursa.Themes.Semi/Styles/_index.axaml @@ -6,6 +6,7 @@ + diff --git a/src/Ursa/Controls/VerificationCode/VerificationCode.cs b/src/Ursa/Controls/PinCode/PinCode.cs similarity index 68% rename from src/Ursa/Controls/VerificationCode/VerificationCode.cs rename to src/Ursa/Controls/PinCode/PinCode.cs index 8563bf6..cb4e7cc 100644 --- a/src/Ursa/Controls/VerificationCode/VerificationCode.cs +++ b/src/Ursa/Controls/PinCode/PinCode.cs @@ -5,18 +5,19 @@ using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; +using Avalonia.LogicalTree; using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; [TemplatePart(PART_ItemsControl, typeof(ItemsControl))] -public class VerificationCode: TemplatedControl +public class PinCode: TemplatedControl { public const string PART_ItemsControl = "PART_ItemsControl"; private ItemsControl? _itemsControl; private int _currentIndex; - public static readonly StyledProperty CompleteCommandProperty = AvaloniaProperty.Register( + public static readonly StyledProperty CompleteCommandProperty = AvaloniaProperty.Register( nameof(CompleteCommand)); public ICommand? CompleteCommand @@ -25,7 +26,7 @@ public class VerificationCode: TemplatedControl set => SetValue(CompleteCommandProperty, value); } - public static readonly StyledProperty CountProperty = AvaloniaProperty.Register( + public static readonly StyledProperty CountProperty = AvaloniaProperty.Register( nameof(Count)); public int Count @@ -35,7 +36,7 @@ public class VerificationCode: TemplatedControl } public static readonly StyledProperty PasswordCharProperty = - AvaloniaProperty.Register( + AvaloniaProperty.Register( nameof(PasswordChar)); public char PasswordChar @@ -44,17 +45,17 @@ public class VerificationCode: TemplatedControl set => SetValue(PasswordCharProperty, value); } - public static readonly StyledProperty ModeProperty = - AvaloniaProperty.Register( - nameof(Mode), defaultValue: VerificationCodeMode.Digit | VerificationCodeMode.Letter); + public static readonly StyledProperty ModeProperty = + AvaloniaProperty.Register( + nameof(Mode), defaultValue: PinCodeMode.Digit | PinCodeMode.Letter); - public VerificationCodeMode Mode + public PinCodeMode Mode { get => GetValue(ModeProperty); set => SetValue(ModeProperty, value); } - public static readonly DirectProperty> DigitsProperty = AvaloniaProperty.RegisterDirect>( + public static readonly DirectProperty> DigitsProperty = AvaloniaProperty.RegisterDirect>( nameof(Digits), o => o.Digits); private IList _digits = []; @@ -64,23 +65,23 @@ public class VerificationCode: TemplatedControl private set => SetAndRaise(DigitsProperty, ref _digits, value); } - public static readonly RoutedEvent CompleteEvent = - RoutedEvent.Register( + public static readonly RoutedEvent CompleteEvent = + RoutedEvent.Register( nameof(Complete), RoutingStrategies.Bubble); - public event EventHandler Complete + public event EventHandler Complete { add => AddHandler(CompleteEvent, value); remove => RemoveHandler(CompleteEvent, value); } - static VerificationCode() + static PinCode() { - CountProperty.Changed.AddClassHandler((code, args) => code.OnCountOfDigitChanged(args)); - FocusableProperty.OverrideDefaultValue(true); + CountProperty.Changed.AddClassHandler((code, args) => code.OnCountOfDigitChanged(args)); + FocusableProperty.OverrideDefaultValue(true); } - public VerificationCode() + public PinCode() { InputMethod.SetIsInputMethodEnabled(this, false); } @@ -103,18 +104,21 @@ public class VerificationCode: TemplatedControl private void OnControlPressed(object? sender, PointerPressedEventArgs e) { - if (e.Source is Control) + if (e.Source is Control t) { - /* - var item = t.FindLogicalAncestorOfType(); + + var item = t.FindLogicalAncestorOfType(); if (item != null) { item.Focus(); _currentIndex = _itemsControl?.IndexFromContainer(item) ?? 0; } - */ - _currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1); - _itemsControl?.ContainerFromIndex(_currentIndex)?.Focus(); + else + { + _currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1); + _itemsControl?.ContainerFromIndex(_currentIndex)?.Focus(); + } + } e.Handled = true; } @@ -124,7 +128,7 @@ public class VerificationCode: TemplatedControl base.OnTextInput(e); if (e.Text?.Length == 1 && _currentIndex < Count) { - var presenter = _itemsControl?.ContainerFromIndex(_currentIndex) as VerificationCodeItem; + var presenter = _itemsControl?.ContainerFromIndex(_currentIndex) as PinCodeItem; if (presenter is null) return; char c = e.Text[0]; if (!Valid(c, this.Mode)) return; @@ -135,20 +139,20 @@ public class VerificationCode: TemplatedControl if (_currentIndex == Count) { CompleteCommand?.Execute(Digits); - RaiseEvent(new VerificationCodeCompleteEventArgs(Digits, CompleteEvent)); + RaiseEvent(new PinCodeCompleteEventArgs(Digits, CompleteEvent)); } } } - private bool Valid(char c, VerificationCodeMode mode) + private bool Valid(char c, PinCodeMode mode) { bool isDigit = char.IsDigit(c); bool isLetter = char.IsLetter(c); return mode switch { - VerificationCodeMode.Digit => isDigit, - VerificationCodeMode.Letter => isLetter, - VerificationCodeMode.Digit | VerificationCodeMode.Letter => isDigit || isLetter, + PinCodeMode.Digit => isDigit, + PinCodeMode.Letter => isLetter, + PinCodeMode.Digit | PinCodeMode.Letter => isDigit || isLetter, _ => true }; } @@ -159,7 +163,7 @@ public class VerificationCode: TemplatedControl if (e.Key == Key.Back && _currentIndex >= 0) { _currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1); - var presenter = _itemsControl?.ContainerFromIndex(_currentIndex) as VerificationCodeItem; + var presenter = _itemsControl?.ContainerFromIndex(_currentIndex) as PinCodeItem; if (presenter is null) return; Digits[_currentIndex] = string.Empty; presenter.Text = string.Empty; diff --git a/src/Ursa/Controls/VerificationCode/VerificationCodeCollection.cs b/src/Ursa/Controls/PinCode/PinCodeCollection.cs similarity index 69% rename from src/Ursa/Controls/VerificationCode/VerificationCodeCollection.cs rename to src/Ursa/Controls/PinCode/PinCodeCollection.cs index 0bf0dd5..24810e6 100644 --- a/src/Ursa/Controls/VerificationCode/VerificationCodeCollection.cs +++ b/src/Ursa/Controls/PinCode/PinCodeCollection.cs @@ -3,16 +3,16 @@ using Avalonia.Input; namespace Ursa.Controls; -public class VerificationCodeCollection: ItemsControl +public class PinCodeCollection: ItemsControl { protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) { - return NeedsContainer(item, out recycleKey); + return NeedsContainer(item, out recycleKey); } protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey) { - return new VerificationCodeItem() + return new PinCodeItem() { [InputMethod.IsInputMethodEnabledProperty] = false, }; diff --git a/src/Ursa/Controls/PinCode/PinCodeCompleteEventArgs.cs b/src/Ursa/Controls/PinCode/PinCodeCompleteEventArgs.cs new file mode 100644 index 0000000..7bf034d --- /dev/null +++ b/src/Ursa/Controls/PinCode/PinCodeCompleteEventArgs.cs @@ -0,0 +1,8 @@ +using Avalonia.Interactivity; + +namespace Ursa.Controls; + +public class PinCodeCompleteEventArgs(IList code, RoutedEvent? @event) : RoutedEventArgs(@event) +{ + public IList Code { get; } = code; +} \ No newline at end of file diff --git a/src/Ursa/Controls/VerificationCode/VerificationCodeItem.cs b/src/Ursa/Controls/PinCode/PinCodeItem.cs similarity index 78% rename from src/Ursa/Controls/VerificationCode/VerificationCodeItem.cs rename to src/Ursa/Controls/PinCode/PinCodeItem.cs index 081bc7f..f160498 100644 --- a/src/Ursa/Controls/VerificationCode/VerificationCodeItem.cs +++ b/src/Ursa/Controls/PinCode/PinCodeItem.cs @@ -4,9 +4,9 @@ using Avalonia.Data; namespace Ursa.Controls; -public class VerificationCodeItem: TemplatedControl +public class PinCodeItem: TemplatedControl { - public static readonly StyledProperty TextProperty = AvaloniaProperty.Register( + public static readonly StyledProperty TextProperty = AvaloniaProperty.Register( nameof(Text), defaultBindingMode: BindingMode.TwoWay); public string Text @@ -15,7 +15,7 @@ public class VerificationCodeItem: TemplatedControl set => SetValue(TextProperty, value); } - public static readonly StyledProperty PasswordCharProperty = AvaloniaProperty.Register( + public static readonly StyledProperty PasswordCharProperty = AvaloniaProperty.Register( nameof(PasswordChar), defaultBindingMode: BindingMode.TwoWay); public char PasswordChar diff --git a/src/Ursa/Controls/VerificationCode/VerificationCodeMode.cs b/src/Ursa/Controls/PinCode/PinCodeMode.cs similarity index 67% rename from src/Ursa/Controls/VerificationCode/VerificationCodeMode.cs rename to src/Ursa/Controls/PinCode/PinCodeMode.cs index 6caf485..5d929a1 100644 --- a/src/Ursa/Controls/VerificationCode/VerificationCodeMode.cs +++ b/src/Ursa/Controls/PinCode/PinCodeMode.cs @@ -1,7 +1,7 @@ namespace Ursa.Controls; [Flags] -public enum VerificationCodeMode +public enum PinCodeMode { Letter = 1, Digit = 2, diff --git a/src/Ursa/Controls/VerificationCode/VerificationCodeCompleteEventArgs.cs b/src/Ursa/Controls/VerificationCode/VerificationCodeCompleteEventArgs.cs deleted file mode 100644 index 7fc285e..0000000 --- a/src/Ursa/Controls/VerificationCode/VerificationCodeCompleteEventArgs.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Avalonia.Interactivity; - -namespace Ursa.Controls; - -public class VerificationCodeCompleteEventArgs(IList code, RoutedEvent? @event) : RoutedEventArgs(@event) -{ - public IList Code { get; } = code; -} \ No newline at end of file