From 6ef0cf9e1c9296f862fb130697125816a63f0c1f Mon Sep 17 00:00:00 2001 From: rabbitism Date: Wed, 6 Nov 2024 14:38:39 +0800 Subject: [PATCH] feat: support paste. --- src/Ursa/Controls/PinCode/PinCode.cs | 24 ++++- .../Controls/PinCodeTests/PasteTest.cs | 89 +++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/PinCodeTests/PasteTest.cs diff --git a/src/Ursa/Controls/PinCode/PinCode.cs b/src/Ursa/Controls/PinCode/PinCode.cs index 1f6d2fa..4c9bc62 100644 --- a/src/Ursa/Controls/PinCode/PinCode.cs +++ b/src/Ursa/Controls/PinCode/PinCode.cs @@ -159,8 +159,30 @@ public class PinCode: TemplatedControl }; } - protected void OnPreviewKeyDown(KeyEventArgs e) + protected async void OnPreviewKeyDown(KeyEventArgs e) { + TextBox b = new TextBox(); + var pasteKeys = Application.Current?.PlatformSettings.HotkeyConfiguration.Paste; + if (pasteKeys?.Any(a => a.Matches(e)) == true) + { + var clipboard = TopLevel.GetTopLevel(this)?.Clipboard; + var text = await clipboard.GetTextAsync(); + if (text is not null) + { + var newText = text.Where(c => Valid(c, Mode)).Take(Count).ToArray(); + for (int i = 0; i < newText.Length; i++) + { + Digits[i] = newText[i].ToString(); + var presenter = _itemsControl?.ContainerFromIndex(i) as PinCodeItem; + if (presenter is not null) + { + presenter.Focus(); + presenter.Text = newText[i].ToString(); + } + } + } + return; + } if (e.Key == Key.Tab && e.Source is PinCodeItem) { _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 new file mode 100644 index 0000000..dc72db7 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/PinCodeTests/PasteTest.cs @@ -0,0 +1,89 @@ +using Avalonia.Controls; +using Avalonia.Headless; +using Avalonia.Headless.XUnit; +using Avalonia.Input; +using Avalonia.Threading; +using Ursa.Controls; + +namespace HeadlessTest.Ursa.Controls.PinCodeTests; + +public class PasteTest +{ + [AvaloniaFact] + public async void Paste_Should_Insert_Text() + { + var window = new Window(); + var pinCode = new PinCode() + { + Count = 4, + }; + window.Content = pinCode; + window.Show(); + var clipboard = window.Clipboard; + Assert.NotNull(clipboard); + await clipboard.SetTextAsync("abcd"); + pinCode.Focus(); + window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); + // add await for clipboard processing. + await Task.Delay(1); + Assert.Equal("abcd", string.Join("", pinCode.Digits)); + } + + [AvaloniaFact] + public async void Paste_Should_Insert_Text_When_Text_Is_Shorter() + { + var window = new Window(); + var pinCode = new PinCode() + { + Count = 4, + }; + window.Content = pinCode; + window.Show(); + var clipboard = window.Clipboard; + Assert.NotNull(clipboard); + await clipboard.SetTextAsync("abc"); + pinCode.Focus(); + window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); + await Task.Delay(1); + Assert.Equal("abc", string.Join("", pinCode.Digits)); + } + + [AvaloniaFact] + public async void Paste_Should_Insert_Text_When_Text_Is_Longer() + { + var window = new Window(); + var pinCode = new PinCode() + { + Count = 4, + }; + window.Content = pinCode; + window.Show(); + var clipboard = window.Clipboard; + Assert.NotNull(clipboard); + await clipboard.SetTextAsync("abcde"); + pinCode.Focus(); + window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); + await Task.Delay(1); + Assert.Equal("abcd", string.Join("", pinCode.Digits)); + } + + [AvaloniaFact] + public async void Paste_Should_Not_Insert_Text_When_Text_Is_In_Invalid_Mode() + { + var window = new Window(); + var pinCode = new PinCode() + { + Count = 4, + Mode = PinCodeMode.Digit, + }; + window.Content = pinCode; + window.Show(); + var clipboard = window.Clipboard; + Assert.NotNull(clipboard); + await clipboard.SetTextAsync("abcde"); + pinCode.Focus(); + window.KeyPressQwerty(PhysicalKey.V, RawInputModifiers.Control); + await Task.Delay(1); + Assert.Equal("", string.Join("", pinCode.Digits)); + } +} \ No newline at end of file