Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added inputextensions returntype property #1128

Merged
merged 3 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 11 additions & 7 deletions doc/helpers/Input-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ Provides various attached properties for _input controls_, such as `TextBox` and

rajamatt marked this conversation as resolved.
Show resolved Hide resolved
## 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__. |
rajamatt marked this conversation as resolved.
Show resolved Hide resolved

`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

Expand All @@ -35,6 +36,9 @@ xmlns:utu="using:Uno.Toolkit.UI"
<TextBox x:Name="Input3" utu:InputExtensions.AutoFocusNextElement="{Binding ElementName=Input1}" />
<TextBox x:Name="Input4" utu:InputExtensions.AutoFocusNextElement="{Binding ElementName=Input3}" />

<!-- Dismiss soft-keyboard on enter -->
<!-- Dismiss soft keyboard on enter -->
<TextBox utu:InputExtensions.AutoDismiss="True" />

<!-- Soft keyboard with send as return button -->
<TextBox utu:InputExtensions.ReturnType="Send" />
```
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,20 @@
</StackPanel>

<StackPanel Spacing="8">
<TextBlock Text="Dismiss soft-keyboard on enter" />
<TextBlock Text="Dismiss soft keyboard on enter" />
<TextBox utu:InputExtensions.AutoDismiss="True" />
</StackPanel>

<StackPanel Spacing="8">
<TextBlock Text="Soft keyboards of different return types" />
<TextBox Text="Default" utu:InputExtensions.ReturnType="Default" />
<TextBox Text="Done" utu:InputExtensions.ReturnType="Done" />
<TextBox Text="Go" utu:InputExtensions.ReturnType="Go" />
<TextBox Text="Next" utu:InputExtensions.ReturnType="Next" />
<TextBox Text="Search" utu:InputExtensions.ReturnType="Search" />
<TextBox Text="Send" utu:InputExtensions.ReturnType="Send" />
</StackPanel>

</StackPanel>
</DataTemplate>
</sample:SamplePageLayout.DesignAgnosticTemplate>
Expand Down
96 changes: 95 additions & 1 deletion src/Uno.Toolkit.UI/Behaviors/InputExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
}
rajamatt marked this conversation as resolved.
Show resolved Hide resolved

#region DependencyProperty: ReturnType

/// <summary>
/// Backing property for what type of return the soft keyboard will show.
/// </summary>
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

/// <summary>
/// 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.
/// </summary>
public static DependencyProperty AutoDismissProperty { [DynamicDependency(nameof(GetAutoDismiss))] get; } = DependencyProperty.RegisterAttached(
"AutoDismiss",
Expand Down Expand Up @@ -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)
rajamatt marked this conversation as resolved.
Show resolved Hide resolved
rajamatt marked this conversation as resolved.
Show resolved Hide resolved
{
#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);
Expand Down Expand Up @@ -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;
}
rajamatt marked this conversation as resolved.
Show resolved Hide resolved
}
#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;
}
rajamatt marked this conversation as resolved.
Show resolved Hide resolved
}
#endif
rajamatt marked this conversation as resolved.
Show resolved Hide resolved
}
}