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

Implement PointerGestureRecognizer #9592

Merged
merged 12 commits into from
Aug 26, 2022
Merged

Implement PointerGestureRecognizer #9592

merged 12 commits into from
Aug 26, 2022

Conversation

rachelkang
Copy link
Member

@rachelkang rachelkang commented Aug 23, 2022

PointerGestureRecognizer

Description

Implementation of PointerGestureRecognizer with PointerEntered, PointerExited, and PointerMoved events.

Windows implementation complete!
Mac implementation TBD

Implements part of #9139

API Changes

Maui.Controls

namespace Microsoft.Maui.Controls
{
  /// <summary>
  /// Provides pointer gesture recognition and events.
  /// </summary>
  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 event EventHandler<PointerEventArgs>? PointerEntered;
      public event EventHandler<PointerEventArgs>? PointerExited;
      public event EventHandler<PointerEventArgs>? PointerMoved;
namespace Microsoft.Maui.Controls
{
    /// <summary>
    /// Arguments for PointerGestureRecognizer events.
    /// </summary>
    public class PointerEventArgs : EventArgs
    {
        public virtual Point? GetPosition(Element? relativeTo);
    }
}

Scenario

<Label 
  x:Name="hoverLabel"
  FontSize="24"
  Text="Hover me!">
  <Label.GestureRecognizers>
      <PointerGestureRecognizer PointerEntered="HoverBegan" PointerExited="HoverEnded" PointerMoved="HoverMoved" />
  </Label.GestureRecognizers>
</Label>
<Label x:Name="positionLabel" Text="Hover above label to reveal pointer position"/>
private void HoverBegan(object sender, PointerEventArgs e)
{
    hoverLabel.Text = "Thanks for hovering me!";
}

private void HoverEnded(object sender, PointerEventArgs e)
{
    hoverLabel.Text = "Hover me again!";
    positionLabel.Text = "Hover above label to reveal pointer position again";
}

private void HoverMoved(object sender, PointerEventArgs e)
{
    positionLabel.Text = $"Pointer position is at: {e.GetPosition((View)sender)}";
}

Screenshots

aka quick home video since my screen record isn't working at the moment :p

IMG_5070.MOV

Copy link
Member

@jfversluis jfversluis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor code things mainly :)

@jfversluis jfversluis added the legacy-area-desktop Windows / WinUI / Project Reunion & Mac Catalyst / macOS specifics (Menus & other Controls)) label Aug 23, 2022
@rachelkang rachelkang changed the title [WIP] Implement PointerGestureRecognizer Implement PointerGestureRecognizer Aug 24, 2022
@rachelkang rachelkang marked this pull request as ready for review August 24, 2022 22:44
@PureWeen PureWeen requested a review from rmarinho August 26, 2022 15:34
Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API seems fine and it works. just little comments on code style but shouldn't block the merge.

  • Needs public api file changes
  • Maybe add some xml doc comments

Good stuff Rachel

InitializeComponent();
}

private void HoverBegan(object sender, PointerEventArgs e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just little thing we don't use the "private" keyword because it's the default

}
}

Point? GetPosition(IElement? relativeTo, RoutedEventArgs e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why there wouldn't be a Position?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using Point from Maui.Graphics - to my knowledge, there's no Position there

ccing @PureWeen who implemented GetPosition in his other PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user passes an invalid element
The other option here would be to throw an exception

internal void SendPointerMoved(View sender, Func<IElement?, Point?>? getPosition)
{
ICommand cmd = PointerMovedCommand;
if (cmd != null && cmd.CanExecute(PointerMovedCommandParameter))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (cmd != null && cmd.CanExecute(PointerMovedCommandParameter))
if (cmd?.CanExecute(PointerMovedCommandParameter))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intellisense tells me this won't work since it can't implicitly convert type bool? to bool, so I'll leave this one as is for now.
Alternatively, I can cast it as a bool, but I prefer to leave it as is. Let me know what you think!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do it like this

cmd?.CanExecute(PointerMovedCommandParameter) == true

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh of course, fixed!

cmd.Execute(PointerMovedCommandParameter);

EventHandler<PointerEventArgs>? handler = PointerMoved;
if (handler != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think you need this check since your are doing handler?. bellow

@github-actions github-actions bot locked and limited conversation to collaborators Dec 18, 2023
@Eilon Eilon added t/desktop The issue relates to desktop scenarios (MacOS/MacCatalyst/Windows/WinUI/WinAppSDK) area-gestures Gesture types and removed legacy-area-desktop Windows / WinUI / Project Reunion & Mac Catalyst / macOS specifics (Menus & other Controls)) labels May 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-gestures Gesture types fixed-in-7.0.0-rc.1.6683 t/desktop The issue relates to desktop scenarios (MacOS/MacCatalyst/Windows/WinUI/WinAppSDK)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants