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

KeyboardExtensions #1064

Merged
merged 30 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ffefe46
KeyboardManager
PureWeen Mar 5, 2023
ea810c2
- simplify references
PureWeen Mar 5, 2023
ec9a2d0
Merge branch 'main' into keyboardmanager
PureWeen Mar 8, 2023
f93dd04
- review comments and rename to KeyboardExtensions
PureWeen Mar 8, 2023
2720ec5
Updates summaries and APIs
PureWeen Mar 8, 2023
c3dac98
- fix text
PureWeen Mar 8, 2023
7f91327
- add tizen file
PureWeen Mar 8, 2023
8dde14d
Review comments
PureWeen Mar 9, 2023
4151a9b
Merge branch 'main' into keyboardmanager
VladislavAntonyuk Mar 9, 2023
8c85440
Update src/CommunityToolkit.Maui.Core/Platform/KeyboardManager/Keyboa…
PureWeen Mar 9, 2023
5af7b0c
Update src/CommunityToolkit.Maui.Core/Platform/KeyboardManager/Keyboa…
PureWeen Mar 9, 2023
db453ce
- value task
PureWeen Mar 9, 2023
196af53
Merge branch 'main' into keyboardmanager
brminnick Mar 10, 2023
d500dfc
Handle Exceptions using `showKeyboardTCS.SetException(e)`
brminnick Mar 10, 2023
2364741
Update Formatting. Change `[UnsupportedOSPlatform("MacOS")]` -> `[Uns…
brminnick Mar 10, 2023
f83114a
Update Formatting
brminnick Mar 10, 2023
e4cc32f
Remove Unused Controls. Add `KeyboardExtension` label
brminnick Mar 10, 2023
57421dc
Handle Exceptions. Update Formatting. Remove Unused Code
brminnick Mar 10, 2023
24b7540
Rename Folder from `KeyboardManager` -> `KeyboardExtensions`
brminnick Mar 10, 2023
2a93247
Remove unused usings
brminnick Mar 10, 2023
9743c8d
Throw `NotImplementedException`
brminnick Mar 10, 2023
a6be3c8
Update Formatting
brminnick Mar 10, 2023
88c7457
Add `TryGetInputPane()`
brminnick Mar 10, 2023
ffffbea
Merge branch 'main' into keyboardmanager
pictos Mar 10, 2023
63483a7
Add Tizen implementation
JoonghyunCho Mar 13, 2023
bc8ba16
Merge branch 'main' into keyboardmanager
PureWeen Mar 14, 2023
f822d32
- add comment and code to better validate Keyboard Extensions
PureWeen Mar 14, 2023
41f1141
Merge branch 'main' into keyboardmanager
PureWeen Mar 17, 2023
4fdfae0
Merge branch 'main' into keyboardmanager
brminnick Apr 11, 2023
bdaee76
Merge branch 'main' into keyboardmanager
jfversluis Apr 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
using CommunityToolkit.Maui.Sample.ViewModels.Converters;
using CommunityToolkit.Maui.Sample.ViewModels.Essentials;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;
using CommunityToolkit.Maui.Sample.ViewModels.ImageSources;
using CommunityToolkit.Maui.Sample.ViewModels.Layouts;
using CommunityToolkit.Maui.Sample.ViewModels.Views;
Expand Down Expand Up @@ -87,6 +88,7 @@ public partial class AppShell : Shell

// Add Extensions View Models
CreateViewModelMapping<ColorAnimationExtensionsPage, ColorAnimationExtensionsViewModel, ExtensionsGalleryPage, ExtensionsGalleryViewModel>(),
CreateViewModelMapping<KeyboardManagerExtensionsPage, KeyboardManagerExtensionsViewModel, ExtensionsGalleryPage, ExtensionsGalleryViewModel>(),

// Add ImageSources View Models
CreateViewModelMapping<GravatarImageSourcePage, GravatarImageSourceViewModel, ImageSourcesGalleryPage, ImageSourcesGalleryViewModel>(),
Expand Down
2 changes: 2 additions & 0 deletions samples/CommunityToolkit.Maui.Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
using CommunityToolkit.Maui.Sample.ViewModels.Converters;
using CommunityToolkit.Maui.Sample.ViewModels.Essentials;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;
using CommunityToolkit.Maui.Sample.ViewModels.ImageSources;
using CommunityToolkit.Maui.Sample.ViewModels.Layouts;
using CommunityToolkit.Maui.Sample.ViewModels.Views;
Expand Down Expand Up @@ -156,6 +157,7 @@ static void RegisterViewsAndViewModels(in IServiceCollection services)

// Add Extensions Pages + ViewModels
services.AddTransientWithShellRoute<ColorAnimationExtensionsPage, ColorAnimationExtensionsViewModel>();
services.AddTransientWithShellRoute<KeyboardManagerExtensionsPage, KeyboardManagerExtensionsViewModel>();

// Add ImageSources Pages + ViewModels
services.AddTransientWithShellRoute<GravatarImageSourcePage, GravatarImageSourceViewModel>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<pages:BasePage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages"
x:Class="CommunityToolkit.Maui.Sample.Pages.Extensions.KeyboardManagerExtensionsPage"
Title="KeyboardManagerExtensionsPage"
xmlns:vm="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Extensions"
x:TypeArguments="vm:KeyboardManagerExtensionsViewModel"
x:DataType="vm:KeyboardManagerExtensionsViewModel">
<pages:BasePage.Content>
<VerticalStackLayout Spacing="12">
<Entry Text="Hello" x:Name="entry"></Entry>
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
<Button Text="Show Keyboard" CommandParameter="{x:Reference Name=entry}" Command="{Binding ShowKeyboard}"></Button>
<Button Text="Hide Keyboard" CommandParameter="{x:Reference Name=entry}" Command="{Binding HideKeyboard}"></Button>
</VerticalStackLayout>
</pages:BasePage.Content>
</pages:BasePage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using CommunityToolkit.Maui.Sample.ViewModels.Converters;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;

namespace CommunityToolkit.Maui.Sample.Pages.Extensions;

public partial class KeyboardManagerExtensionsPage : BasePage<KeyboardManagerExtensionsViewModel>
{
public KeyboardManagerExtensionsPage(KeyboardManagerExtensionsViewModel viewModel) :
base(viewModel)
{
InitializeComponent();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using CommunityToolkit.Maui.Extensions;
using CommunityToolkit.Maui.Core.Platform;
using CommunityToolkit.Maui.Extensions;
using CommunityToolkit.Maui.Sample.Models;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;

namespace CommunityToolkit.Maui.Sample.ViewModels.Converters;

Expand All @@ -10,6 +12,9 @@ public ExtensionsGalleryViewModel()
{
SectionModel.Create<ColorAnimationExtensionsViewModel>(nameof(ColorAnimationExtensions),
"Extension methods that provide color animations"),

SectionModel.Create<KeyboardManagerExtensionsViewModel>(nameof(KeyboardManager),
"Extension methods that provide keyboard interactions"),
})
{

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Maui.Core.Platform;

namespace CommunityToolkit.Maui.Sample.ViewModels.Extensions;
public class KeyboardManagerExtensionsViewModel : BaseViewModel
{
public Command<ITextInput> ShowKeyboard { get; }
public Command<ITextInput> HideKeyboard { get; }

public KeyboardManagerExtensionsViewModel()
{
ShowKeyboard = new Command<ITextInput>(OnShowKeyboard);
HideKeyboard = new Command<ITextInput>(OnHideKeyboard);
}

void OnHideKeyboard(ITextInput view)
{
view.HideKeyboard();
}

void OnShowKeyboard(ITextInput view)
{
view.ShowKeyboard();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using Android.Content;
using Android.Views;
using Android.Views.InputMethods;
using AndroidX.Core.View;
using Microsoft.Maui.Platform;
using AView = Android.Views.View;

namespace CommunityToolkit.Maui.Core.Platform;

public static partial class KeyboardManager
{
static void HideKeyboard(this AView inputView)
{
if (inputView?.Context == null)
{
throw new ArgumentNullException(nameof(inputView), "Must be set before the keyboard can be hidden.");
}

var focusedView = inputView.Context?.GetActivity()?.Window?.CurrentFocus;
AView tokenView = focusedView ?? inputView;

using (var inputMethodManager = (InputMethodManager)tokenView.Context?.GetSystemService(Context.InputMethodService)!)
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
{
var windowToken = tokenView.WindowToken;
if (windowToken != null && inputMethodManager != null)
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
{
inputMethodManager.HideSoftInputFromWindow(windowToken, HideSoftInputFlags.None);
}
}
}

static void ShowKeyboard(this TextView inputView)
{
if (inputView?.Context == null)
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
{
throw new ArgumentNullException(nameof(inputView), "Must be set before the keyboard can be shown.");
}

using (var inputMethodManager = (InputMethodManager)inputView.Context.GetSystemService(Context.InputMethodService)!)
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
{
// The zero value for the second parameter comes from
// https://developer.android.com/reference/android/view/inputmethod/InputMethodManager#showSoftInput(android.view.View,%20int)
// Apparently there's no named value for zero in this case
inputMethodManager?.ShowSoftInput(inputView, 0);
}
}

static void ShowKeyboard(this AView view)
{
switch (view)
{
case TextView textView:
textView.ShowKeyboard();
break;
case ViewGroup viewGroup:
viewGroup.GetFirstChildOfType<TextView>()?.ShowKeyboard();
break;
}
}

static bool IsSoftKeyboardVisible(this AView view)
{
var insets = ViewCompat.GetRootWindowInsets(view);
if (insets == null)
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
{
return false;
}

var result = insets.IsVisible(WindowInsetsCompat.Type.Ime());
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using UIKit;

namespace CommunityToolkit.Maui.Core.Platform;

public static partial class KeyboardManager
{
static void HideKeyboard(this UIView inputView) => inputView.ResignFirstResponder();

static void ShowKeyboard(this UIView inputView) => inputView.BecomeFirstResponder();

static bool IsSoftKeyboardVisible(this UIView inputView) => inputView.IsFirstResponder;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using UIKit;

namespace CommunityToolkit.Maui.Core.Platform;

[UnsupportedOSPlatform("MacOS")]
public static partial class KeyboardManager
{
static void HideKeyboard(this UIView inputView)
{
throw new NotSupportedException("MacOS does not currently support opening the SoftKeyboard");
}

static void ShowKeyboard(this UIView inputView)
{
throw new NotSupportedException("MacOS does not currently support opening the SoftKeyboard");
}

static bool IsSoftKeyboardVisible(this UIView inputView)
{
throw new NotSupportedException("MacOS does not currently support opening the SoftKeyboard");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Diagnostics;
using System.Reflection.Metadata;

namespace CommunityToolkit.Maui.Core.Platform;

public static partial class KeyboardManager
{
static void HideKeyboard(this object _)
{
}

static void ShowKeyboard(this object _)
{
}

static bool IsSoftKeyboardVisible(this object _)
{
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.Maui.Core.Extensions;
using Microsoft.Maui.Dispatching;

#if IOS || MACCATALYST
using PlatformView = UIKit.UIView;
#elif ANDROID
using PlatformView = Android.Views.View;
#elif WINDOWS
using PlatformView = Microsoft.UI.Xaml.FrameworkElement;
#elif TIZEN
using PlatformView = Tizen.NUI.BaseComponents.View;
#elif (NETSTANDARD || !PLATFORM) || (NET6_0_OR_GREATER && !IOS && !ANDROID && !TIZEN)
using PlatformView = System.Object;
using IPlatformViewHandler = Microsoft.Maui.IViewHandler;
#endif

namespace CommunityToolkit.Maui.Core.Platform;

/// <summary>
///
/// </summary>
public static partial class KeyboardManager
{
static bool TryGetPlatformView(
this ITextInput textInput,
[NotNullWhen(true)] out PlatformView? platformView,
[NotNullWhen(true)] out IPlatformViewHandler? handler,
[NotNullWhen(true)] out IView? view)
{
if (textInput is not IView iView ||
iView.Handler is not IPlatformViewHandler platformViewHandler)
{
platformView = null;
handler = null;
view = null;
return false;
}

if (iView.Handler?.PlatformView is not PlatformView platform)
{

platformView = null;
handler = null;
view = null;
return false;
}

handler = platformViewHandler;
platformView = platform;
view = iView;

return true;
}

/// <summary>
///
/// </summary>
/// <param name="targetView"></param>
public static void HideKeyboard(this ITextInput targetView)
{
if (!targetView.TryGetPlatformView(
out var platformView,
out _,
out _))
{
return;
}

HideKeyboard(platformView);
}

/// <summary>
///
/// </summary>
/// <param name="targetView"></param>
public static void ShowKeyboard(this ITextInput targetView)
{
if (!targetView.TryGetPlatformView(
out var platformView,
out var handler,
out var view))
{
return;
}

if (!view.IsFocused)
{
handler.Invoke(nameof(IView.Focus), new FocusRequest(false));
handler.GetRequiredService<IDispatcher>()
.Dispatch(() =>
{
platformView.ShowKeyboard();
});
}
else
{
platformView.ShowKeyboard();
}
}

/// <summary>
///
/// </summary>
/// <param name="targetView"></param>
/// <returns></returns>
public static bool IsSoftKeyboardVisible(this ITextInput targetView)
{
if (!targetView.TryGetPlatformView(
out var platformView,
out _,
out _))
{
return false;
}

return platformView.IsSoftKeyboardVisible();
}
}
Loading