From 933104cd6fb622f75910a79ebbf79f44f05dd774 Mon Sep 17 00:00:00 2001 From: Rachel Kang Date: Mon, 22 Aug 2022 20:03:59 -0400 Subject: [PATCH 1/3] Initial PointerGestureRecognizer code --- .../GestureManager/GestureManager.Windows.cs | 91 ++++++++++++++ src/Controls/src/Core/PointerEventArgs.cs | 14 +++ .../src/Core/PointerGestureRecognizer.cs | 113 ++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 src/Controls/src/Core/PointerEventArgs.cs create mode 100644 src/Controls/src/Core/PointerGestureRecognizer.cs diff --git a/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs b/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs index da2ebf530530..4168543f8067 100644 --- a/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs +++ b/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Graphics; +using Microsoft.UI.Input; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Media.Imaging; @@ -103,6 +104,8 @@ public FrameworkElement? Control { _control.Tapped -= HandleTapped; _control.DoubleTapped -= HandleDoubleTapped; + //_control.PointerEntered -= HandlePointerEventExecuted; + //_control.PointerExited -= HandlePointerEventExecuted; } _control = value; @@ -321,6 +324,9 @@ void ClearContainerEventHandlers() _container.PointerExited -= OnPointerExited; _container.PointerReleased -= OnPointerReleased; _container.PointerCanceled -= OnPointerCanceled; + _container.PointerEntered -= OnPgrPointerEntered; + _container.PointerExited -= OnPgrPointerExited; + _container.PointerMoved -= OnPgrPointerMoved; } } @@ -351,6 +357,8 @@ protected virtual void Dispose(bool disposing) { _control.Tapped -= HandleTapped; _control.DoubleTapped -= HandleDoubleTapped; + //_control.PointerEntered -= HandlePointerEventExecuted; + //_control.PointerExited -= HandlePointerEventExecuted; } Control = null; @@ -511,6 +519,81 @@ void OnPointerReleased(object sender, PointerRoutedEventArgs e) PanComplete(true); } + void OnPgrPointerEntered(object sender, PointerRoutedEventArgs e) + { + var view = Element as View; + if (view == null) + return; + + var pointerPoint = e.GetCurrentPoint(Control); + var children = (view as IGestureController)?.GetChildElements(new Point(pointerPoint.Position.X, pointerPoint.Position.Y)); + + if (children != null) + foreach (var recognizer in children.GetChildGesturesFor()) + { + recognizer.SendPointerEntered(view); + } + + if (e.Handled) + return; + + IEnumerable pointerGestures = view.GestureRecognizers.GetGesturesFor(); + foreach (var recognizer in pointerGestures) + { + recognizer.SendPointerEntered(view); + } + } + + void OnPgrPointerExited(object sender, PointerRoutedEventArgs e) + { + var view = Element as View; + if (view == null) + return; + + var pointerPoint = e.GetCurrentPoint(Control); + var children = (view as IGestureController)?.GetChildElements(new Point(pointerPoint.Position.X, pointerPoint.Position.Y)); + + if (children != null) + foreach (var recognizer in children.GetChildGesturesFor()) + { + recognizer.SendPointerExited(view); + } + + if (e.Handled) + return; + + IEnumerable pointerGestures = view.GestureRecognizers.GetGesturesFor(); + foreach (var recognizer in pointerGestures) + { + recognizer.SendPointerExited(view); + } + } + + void OnPgrPointerMoved(object sender, PointerRoutedEventArgs e) + { + var view = Element as View; + if (view == null) + return; + + var pointerPoint = e.GetCurrentPoint(Control); + var children = (view as IGestureController)?.GetChildElements(new Point(pointerPoint.Position.X, pointerPoint.Position.Y)); + + if (children != null) + foreach (var recognizer in children.GetChildGesturesFor()) + { + recognizer.SendPointerMoved(view); + } + + if (e.Handled) + return; + + IEnumerable pointerGestures = view.GestureRecognizers.GetGesturesFor(); + foreach (var recognizer in pointerGestures) + { + recognizer.SendPointerMoved(view); + } + } + void OnTap(object sender, TappedRoutedEventArgs e) { var view = Element as View; @@ -671,6 +754,10 @@ void UpdatingGestureRecognizers() } } + _container.PointerEntered += OnPgrPointerEntered; + _container.PointerExited += OnPgrPointerExited; + _container.PointerMoved += OnPgrPointerMoved; + bool hasSwipeGesture = gestures.GetGesturesFor().GetEnumerator().MoveNext(); bool hasPinchGesture = gestures.GetGesturesFor().GetEnumerator().MoveNext(); bool hasPanGesture = gestures.GetGesturesFor().GetEnumerator().MoveNext(); @@ -710,5 +797,9 @@ void HandleDoubleTapped(object sender, DoubleTappedRoutedEventArgs doubleTappedR doubleTappedRoutedEventArgs.Handled = true; } + //void HandlePointerEventExecuted(object sender, PointerRoutedEventArgs pointerRoutedEventArgs) + //{ + // pointerRoutedEventArgs.Handled = true; + //} } } diff --git a/src/Controls/src/Core/PointerEventArgs.cs b/src/Controls/src/Core/PointerEventArgs.cs new file mode 100644 index 000000000000..d4d3d6457212 --- /dev/null +++ b/src/Controls/src/Core/PointerEventArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace Microsoft.Maui.Controls +{ + /// + /// Event arguments used for PointerGestureRecognizer. + /// + public class PointerEventArgs : EventArgs + { + public PointerEventArgs() + { + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/PointerGestureRecognizer.cs b/src/Controls/src/Core/PointerGestureRecognizer.cs new file mode 100644 index 000000000000..bafcc3403288 --- /dev/null +++ b/src/Controls/src/Core/PointerGestureRecognizer.cs @@ -0,0 +1,113 @@ +using System; +using System.ComponentModel; +using System.Windows.Input; + +namespace Microsoft.Maui.Controls +{ + /// + /// Provides pointer gesture recognition and events. + /// + public sealed class PointerGestureRecognizer : GestureRecognizer + { + public static readonly BindableProperty PointerEnteredCommandProperty = BindableProperty.Create(nameof(PointerEnteredCommand), typeof(ICommand), typeof(PointerGestureRecognizer), null); + + public static readonly BindableProperty PointerEnteredCommandParameterProperty = BindableProperty.Create(nameof(PointerEnteredCommandParameter), typeof(object), typeof(PointerGestureRecognizer), null); + + public static readonly BindableProperty PointerExitedCommandProperty = BindableProperty.Create(nameof(PointerExitedCommand), typeof(ICommand), typeof(PointerGestureRecognizer), null); + + public static readonly BindableProperty PointerExitedCommandParameterProperty = BindableProperty.Create(nameof(PointerExitedCommandParameter), typeof(object), typeof(PointerGestureRecognizer), null); + + public static readonly BindableProperty PointerMovedCommandProperty = BindableProperty.Create(nameof(PointerMovedCommand), typeof(ICommand), typeof(PointerGestureRecognizer), null); + + public static readonly BindableProperty PointerMovedCommandParameterProperty = BindableProperty.Create(nameof(PointerMovedCommandParameter), typeof(object), typeof(PointerGestureRecognizer), null); + + public PointerGestureRecognizer() + { + } + + //public ICommand Command + //{ + // get { return (ICommand)GetValue(CommandProperty); } + // set { SetValue(CommandProperty, value); } + //} + + //public object CommandParameter + //{ + // get { return GetValue(CommandParameterProperty); } + // set { SetValue(CommandParameterProperty, value); } + //} + + public event EventHandler PointerEntered; + public event EventHandler PointerExited; + public event EventHandler PointerMoved; + + PointerEventArgs args = new PointerEventArgs(); + + public ICommand PointerEnteredCommand + { + get { return (ICommand)GetValue(PointerEnteredCommandProperty); } + set { SetValue(PointerEnteredCommandProperty, value); } + } + + public ICommand PointerEnteredCommandParameter + { + get { return (ICommand)GetValue(PointerEnteredCommandParameterProperty); } + set { SetValue(PointerEnteredCommandParameterProperty, value); } + } + public ICommand PointerExitedCommand + { + get { return (ICommand)GetValue(PointerExitedCommandProperty); } + set { SetValue(PointerExitedCommandProperty, value); } + } + public ICommand PointerExitedCommandParameter + { + get { return (ICommand)GetValue(PointerExitedCommandParameterProperty); } + set { SetValue(PointerExitedCommandParameterProperty, value); } + } + + public ICommand PointerMovedCommand + { + get { return (ICommand)GetValue(PointerMovedCommandProperty); } + set { SetValue(PointerMovedCommandProperty, value); } + } + + public ICommand PointerMovedCommandParameter + { + get { return (ICommand)GetValue(PointerMovedCommandParameterProperty); } + set { SetValue(PointerMovedCommandParameterProperty, value); } + } + + internal void SendPointerEntered(View sender) + { + ICommand cmd = PointerEnteredCommand; + if (cmd != null && cmd.CanExecute(PointerEnteredCommandParameter)) + cmd.Execute(PointerEnteredCommandParameter); + + EventHandler handler = PointerEntered; + if (handler != null) + handler?.Invoke(sender, args); + } + + internal void SendPointerExited(View sender) + { + ICommand cmd = PointerExitedCommand; + if (cmd != null && cmd.CanExecute(PointerExitedCommandParameter)) + cmd.Execute(PointerExitedCommandParameter); + + EventHandler handler = PointerExited; + if (handler != null) + handler?.Invoke(sender, args); + } + + internal void SendPointerMoved(View sender) + { + ICommand cmd = PointerMovedCommand; + if (cmd != null && cmd.CanExecute(PointerMovedCommandParameter)) + cmd.Execute(PointerMovedCommandParameter); + + EventHandler handler = PointerMoved; + if (handler != null) + handler?.Invoke(sender, args); + } + } +} \ No newline at end of file From fb50c2dc7a8686bc90d091feccd3d8f1bd795960 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Wed, 24 Aug 2022 10:18:53 -0500 Subject: [PATCH 2/3] Update PointerGestureRecognizer.cs --- src/Controls/src/Core/PointerGestureRecognizer.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Controls/src/Core/PointerGestureRecognizer.cs b/src/Controls/src/Core/PointerGestureRecognizer.cs index bafcc3403288..b9677e840fc6 100644 --- a/src/Controls/src/Core/PointerGestureRecognizer.cs +++ b/src/Controls/src/Core/PointerGestureRecognizer.cs @@ -76,7 +76,12 @@ public ICommand PointerMovedCommandParameter get { return (ICommand)GetValue(PointerMovedCommandParameterProperty); } set { SetValue(PointerMovedCommandParameterProperty, value); } } - + + public Point? GetPosition(Element? relativeTo) + { + throw new NotImplementedException(); + } + internal void SendPointerEntered(View sender) { ICommand cmd = PointerEnteredCommand; @@ -110,4 +115,4 @@ internal void SendPointerMoved(View sender) handler?.Invoke(sender, args); } } -} \ No newline at end of file +} From 0520381205a8c00b09cdf2b04b030d986a160eee Mon Sep 17 00:00:00 2001 From: Rachel Kang Date: Wed, 24 Aug 2022 18:38:12 -0400 Subject: [PATCH 3/3] Clean up code and add nullability --- .../GestureManager/GestureManager.Windows.cs | 70 +++---------------- .../src/Core/PointerGestureRecognizer.cs | 26 +++---- 2 files changed, 19 insertions(+), 77 deletions(-) diff --git a/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs b/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs index 4168543f8067..8329113b599a 100644 --- a/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs +++ b/src/Controls/src/Core/Platform/GestureManager/GestureManager.Windows.cs @@ -104,8 +104,6 @@ public FrameworkElement? Control { _control.Tapped -= HandleTapped; _control.DoubleTapped -= HandleDoubleTapped; - //_control.PointerEntered -= HandlePointerEventExecuted; - //_control.PointerExited -= HandlePointerEventExecuted; } _control = value; @@ -357,8 +355,6 @@ protected virtual void Dispose(bool disposing) { _control.Tapped -= HandleTapped; _control.DoubleTapped -= HandleDoubleTapped; - //_control.PointerEntered -= HandlePointerEventExecuted; - //_control.PointerExited -= HandlePointerEventExecuted; } Control = null; @@ -519,57 +515,16 @@ void OnPointerReleased(object sender, PointerRoutedEventArgs e) PanComplete(true); } - void OnPgrPointerEntered(object sender, PointerRoutedEventArgs e) - { - var view = Element as View; - if (view == null) - return; - - var pointerPoint = e.GetCurrentPoint(Control); - var children = (view as IGestureController)?.GetChildElements(new Point(pointerPoint.Position.X, pointerPoint.Position.Y)); - - if (children != null) - foreach (var recognizer in children.GetChildGesturesFor()) - { - recognizer.SendPointerEntered(view); - } - - if (e.Handled) - return; - - IEnumerable pointerGestures = view.GestureRecognizers.GetGesturesFor(); - foreach (var recognizer in pointerGestures) - { - recognizer.SendPointerEntered(view); - } - } + void OnPgrPointerEntered(object sender, PointerRoutedEventArgs e) + => HandlePgrPointerEvent(e, (view, recognizer) => recognizer.SendPointerEntered(view)); void OnPgrPointerExited(object sender, PointerRoutedEventArgs e) - { - var view = Element as View; - if (view == null) - return; - - var pointerPoint = e.GetCurrentPoint(Control); - var children = (view as IGestureController)?.GetChildElements(new Point(pointerPoint.Position.X, pointerPoint.Position.Y)); - - if (children != null) - foreach (var recognizer in children.GetChildGesturesFor()) - { - recognizer.SendPointerExited(view); - } - - if (e.Handled) - return; - - IEnumerable pointerGestures = view.GestureRecognizers.GetGesturesFor(); - foreach (var recognizer in pointerGestures) - { - recognizer.SendPointerExited(view); - } - } + => HandlePgrPointerEvent(e, (view, recognizer) => recognizer.SendPointerExited(view)); void OnPgrPointerMoved(object sender, PointerRoutedEventArgs e) + => HandlePgrPointerEvent(e, (view, recognizer) => recognizer.SendPointerMoved(view)); + + private void HandlePgrPointerEvent(PointerRoutedEventArgs e, Action SendPointerEvent) { var view = Element as View; if (view == null) @@ -579,18 +534,20 @@ void OnPgrPointerMoved(object sender, PointerRoutedEventArgs e) var children = (view as IGestureController)?.GetChildElements(new Point(pointerPoint.Position.X, pointerPoint.Position.Y)); if (children != null) + { foreach (var recognizer in children.GetChildGesturesFor()) { - recognizer.SendPointerMoved(view); + SendPointerEvent.Invoke(view, recognizer); } + } if (e.Handled) return; - IEnumerable pointerGestures = view.GestureRecognizers.GetGesturesFor(); + var pointerGestures = view.GestureRecognizers.GetGesturesFor(); foreach (var recognizer in pointerGestures) { - recognizer.SendPointerMoved(view); + SendPointerEvent.Invoke(view, recognizer); } } @@ -796,10 +753,5 @@ void HandleDoubleTapped(object sender, DoubleTappedRoutedEventArgs doubleTappedR { doubleTappedRoutedEventArgs.Handled = true; } - - //void HandlePointerEventExecuted(object sender, PointerRoutedEventArgs pointerRoutedEventArgs) - //{ - // pointerRoutedEventArgs.Handled = true; - //} } } diff --git a/src/Controls/src/Core/PointerGestureRecognizer.cs b/src/Controls/src/Core/PointerGestureRecognizer.cs index b9677e840fc6..2ee9f52c2de5 100644 --- a/src/Controls/src/Core/PointerGestureRecognizer.cs +++ b/src/Controls/src/Core/PointerGestureRecognizer.cs @@ -1,5 +1,7 @@ +#nullable enable using System; using System.ComponentModel; +using Microsoft.Maui.Graphics; using System.Windows.Input; namespace Microsoft.Maui.Controls @@ -25,21 +27,9 @@ public PointerGestureRecognizer() { } - //public ICommand Command - //{ - // get { return (ICommand)GetValue(CommandProperty); } - // set { SetValue(CommandProperty, value); } - //} - - //public object CommandParameter - //{ - // get { return GetValue(CommandParameterProperty); } - // set { SetValue(CommandParameterProperty, value); } - //} - - public event EventHandler PointerEntered; - public event EventHandler PointerExited; - public event EventHandler PointerMoved; + public event EventHandler? PointerEntered; + public event EventHandler? PointerExited; + public event EventHandler? PointerMoved; PointerEventArgs args = new PointerEventArgs(); @@ -88,7 +78,7 @@ internal void SendPointerEntered(View sender) if (cmd != null && cmd.CanExecute(PointerEnteredCommandParameter)) cmd.Execute(PointerEnteredCommandParameter); - EventHandler handler = PointerEntered; + EventHandler? handler = PointerEntered; if (handler != null) handler?.Invoke(sender, args); } @@ -99,7 +89,7 @@ internal void SendPointerExited(View sender) if (cmd != null && cmd.CanExecute(PointerExitedCommandParameter)) cmd.Execute(PointerExitedCommandParameter); - EventHandler handler = PointerExited; + EventHandler? handler = PointerExited; if (handler != null) handler?.Invoke(sender, args); } @@ -110,7 +100,7 @@ internal void SendPointerMoved(View sender) if (cmd != null && cmd.CanExecute(PointerMovedCommandParameter)) cmd.Execute(PointerMovedCommandParameter); - EventHandler handler = PointerMoved; + EventHandler? handler = PointerMoved; if (handler != null) handler?.Invoke(sender, args); }