diff --git a/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizer.cs b/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizer.cs index 2cb97b4707..cdd7ef7cd2 100644 --- a/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizer.cs +++ b/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizer.cs @@ -3,6 +3,7 @@ public abstract class GestureRecognizer : StyledElement { protected internal IInputElement? Target { get; internal set; } + protected internal GestureRecognizerCollection? GestureRecognizerCollection { get; internal set; } protected abstract void PointerPressed(PointerPressedEventArgs e); protected abstract void PointerReleased(PointerReleasedEventArgs e); diff --git a/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs b/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs index 05dce8214b..a17c8cdcc7 100644 --- a/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs +++ b/src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using Avalonia.Controls; @@ -24,8 +25,14 @@ namespace Avalonia.Input.GestureRecognizers _recognizers = new List(); } + if(recognizer.GestureRecognizerCollection != null && recognizer.GestureRecognizerCollection != this) + { + throw new InvalidOperationException("The gesture recognizer has already been added to a gesture recognizer collection"); + } + _recognizers.Add(recognizer); recognizer.Target = _inputElement; + recognizer.GestureRecognizerCollection = this; // Hacks to make bindings work @@ -59,6 +66,20 @@ namespace Avalonia.Input.GestureRecognizers return e.Handled; } + internal void HandleCaptureLost(IPointer pointer) + { + if (_recognizers == null || pointer is not Pointer p) + return; + + foreach (var r in _recognizers) + { + if (p.CapturedGestureRecognizer == r) + continue; + + r.PointerCaptureLostInternal(pointer); + } + } + internal bool HandlePointerReleased(PointerReleasedEventArgs e) { if (_recognizers == null) diff --git a/src/Avalonia.Base/Input/GestureRecognizers/PinchGestureRecognizer.cs b/src/Avalonia.Base/Input/GestureRecognizers/PinchGestureRecognizer.cs index b02c82a066..2a6dcba0f0 100644 --- a/src/Avalonia.Base/Input/GestureRecognizers/PinchGestureRecognizer.cs +++ b/src/Avalonia.Base/Input/GestureRecognizers/PinchGestureRecognizer.cs @@ -1,4 +1,5 @@ -using Avalonia.Input.GestureRecognizers; +using System.Diagnostics; +using Avalonia.Input.GestureRecognizers; namespace Avalonia.Input { @@ -61,6 +62,7 @@ namespace Avalonia.Input { if (Target != null && Target is Visual visual && (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen)) { + Debug.WriteLine($"Pointer with ID: {e.Pointer.Id} pressed"); if (_firstContact == null) { _firstContact = e.Pointer; @@ -110,6 +112,9 @@ namespace Avalonia.Input _secondContact = null; } + + Debug.WriteLine($"Pointer with ID: {pointer.Id} removed"); + Target?.RaiseEvent(new PinchEndedEventArgs()); } } diff --git a/src/Avalonia.Base/Input/InputElement.cs b/src/Avalonia.Base/Input/InputElement.cs index 46f543d25b..91dae88dbb 100644 --- a/src/Avalonia.Base/Input/InputElement.cs +++ b/src/Avalonia.Base/Input/InputElement.cs @@ -230,6 +230,7 @@ namespace Avalonia.Input PointerMovedEvent.AddClassHandler((x, e) => x.OnGesturePointerMoved(e), handledEventsToo: true); PointerPressedEvent.AddClassHandler((x, e) => x.OnGesturePointerPressed(e), handledEventsToo: true); PointerReleasedEvent.AddClassHandler((x, e) => x.OnGesturePointerReleased(e), handledEventsToo: true); + PointerCaptureLostEvent.AddClassHandler((x, e) => x.OnGesturePointerCaptureLost(e), handledEventsToo: true); } public InputElement() @@ -615,6 +616,11 @@ namespace Avalonia.Input } } + private void OnGesturePointerCaptureLost(PointerCaptureLostEventArgs e) + { + _gestureRecognizers?.HandleCaptureLost(e.Pointer); + } + private void OnGesturePointerPressed(PointerPressedEventArgs e) { if (!e.IsGestureRecognitionSkipped) diff --git a/src/Avalonia.Base/Input/Pointer.cs b/src/Avalonia.Base/Input/Pointer.cs index 5744ddf963..f0e6e5bc64 100644 --- a/src/Avalonia.Base/Input/Pointer.cs +++ b/src/Avalonia.Base/Input/Pointer.cs @@ -91,12 +91,17 @@ namespace Avalonia.Input internal void CaptureGestureRecognizer(GestureRecognizer? gestureRecognizer) { if (CapturedGestureRecognizer != gestureRecognizer) + { CapturedGestureRecognizer?.PointerCaptureLostInternal(this); + } + + CapturedGestureRecognizer = gestureRecognizer; if (gestureRecognizer != null) + { + gestureRecognizer.GestureRecognizerCollection?.HandleCaptureLost(this); Capture(null); - - CapturedGestureRecognizer = gestureRecognizer; + } } } }