AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.03k stars 2.25k forks source link

Mouse support for gesture recognizers #13645

Open MiKom opened 1 year ago

MiKom commented 1 year ago

Is your feature request related to a problem? Please describe.

I'm evaluating usage of Avalonia in an embedded industrial application. It will be deployed to a device with touch input. It uses gestures like ScrollGesture. On day-to-day basis, the application is developed and tested on a PC without actual touch input.

I'd like to be able to have some mode for gesture recognizers to also react to pointer events from regular mouse so that I don't have to deploy the application to the actual device for testing as it's detrimental to the developer feedback loop.

Describe the solution you'd like

Ideally, gesture recognizers could get some knob to also allow being triggered by mouse input. Not only by an actual touch device.

I experimentally commented out the checks for (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen) in ScrollGestureRecognizer.PointerPressed and PullGestureRecognizer.PointerPressed and the gesture page in the control gallery kind of worked.

There were some issues like pull gesture not recognizing that gesture ended if I released mouse button outside the window but it already was pretty useful.

Describe alternatives you've considered

I looked into adding my own gesture recognizer classes that allowed for mouse events but that's kind of tedious because it means I would have to essentially re-write the gesture recognizer functionality almost as-is in Avalonia. I could also override the classes and only re-write the PointerPressed method in them as it's protected. Not a big deal but IMO the framework could already provide that.

Additional context

Such functionality would be very useful for embedded applications which are a nice market for Avalonia to be present at.

MiKom commented 1 year ago

Hmm, I can't get away with just re-implementing PointerPressed as it uses private members. So this alternative is not viable.

ms1094392787 commented 11 months ago

Is the function of adding a recognizer to support the mouse implemented?

MiKom commented 11 months ago

Is the function of adding a recognizer to support the mouse implemented?

No, it's not. This issue is about such implementation.

cboittin commented 5 months ago

I would also be very interested in this, with the same use case.

JScrivo commented 1 week ago

+1, Similar use case, need to ensure gesture compatibility if the touch screen is configured for full mouse emulation mode.

MiKom commented 1 week ago

As a workaround I straight up copied ScrollGestureRecognizer.cs into my project (together with VelocityTracker.cs), did the required changes (commented out the checks for (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen) in ScrollGestureRecognizer.PointerPressed and PullGestureRecognizer.PointerPressed) and installed it as my own gesture recognizer:

<UserControl xmlns="https://github.com/avaloniaui"
             //...
             xmlns:gesture="clr-namespace:MyProject.Utilities.GestureRecognizers"
             //...
>
    //...

        <Border Name="StatusPageContent" Grid.Row="1"
                Background="White"
                BorderThickness="1" BorderBrush="{StaticResource PanelBorderBrush}"
                Margin="3 0 3 0">
            <Border.GestureRecognizers>
                <!-- TODO: replace with default gesture recognizer once https://github.com/AvaloniaUI/Avalonia/issues/13645 is done -->
                <gesture:MyCustomScrollGestureRecognizer CanHorizontallyScroll="True" />
            </Border.GestureRecognizers>
       ///
       </Border>
JScrivo commented 6 days ago

Thanks for the insight! In my test project I kinda just attached pointer event handlers directly to my controls in the view and implemented the swipe detection myself but this seems like a much more robust and simple solution.

aguahombre commented 2 days ago

I had the same issue and had to reinvent the wheel by duplicating the existing gestures, because Avalonia 11 changes has made creating custom gestures very difficult due to it making many of the related classes internal or private API. Please open up the internal inertia classes API to allow creation of custom gestures.

I think ScrollGestureRecognizer, should have a new property e.g. EnableMouseGesture to enable/disable mouse scroll gestures. It would be very simple to implement by making the code described by @MiKom conditional on the property. Make it default to disable and it would not be a breaking change.