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