diff --git a/src/Ursa/Controls/PinCode/PinCode.cs b/src/Ursa/Controls/PinCode/PinCode.cs index a04fb6d..a1957be 100644 --- a/src/Ursa/Controls/PinCode/PinCode.cs +++ b/src/Ursa/Controls/PinCode/PinCode.cs @@ -11,12 +11,12 @@ using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; [TemplatePart(PART_ItemsControl, typeof(ItemsControl))] -public class PinCode: 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( nameof(CompleteCommand)); @@ -57,18 +57,18 @@ public class PinCode: TemplatedControl public static readonly DirectProperty> DigitsProperty = AvaloniaProperty.RegisterDirect>( nameof(Digits), o => o.Digits); - + private IList _digits = []; public IList Digits { get => _digits; private set => SetAndRaise(DigitsProperty, ref _digits, value); } - + public static readonly RoutedEvent CompleteEvent = RoutedEvent.Register( nameof(Complete), RoutingStrategies.Bubble); - + public event EventHandler Complete { add => AddHandler(CompleteEvent, value); @@ -79,7 +79,7 @@ public class PinCode: TemplatedControl { CountProperty.Changed.AddClassHandler((code, args) => code.OnCountOfDigitChanged(args)); FocusableProperty.OverrideDefaultValue(true); - KeyDownEvent.AddClassHandler((o,e)=>o.OnPreviewKeyDown(e), RoutingStrategies.Tunnel); + KeyDownEvent.AddClassHandler((o, e) => o.OnPreviewKeyDown(e), RoutingStrategies.Tunnel); } public PinCode() @@ -119,7 +119,7 @@ public class PinCode: TemplatedControl _currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1); _itemsControl?.ContainerFromIndex(_currentIndex)?.Focus(); } - + } e.Handled = true; } @@ -181,6 +181,11 @@ public class PinCode: TemplatedControl presenter.Text = newText[i].ToString(); } } + if (newText.Length == Count) + { + CompleteCommand?.Execute(Digits); + RaiseEvent(new PinCodeCompleteEventArgs(Digits, CompleteEvent)); + } } return; } @@ -210,7 +215,7 @@ public class PinCode: TemplatedControl _currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1); _itemsControl?.ContainerFromIndex(_currentIndex)?.Focus(); } - else if(e.Key is Key.Right or Key.FnRightArrow) + else if (e.Key is Key.Right or Key.FnRightArrow) { _currentIndex++; _currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1); diff --git a/tests/HeadlessTest.Ursa/Controls/PinCodeTests/PasteTest.cs b/tests/HeadlessTest.Ursa/Controls/PinCodeTests/PasteTest.cs index dc72db7..fad68f8 100644 --- a/tests/HeadlessTest.Ursa/Controls/PinCodeTests/PasteTest.cs +++ b/tests/HeadlessTest.Ursa/Controls/PinCodeTests/PasteTest.cs @@ -3,6 +3,7 @@ using Avalonia.Headless; using Avalonia.Headless.XUnit; using Avalonia.Input; using Avalonia.Threading; +using CommunityToolkit.Mvvm.Input; using Ursa.Controls; namespace HeadlessTest.Ursa.Controls.PinCodeTests; @@ -13,9 +14,11 @@ public class PasteTest public async void Paste_Should_Insert_Text() { var window = new Window(); + bool commandInvoked = false; var pinCode = new PinCode() { Count = 4, + CompleteCommand = new RelayCommand(() => commandInvoked = true), }; window.Content = pinCode; window.Show(); @@ -27,15 +30,18 @@ public class PasteTest // add await for clipboard processing. await Task.Delay(1); Assert.Equal("abcd", string.Join("", pinCode.Digits)); + Assert.True(commandInvoked); } [AvaloniaFact] public async void Paste_Should_Insert_Text_When_Text_Is_Shorter() { var window = new Window(); + bool commandInvoked = false; var pinCode = new PinCode() { Count = 4, + CompleteCommand = new RelayCommand(() => commandInvoked = true), }; window.Content = pinCode; window.Show(); @@ -46,15 +52,18 @@ public class PasteTest window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); await Task.Delay(1); Assert.Equal("abc", string.Join("", pinCode.Digits)); + Assert.False(commandInvoked); } [AvaloniaFact] public async void Paste_Should_Insert_Text_When_Text_Is_Longer() { var window = new Window(); + bool commandInvoked = false; var pinCode = new PinCode() { Count = 4, + CompleteCommand = new RelayCommand(() => commandInvoked = true), }; window.Content = pinCode; window.Show(); @@ -65,16 +74,19 @@ public class PasteTest window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); await Task.Delay(1); Assert.Equal("abcd", string.Join("", pinCode.Digits)); + Assert.True(commandInvoked); } [AvaloniaFact] public async void Paste_Should_Not_Insert_Text_When_Text_Is_In_Invalid_Mode() { var window = new Window(); + var commandInvoked = false; var pinCode = new PinCode() { Count = 4, Mode = PinCodeMode.Digit, + CompleteCommand = new RelayCommand(() => commandInvoked = true), }; window.Content = pinCode; window.Show(); @@ -85,5 +97,6 @@ public class PasteTest window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); await Task.Delay(1); Assert.Equal("", string.Join("", pinCode.Digits)); + Assert.False(commandInvoked); } } \ No newline at end of file