From cef56d67a569a18eb1f6c9dcc378b6eb59a271e9 Mon Sep 17 00:00:00 2001 From: Matthew Rajala Date: Wed, 8 May 2024 12:21:05 -0400 Subject: [PATCH 1/2] feat: added inputextensions returntype property --- doc/helpers/Input-extensions.md | 18 ++-- .../Controls/InputExtensionsSamplePage.xaml | 12 ++- .../Behaviors/InputExtensions.cs | 96 ++++++++++++++++++- 3 files changed, 117 insertions(+), 9 deletions(-) diff --git a/doc/helpers/Input-extensions.md b/doc/helpers/Input-extensions.md index 6eaf913e2..fcf585485 100644 --- a/doc/helpers/Input-extensions.md +++ b/doc/helpers/Input-extensions.md @@ -8,13 +8,14 @@ Provides various attached properties for _input controls_, such as `TextBox` and ## Attached Properties -| Property | Type | Description | -|------------------------|-----------|--------------------------------------------------------------------------------------------| -| `AutoDismiss` | `bool` | Whether the soft-keyboard will be dismissed when the enter key is pressed. | -| `AutoFocusNext` | `bool` | Whether the focus will move to the next focusable element when the enter key is pressed.\* | -| `AutoFocusNextElement` | `Control` | Sets the next control to focus when the enter key is pressed.\* | +| Property | Type | Description | +|------------------------|--------------|-----------------------------------------------------------------------------------------------------------------------------------| +| `AutoDismiss` | `bool` | Whether the soft keyboard will be dismissed when the enter key is pressed. | +| `AutoFocusNext` | `bool` | Whether the focus will move to the next focusable element when the enter key is pressed.\* | +| `AutoFocusNextElement` | `Control` | Sets the next control to focus when the enter key is pressed.\* | +| `ReturnType` | `ReturnType` | The type of return button on a soft keyboard. It can be one of the following options: __Default, Done, Go, Next, Search, Send__. | -`AutoFocusNext` and `AutoFocusNextElement`\*: Having either or both of the two properties set will enable the focus next behavior. `AutoFocusNextElement` will take precedences over `AutoFocusNext` when both are set. +`AutoFocusNext` and `AutoFocusNextElement`\*: Having either or both of the two properties set will enable the focus next behavior. `AutoFocusNextElement` will take precedence over `AutoFocusNext` when both are set. ### Remarks @@ -35,6 +36,9 @@ xmlns:utu="using:Uno.Toolkit.UI" - + + + + ``` diff --git a/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/InputExtensionsSamplePage.xaml b/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/InputExtensionsSamplePage.xaml index 3e72a9152..c12597a6a 100644 --- a/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/InputExtensionsSamplePage.xaml +++ b/samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/Controls/InputExtensionsSamplePage.xaml @@ -31,10 +31,20 @@ - + + + + + + + + + + + diff --git a/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs b/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs index 44f1f9f7b..8164fd9a8 100644 --- a/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs +++ b/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs @@ -11,6 +11,12 @@ using Windows.System; using Windows.UI.ViewManagement; +#if __ANDROID__ +using Android.Views.InputMethods; +#elif __IOS__ +using UIKit; +#endif + #if IS_WINUI using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -27,10 +33,36 @@ public static class InputExtensions { private static readonly ILogger _logger = typeof(InputExtensions).Log(); + public enum ReturnType { + Default, + Done, + Go, + Next, + Search, + Send + } + + #region DependencyProperty: ReturnType + + /// + /// Backing property for what type of return the soft keyboard will show. + /// + public static DependencyProperty ReturnTypeProperty { [DynamicDependency(nameof(GetReturnType))] get; } = DependencyProperty.RegisterAttached( + "ReturnType", + typeof(ReturnType), + typeof(InputExtensions), + new PropertyMetadata(ReturnType.Default, OnReturnTypeChanged)); + + [DynamicDependency(nameof(SetReturnType))] + public static ReturnType GetReturnType(DependencyObject obj) => (ReturnType)obj.GetValue(ReturnTypeProperty); + [DynamicDependency(nameof(GetReturnType))] + public static void SetReturnType(DependencyObject obj, ReturnType value) => obj.SetValue(ReturnTypeProperty, value); + + #endregion #region DependencyProperty: AutoDismiss /// - /// Backing property for whether the soft-keyboard will be dismissed when the enter key is pressed. + /// Backing property for whether the soft keyboard will be dismissed when the enter key is pressed. /// public static DependencyProperty AutoDismissProperty { [DynamicDependency(nameof(GetAutoDismiss))] get; } = DependencyProperty.RegisterAttached( "AutoDismiss", @@ -109,6 +141,36 @@ internal static bool IsEnterCommandSupportedFor(DependencyObject host) return host is TextBox || host is PasswordBox; } + private static void OnReturnTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + if (sender is Control control && (sender is TextBox || sender is PasswordBox) && e.NewValue is ReturnType returnType) + { +#if __ANDROID__ + ImeAction imeAction = GetImeActionFromReturnType(returnType); + + if (control is TextBox textBox) + { + textBox.ImeOptions = imeAction; + } + else if (control is PasswordBox passwordBox) + { + passwordBox.ImeOptions = imeAction; + } +#elif __IOS__ + UIReturnKeyType returnKeyType = GetReturnKeyTypeFromReturnType(returnType); + + if (control is TextBox textBox) + { + textBox.ReturnKeyType = returnKeyType; + } + else if (control is PasswordBox passwordBox) + { + passwordBox.ReturnKeyType = returnKeyType; + } +#endif + } + } + private static void OnAutoDismissChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) => UpdateSubscription(sender); private static void OnAutoFocusNextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) => UpdateSubscription(sender); private static void OnAutoFocusNextElementChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) => UpdateSubscription(sender); @@ -177,5 +239,37 @@ private static void OnUIElementKeyUp(object sender, KeyRoutedEventArgs e) _ => default, }; } + +#if __ANDROID__ + private static ImeAction GetImeActionFromReturnType(ReturnType returnType) + { + switch (returnType) + { + case ReturnType.Next: return ImeAction.Next; + case ReturnType.Go: return ImeAction.Go; + case ReturnType.Search: return ImeAction.Search; + case ReturnType.Send: return ImeAction.Send; + case ReturnType.Done: return ImeAction.Done; + case ReturnType.Default: + default: return ImeAction.Unspecified; + } + } +#endif + +#if __IOS__ + private static UIReturnKeyType GetReturnKeyTypeFromReturnType(ReturnType returnType) + { + switch (returnType) + { + case ReturnType.Next: return UIReturnKeyType.Next; + case ReturnType.Go: return UIReturnKeyType.Go; + case ReturnType.Search: return UIReturnKeyType.Search; + case ReturnType.Send: return UIReturnKeyType.Send; + case ReturnType.Done: return UIReturnKeyType.Done; + case ReturnType.Default: + default: return UIReturnKeyType.Default; + } + } +#endif } } From 97bc9f31411c1ab264ffda9d908e597b6a182e80 Mon Sep 17 00:00:00 2001 From: rajamatt Date: Fri, 10 May 2024 14:22:04 -0400 Subject: [PATCH 2/2] chore: refactoring returntype --- doc/helpers/Input-extensions.md | 12 ++--- .../Behaviors/InputExtensions.cs | 54 +++++++++---------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/doc/helpers/Input-extensions.md b/doc/helpers/Input-extensions.md index fcf585485..8874f6f67 100644 --- a/doc/helpers/Input-extensions.md +++ b/doc/helpers/Input-extensions.md @@ -8,12 +8,12 @@ Provides various attached properties for _input controls_, such as `TextBox` and ## Attached Properties -| Property | Type | Description | -|------------------------|--------------|-----------------------------------------------------------------------------------------------------------------------------------| -| `AutoDismiss` | `bool` | Whether the soft keyboard will be dismissed when the enter key is pressed. | -| `AutoFocusNext` | `bool` | Whether the focus will move to the next focusable element when the enter key is pressed.\* | -| `AutoFocusNextElement` | `Control` | Sets the next control to focus when the enter key is pressed.\* | -| `ReturnType` | `ReturnType` | The type of return button on a soft keyboard. It can be one of the following options: __Default, Done, Go, Next, Search, Send__. | +| Property | Type | Description | +|------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------| +| `AutoDismiss` | `bool` | Whether the soft keyboard will be dismissed when the enter key is pressed. | +| `AutoFocusNext` | `bool` | Whether the focus will move to the next focusable element when the enter key is pressed.\* | +| `AutoFocusNextElement` | `Control` | Sets the next control to focus when the enter key is pressed.\* | +| `ReturnType` | `ReturnType` | The type of return button on a soft keyboard for Android/iOS. It can be one of the following options: __Default, Done, Go, Next, Search, Send__. | `AutoFocusNext` and `AutoFocusNextElement`\*: Having either or both of the two properties set will enable the focus next behavior. `AutoFocusNextElement` will take precedence over `AutoFocusNext` when both are set. diff --git a/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs b/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs index 8164fd9a8..c56d38203 100644 --- a/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs +++ b/src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs @@ -143,27 +143,31 @@ internal static bool IsEnterCommandSupportedFor(DependencyObject host) private static void OnReturnTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { - if (sender is Control control && (sender is TextBox || sender is PasswordBox) && e.NewValue is ReturnType returnType) + if (sender is TextBox || sender is PasswordBox) { + if (e.NewValue is not ReturnType returnType) + { + returnType = ReturnType.Default; + } #if __ANDROID__ ImeAction imeAction = GetImeActionFromReturnType(returnType); - if (control is TextBox textBox) + if (sender is TextBox textBox) { textBox.ImeOptions = imeAction; } - else if (control is PasswordBox passwordBox) + else if (sender is PasswordBox passwordBox) { passwordBox.ImeOptions = imeAction; } #elif __IOS__ UIReturnKeyType returnKeyType = GetReturnKeyTypeFromReturnType(returnType); - if (control is TextBox textBox) + if (sender is TextBox textBox) { textBox.ReturnKeyType = returnKeyType; } - else if (control is PasswordBox passwordBox) + else if (sender is PasswordBox passwordBox) { passwordBox.ReturnKeyType = returnKeyType; } @@ -241,35 +245,27 @@ private static void OnUIElementKeyUp(object sender, KeyRoutedEventArgs e) } #if __ANDROID__ - private static ImeAction GetImeActionFromReturnType(ReturnType returnType) + private static ImeAction GetImeActionFromReturnType(ReturnType returnType) => returnType switch { - switch (returnType) - { - case ReturnType.Next: return ImeAction.Next; - case ReturnType.Go: return ImeAction.Go; - case ReturnType.Search: return ImeAction.Search; - case ReturnType.Send: return ImeAction.Send; - case ReturnType.Done: return ImeAction.Done; - case ReturnType.Default: - default: return ImeAction.Unspecified; - } - } + ReturnType.Next => ImeAction.Next, + ReturnType.Go => ImeAction.Go, + ReturnType.Search => ImeAction.Search, + ReturnType.Send => ImeAction.Send, + ReturnType.Done => ImeAction.Done, + ReturnType.Default or _ => ImeAction.Unspecified + }; #endif #if __IOS__ - private static UIReturnKeyType GetReturnKeyTypeFromReturnType(ReturnType returnType) + private static UIReturnKeyType GetReturnKeyTypeFromReturnType(ReturnType returnType) => returnType switch { - switch (returnType) - { - case ReturnType.Next: return UIReturnKeyType.Next; - case ReturnType.Go: return UIReturnKeyType.Go; - case ReturnType.Search: return UIReturnKeyType.Search; - case ReturnType.Send: return UIReturnKeyType.Send; - case ReturnType.Done: return UIReturnKeyType.Done; - case ReturnType.Default: - default: return UIReturnKeyType.Default; - } - } + ReturnType.Next => UIReturnKeyType.Next, + ReturnType.Go => UIReturnKeyType.Go, + ReturnType.Search => UIReturnKeyType.Search, + ReturnType.Send => UIReturnKeyType.Send, + ReturnType.Done => UIReturnKeyType.Done, + ReturnType.Default or _ => UIReturnKeyType.Default + }; #endif } }