-
-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
#618 clear icon focus handling
- Loading branch information
Showing
7 changed files
with
373 additions
and
257 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
src/UraniumUI/Handlers/StatefulContentViewHandler.Android.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#if ANDROID | ||
using Android.Views; | ||
using Microsoft.Maui.Platform; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using UraniumUI.Views; | ||
using static Microsoft.Maui.Controls.VisualStateManager; | ||
|
||
namespace UraniumUI.Handlers; | ||
public partial class StatefulContentViewHandler | ||
{ | ||
protected override ContentViewGroup CreatePlatformView() | ||
{ | ||
var platformView = base.CreatePlatformView(); | ||
|
||
platformView.Touch += OnTouch; | ||
platformView.Hover += NativeView_Hover; | ||
platformView.Click += PlatformView_Click; | ||
platformView.LongClick += PlatformView_LongClick; | ||
|
||
return platformView; | ||
} | ||
|
||
protected override void DisconnectHandler(ContentViewGroup platformView) | ||
{ | ||
platformView.Touch -= OnTouch; | ||
platformView.Hover -= NativeView_Hover; | ||
platformView.LongClick -= PlatformView_LongClick; | ||
base.DisconnectHandler(platformView); | ||
} | ||
|
||
private void NativeView_Hover(object sender, Android.Views.View.HoverEventArgs e) | ||
{ | ||
if (e.Event.Action == MotionEventActions.HoverEnter) | ||
{ | ||
GoToState(StatefulView, CommonStates.PointerOver); | ||
ExecuteCommandIfCan(StatefulView.HoverCommand); | ||
StatefulView.InvokeHovered(); | ||
return; | ||
} | ||
|
||
if (e.Event.Action == MotionEventActions.HoverExit) | ||
{ | ||
GoToState(StatefulView, CommonStates.Normal); | ||
ExecuteCommandIfCan(StatefulView.HoverExitCommand); | ||
StatefulView.InvokeHoverExited(); | ||
} | ||
} | ||
|
||
private void OnTouch(object sender, Android.Views.View.TouchEventArgs e) | ||
{ | ||
if (e.Event.Action == MotionEventActions.Down) | ||
{ | ||
GoToState(StatefulView, "Pressed"); | ||
ExecuteCommandIfCan(StatefulView.PressedCommand); | ||
StatefulView.InvokePressed(); | ||
e.Handled = false; | ||
} | ||
else if (e.Event.Action == MotionEventActions.Up) | ||
{ | ||
GoToState(StatefulView, CommonStates.Normal); | ||
e.Handled = false; | ||
} | ||
} | ||
|
||
private void PlatformView_Click(object sender, EventArgs e) | ||
{ | ||
GoToState(StatefulView, CommonStates.Normal); | ||
ExecuteCommandIfCan(StatefulView.TappedCommand); | ||
StatefulView.InvokeTapped(); | ||
} | ||
|
||
private void PlatformView_LongClick(object sender, Android.Views.View.LongClickEventArgs e) | ||
{ | ||
ExecuteCommandIfCan(StatefulView.LongPressCommand); | ||
StatefulView.InvokeLongPressed(); | ||
} | ||
|
||
public static void MapIsFocusable(StatefulContentViewHandler handler, StatefulContentView view) | ||
{ | ||
handler.StatefulView.IsFocusable = view.IsFocusable; | ||
} | ||
} | ||
#endif |
133 changes: 133 additions & 0 deletions
133
src/UraniumUI/Handlers/StatefulContentViewHandler.Apple.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
#if IOS || MACCATALYST | ||
using Foundation; | ||
using System.Diagnostics; | ||
using UraniumUI.Views; | ||
using UIKit; | ||
using static Microsoft.Maui.Controls.VisualStateManager; | ||
|
||
namespace UraniumUI.Handlers; | ||
public partial class StatefulContentViewHandler | ||
{ | ||
protected override Microsoft.Maui.Platform.ContentView CreatePlatformView() | ||
{ | ||
var platformView = new StatefulUIContentView(); | ||
platformView.IsFocusable = StatefulView.IsFocusable; | ||
return platformView; | ||
} | ||
|
||
protected override void ConnectHandler(Microsoft.Maui.Platform.ContentView platformView) | ||
{ | ||
platformView.AddGestureRecognizer(new UIContinousGestureRecognizer(Tapped)); | ||
if (OperatingSystem.IsIOSVersionAtLeast(13)) | ||
{ | ||
platformView.AddGestureRecognizer(new UIHoverGestureRecognizer(OnHover)); | ||
} | ||
platformView.AddGestureRecognizer(new UILongPressGestureRecognizer(OnLongPress)); | ||
base.ConnectHandler(platformView); | ||
} | ||
|
||
private void OnLongPress(UILongPressGestureRecognizer recognizer) | ||
{ | ||
ExecuteCommandIfCan(StatefulView.LongPressCommand); | ||
StatefulView.InvokeLongPressed(); | ||
} | ||
|
||
private void OnHover(UIHoverGestureRecognizer recognizer) | ||
{ | ||
switch (recognizer.State) | ||
{ | ||
case UIGestureRecognizerState.Began: | ||
|
||
GoToState(StatefulView, CommonStates.PointerOver); | ||
ExecuteCommandIfCan(StatefulView.HoverCommand); | ||
StatefulView.InvokeHovered(); | ||
break; | ||
case UIGestureRecognizerState.Ended: | ||
case UIGestureRecognizerState.Cancelled: | ||
case UIGestureRecognizerState.Failed: | ||
GoToState(StatefulView, CommonStates.Normal); | ||
ExecuteCommandIfCan(StatefulView.HoverExitCommand); | ||
StatefulView.InvokeHoverExited(); | ||
break; | ||
} | ||
} | ||
|
||
private void Tapped(UIGestureRecognizer recognizer) | ||
{ | ||
switch (recognizer.State) | ||
{ | ||
case UIGestureRecognizerState.Began: | ||
GoToState(StatefulView, "Pressed"); | ||
ExecuteCommandIfCan(StatefulView.PressedCommand); | ||
StatefulView.InvokePressed(); | ||
|
||
break; | ||
case UIGestureRecognizerState.Ended: | ||
GoToState(StatefulView, CommonStates.Normal); | ||
ExecuteCommandIfCan(StatefulView.TappedCommand); | ||
StatefulView.InvokeTapped(); | ||
|
||
//// TODO: Fix working of native gesture recognizers of MAUI | ||
foreach (var item in StatefulView.GestureRecognizers) | ||
{ | ||
Debug.WriteLine(item.GetType().Name); | ||
if (item is TapGestureRecognizer tgr) | ||
{ | ||
tgr.Command?.Execute(StatefulView); | ||
} | ||
} | ||
|
||
break; | ||
} | ||
} | ||
|
||
// TODO: Move it to the different file | ||
internal class UIContinousGestureRecognizer : UIGestureRecognizer | ||
{ | ||
private readonly Action<UIGestureRecognizer> action; | ||
|
||
public UIContinousGestureRecognizer(Action<UIGestureRecognizer> action) | ||
{ | ||
this.action = action; | ||
} | ||
|
||
public override void TouchesBegan(NSSet touches, UIEvent evt) | ||
{ | ||
State = UIGestureRecognizerState.Began; | ||
|
||
action(this); | ||
|
||
base.TouchesBegan(touches, evt); | ||
} | ||
|
||
public override void TouchesEnded(NSSet touches, UIEvent evt) | ||
{ | ||
State = UIGestureRecognizerState.Ended; | ||
|
||
action(this); | ||
|
||
base.TouchesEnded(touches, evt); | ||
} | ||
} | ||
|
||
public static void MapIsFocusable(StatefulContentViewHandler handler, StatefulContentView view) | ||
{ | ||
if (handler.PlatformView is StatefulUIContentView uiView) | ||
{ | ||
uiView.IsFocusable = view.IsFocusable; | ||
} | ||
} | ||
|
||
internal void UpdateFocusable() | ||
{ | ||
|
||
} | ||
|
||
// TODO: Move it to the different file | ||
public class StatefulUIContentView : Microsoft.Maui.Platform.ContentView | ||
{ | ||
public bool IsFocusable { get; set; } | ||
public override bool CanBecomeFocused => IsFocusable; | ||
} | ||
} | ||
#endif |
120 changes: 120 additions & 0 deletions
120
src/UraniumUI/Handlers/StatefulContentViewHandler.Windows.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#if WINDOWS | ||
using Microsoft.Maui.Platform; | ||
using Microsoft.UI.Xaml.Input; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using UraniumUI.Views; | ||
using static Microsoft.Maui.Controls.VisualStateManager; | ||
|
||
namespace UraniumUI.Handlers; | ||
public partial class StatefulContentViewHandler | ||
{ | ||
protected override ContentPanel CreatePlatformView() | ||
{ | ||
var platformView = base.CreatePlatformView(); | ||
|
||
platformView.AddHandler( | ||
Microsoft.UI.Xaml.Controls.Button.PointerPressedEvent, | ||
new PointerEventHandler(PlatformView_PointerPressed), true); | ||
|
||
platformView.AddHandler( | ||
Microsoft.UI.Xaml.Controls.Button.PointerReleasedEvent, | ||
new PointerEventHandler(PlatformView_PointerReleased), true); | ||
|
||
platformView.PointerEntered += PlatformView_PointerEntered; | ||
platformView.PointerExited += PlatformView_PointerExited; | ||
|
||
platformView.IsTabStop = true; | ||
platformView.UseSystemFocusVisuals = true; | ||
platformView.KeyDown += PlatformView_KeyDown; | ||
platformView.KeyUp += PlatformView_KeyUp; | ||
|
||
return platformView; | ||
} | ||
|
||
protected override void DisconnectHandler(ContentPanel platformView) | ||
{ | ||
platformView.PointerEntered -= PlatformView_PointerEntered; | ||
platformView.PointerExited -= PlatformView_PointerExited; | ||
platformView.KeyDown -= PlatformView_KeyDown; | ||
platformView.KeyUp -= PlatformView_KeyUp; | ||
base.DisconnectHandler(platformView); | ||
} | ||
|
||
private void PlatformView_PointerExited(object sender, PointerRoutedEventArgs e) | ||
{ | ||
GoToState(StatefulView, CommonStates.Normal); | ||
ExecuteCommandIfCan(StatefulView.HoverExitCommand); | ||
StatefulView.InvokeHoverExited(); | ||
} | ||
|
||
private void PlatformView_PointerEntered(object sender, PointerRoutedEventArgs e) | ||
{ | ||
GoToState(StatefulView, CommonStates.PointerOver); | ||
ExecuteCommandIfCan(StatefulView.HoverCommand); | ||
StatefulView.InvokeHovered(); | ||
} | ||
|
||
long lastPressed; | ||
|
||
private void PlatformView_PointerPressed(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e) | ||
{ | ||
lastPressed = DateTime.Now.Ticks; | ||
|
||
GoToState(StatefulView, "Pressed"); | ||
ExecuteCommandIfCan(StatefulView.PressedCommand); | ||
StatefulView.InvokePressed(); | ||
} | ||
|
||
private void PlatformView_PointerReleased(object sender, PointerRoutedEventArgs e) | ||
{ | ||
// TODO: Implement better. | ||
if (DateTime.Now.Ticks - lastPressed >= TimeSpan.TicksPerMillisecond * 500) | ||
{ | ||
ExecuteCommandIfCan(StatefulView.LongPressCommand); | ||
} | ||
|
||
GoToState(StatefulView, CommonStates.Normal); | ||
ExecuteCommandIfCan(StatefulView.TappedCommand); | ||
StatefulView.InvokeTapped(); | ||
} | ||
|
||
private void PlatformView_KeyDown(object sender, KeyRoutedEventArgs e) | ||
{ | ||
if (IsActionKey(e.Key)) | ||
{ | ||
GoToState(StatefulView, "Pressed"); | ||
ExecuteCommandIfCan(StatefulView.PressedCommand); | ||
StatefulView.InvokePressed(); | ||
} | ||
} | ||
|
||
private void PlatformView_KeyUp(object sender, KeyRoutedEventArgs e) | ||
{ | ||
if (IsActionKey(e.Key)) | ||
{ | ||
ExecuteCommandIfCan(StatefulView.TappedCommand); | ||
StatefulView.InvokeTapped(); | ||
GoToState(StatefulView, CommonStates.Normal); | ||
} | ||
} | ||
|
||
private bool IsActionKey(Windows.System.VirtualKey key) | ||
{ | ||
return key == Windows.System.VirtualKey.Enter || key == Windows.System.VirtualKey.Space; | ||
} | ||
|
||
internal void UpdateFocusable() | ||
{ | ||
PlatformView.IsTabStop = StatefulView.IsFocusable; | ||
} | ||
|
||
public static void MapIsFocusable(StatefulContentViewHandler handler, StatefulContentView view) | ||
{ | ||
handler.PlatformView.IsTabStop = view.IsFocusable; | ||
} | ||
} | ||
#endif |
Oops, something went wrong.