Browse Source

replace IGestureRecognizer with abstrac GestureRecognizer. remove related obsolete interfaces.

pull/11518/head
Emmanuel Hansen 3 years ago
parent
commit
0042c19121
  1. 23
      src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizer.cs
  2. 29
      src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs
  3. 24
      src/Avalonia.Base/Input/GestureRecognizers/IGestureRecognizer.cs
  4. 20
      src/Avalonia.Base/Input/GestureRecognizers/PinchGestureRecognizer.cs
  5. 18
      src/Avalonia.Base/Input/GestureRecognizers/PullGestureRecognizer.cs
  6. 20
      src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs
  7. 24
      src/Avalonia.Base/Input/MouseDevice.cs
  8. 22
      src/Avalonia.Base/Input/PenDevice.cs
  9. 4
      src/Avalonia.Base/Input/Pointer.cs

23
src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizer.cs

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Input.GestureRecognizers
{
public abstract class GestureRecognizer : StyledElement
{
public abstract IInputElement? Target { get; }
public abstract void Initialize(IInputElement target);
public abstract void PointerPressed(PointerPressedEventArgs e);
public abstract void PointerReleased(PointerReleasedEventArgs e);
public abstract void PointerMoved(PointerEventArgs e);
public abstract void PointerCaptureLost(IPointer pointer);
protected void Capture(IPointer pointer)
{
(pointer as Pointer)?.CaptureGestureRecognizer(this);
}
}
}

29
src/Avalonia.Base/Input/GestureRecognizers/GestureRecognizerCollection.cs

@ -6,26 +6,26 @@ using Avalonia.Reactive;
namespace Avalonia.Input.GestureRecognizers namespace Avalonia.Input.GestureRecognizers
{ {
public class GestureRecognizerCollection : IReadOnlyCollection<IGestureRecognizer>, IGestureRecognizerActionsDispatcher public class GestureRecognizerCollection : IReadOnlyCollection<GestureRecognizer>
{ {
private readonly IInputElement _inputElement; private readonly IInputElement _inputElement;
private List<IGestureRecognizer>? _recognizers; private List<GestureRecognizer>? _recognizers;
public GestureRecognizerCollection(IInputElement inputElement) public GestureRecognizerCollection(IInputElement inputElement)
{ {
_inputElement = inputElement; _inputElement = inputElement;
} }
public void Add(IGestureRecognizer recognizer) public void Add(GestureRecognizer recognizer)
{ {
if (_recognizers == null) if (_recognizers == null)
{ {
// We initialize the collection when the first recognizer is added // We initialize the collection when the first recognizer is added
_recognizers = new List<IGestureRecognizer>(); _recognizers = new List<GestureRecognizer>();
} }
_recognizers.Add(recognizer); _recognizers.Add(recognizer);
recognizer.Initialize(_inputElement, this); recognizer.Initialize(_inputElement);
// Hacks to make bindings work // Hacks to make bindings work
@ -38,16 +38,15 @@ namespace Avalonia.Input.GestureRecognizers
} }
} }
static readonly List<IGestureRecognizer> s_Empty = new List<IGestureRecognizer>(); static readonly List<GestureRecognizer> s_Empty = new List<GestureRecognizer>();
public IEnumerator<IGestureRecognizer> GetEnumerator() public IEnumerator<GestureRecognizer> GetEnumerator()
=> _recognizers?.GetEnumerator() ?? s_Empty.GetEnumerator(); => _recognizers?.GetEnumerator() ?? s_Empty.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public int Count => _recognizers?.Count ?? 0; public int Count => _recognizers?.Count ?? 0;
internal bool HandlePointerPressed(PointerPressedEventArgs e) internal bool HandlePointerPressed(PointerPressedEventArgs e)
{ {
if (_recognizers == null) if (_recognizers == null)
@ -91,19 +90,5 @@ namespace Avalonia.Input.GestureRecognizers
} }
return e.Handled; return e.Handled;
} }
void IGestureRecognizerActionsDispatcher.Capture(IPointer pointer, IGestureRecognizer recognizer)
{
var p = pointer as Pointer;
p?.CaptureGestureRecognizer(recognizer);
foreach (var r in _recognizers!)
{
if (r != recognizer)
r.PointerCaptureLost(pointer);
}
}
} }
} }

24
src/Avalonia.Base/Input/GestureRecognizers/IGestureRecognizer.cs

@ -1,24 +0,0 @@
namespace Avalonia.Input.GestureRecognizers
{
public interface IGestureRecognizer
{
IInputElement? Target { get; }
void Initialize(IInputElement target, IGestureRecognizerActionsDispatcher actions);
void PointerPressed(PointerPressedEventArgs e);
void PointerReleased(PointerReleasedEventArgs e);
void PointerMoved(PointerEventArgs e);
void PointerCaptureLost(IPointer pointer);
}
public interface IGestureRecognizerActionsDispatcher
{
void Capture(IPointer pointer, IGestureRecognizer recognizer);
}
public enum GestureRecognizerResult
{
None,
Capture,
ReleaseCapture
}
}

20
src/Avalonia.Base/Input/GestureRecognizers/PinchGestureRecognizer.cs

@ -2,10 +2,9 @@
namespace Avalonia.Input namespace Avalonia.Input
{ {
public class PinchGestureRecognizer : AvaloniaObject, IGestureRecognizer public class PinchGestureRecognizer : GestureRecognizer
{ {
private IInputElement? _target; private IInputElement? _target;
private IGestureRecognizerActionsDispatcher? _actions;
private float _initialDistance; private float _initialDistance;
private IPointer? _firstContact; private IPointer? _firstContact;
private Point _firstPoint; private Point _firstPoint;
@ -13,12 +12,11 @@ namespace Avalonia.Input
private Point _secondPoint; private Point _secondPoint;
private Point _origin; private Point _origin;
public IInputElement? Target => _target; public override IInputElement? Target => _target;
public void Initialize(IInputElement target, IGestureRecognizerActionsDispatcher actions) public override void Initialize(IInputElement target)
{ {
_target = target; _target = target;
_actions = actions;
} }
private void OnPointerPressed(object? sender, PointerPressedEventArgs e) private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
@ -31,12 +29,12 @@ namespace Avalonia.Input
PointerReleased(e); PointerReleased(e);
} }
public void PointerCaptureLost(IPointer pointer) public override void PointerCaptureLost(IPointer pointer)
{ {
RemoveContact(pointer); RemoveContact(pointer);
} }
public void PointerMoved(PointerEventArgs e) public override void PointerMoved(PointerEventArgs e)
{ {
if (_target != null && _target is Visual visual) if (_target != null && _target is Visual visual)
{ {
@ -67,7 +65,7 @@ namespace Avalonia.Input
} }
} }
public void PointerPressed(PointerPressedEventArgs e) public override void PointerPressed(PointerPressedEventArgs e)
{ {
if (_target != null && _target is Visual visual && (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen)) if (_target != null && _target is Visual visual && (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen))
{ {
@ -94,13 +92,13 @@ namespace Avalonia.Input
_origin = new Point((_firstPoint.X + _secondPoint.X) / 2.0f, (_firstPoint.Y + _secondPoint.Y) / 2.0f); _origin = new Point((_firstPoint.X + _secondPoint.X) / 2.0f, (_firstPoint.Y + _secondPoint.Y) / 2.0f);
_actions!.Capture(_firstContact, this); Capture(_firstContact);
_actions!.Capture(_secondContact, this); Capture(_secondContact);
} }
} }
} }
public void PointerReleased(PointerReleasedEventArgs e) public override void PointerReleased(PointerReleasedEventArgs e)
{ {
RemoveContact(e.Pointer); RemoveContact(e.Pointer);
} }

18
src/Avalonia.Base/Input/GestureRecognizers/PullGestureRecognizer.cs

@ -3,12 +3,11 @@ using Avalonia.Input.GestureRecognizers;
namespace Avalonia.Input namespace Avalonia.Input
{ {
public class PullGestureRecognizer : AvaloniaObject, IGestureRecognizer public class PullGestureRecognizer : GestureRecognizer
{ {
internal static int MinPullDetectionSize = 50; internal static int MinPullDetectionSize = 50;
private IInputElement? _target; private IInputElement? _target;
private IGestureRecognizerActionsDispatcher? _actions;
private Point _initialPosition; private Point _initialPosition;
private int _gestureId; private int _gestureId;
private IPointer? _tracking; private IPointer? _tracking;
@ -26,7 +25,7 @@ namespace Avalonia.Input
set => SetValue(PullDirectionProperty, value); set => SetValue(PullDirectionProperty, value);
} }
public IInputElement? Target => _target; public override IInputElement? Target => _target;
public PullGestureRecognizer(PullDirection pullDirection) public PullGestureRecognizer(PullDirection pullDirection)
{ {
@ -35,13 +34,12 @@ namespace Avalonia.Input
public PullGestureRecognizer() { } public PullGestureRecognizer() { }
public void Initialize(IInputElement target, IGestureRecognizerActionsDispatcher actions) public override void Initialize(IInputElement target)
{ {
_target = target; _target = target;
_actions = actions;
} }
public void PointerCaptureLost(IPointer pointer) public override void PointerCaptureLost(IPointer pointer)
{ {
if (_tracking == pointer) if (_tracking == pointer)
{ {
@ -49,12 +47,12 @@ namespace Avalonia.Input
} }
} }
public void PointerMoved(PointerEventArgs e) public override void PointerMoved(PointerEventArgs e)
{ {
if (_tracking == e.Pointer && _target is Visual visual) if (_tracking == e.Pointer && _target is Visual visual)
{ {
var currentPosition = e.GetPosition(visual); var currentPosition = e.GetPosition(visual);
_actions!.Capture(e.Pointer, this); Capture(e.Pointer);
e.PreventGestureRecognition(); e.PreventGestureRecognition();
Vector delta = default; Vector delta = default;
@ -94,7 +92,7 @@ namespace Avalonia.Input
} }
} }
public void PointerPressed(PointerPressedEventArgs e) public override void PointerPressed(PointerPressedEventArgs e)
{ {
if (_target != null && _target is Visual visual && (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen)) if (_target != null && _target is Visual visual && (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen))
{ {
@ -129,7 +127,7 @@ namespace Avalonia.Input
} }
} }
public void PointerReleased(PointerReleasedEventArgs e) public override void PointerReleased(PointerReleasedEventArgs e)
{ {
if (_tracking == e.Pointer && _pullInProgress) if (_tracking == e.Pointer && _pullInProgress)
{ {

20
src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs

@ -4,7 +4,7 @@ using Avalonia.Threading;
namespace Avalonia.Input.GestureRecognizers namespace Avalonia.Input.GestureRecognizers
{ {
public class ScrollGestureRecognizer : AvaloniaObject, IGestureRecognizer public class ScrollGestureRecognizer : GestureRecognizer
{ {
// Pixels per second speed that is considered to be the stop of inertial scroll // Pixels per second speed that is considered to be the stop of inertial scroll
internal const double InertialScrollSpeedEnd = 5; internal const double InertialScrollSpeedEnd = 5;
@ -19,7 +19,6 @@ namespace Avalonia.Input.GestureRecognizers
private Point _trackedRootPoint; private Point _trackedRootPoint;
private IPointer? _tracking; private IPointer? _tracking;
private IInputElement? _target; private IInputElement? _target;
private IGestureRecognizerActionsDispatcher? _actions;
private int _gestureId; private int _gestureId;
private Point _pointerPressedPoint; private Point _pointerPressedPoint;
private VelocityTracker? _velocityTracker; private VelocityTracker? _velocityTracker;
@ -93,15 +92,14 @@ namespace Avalonia.Input.GestureRecognizers
set => SetAndRaise(ScrollStartDistanceProperty, ref _scrollStartDistance, value); set => SetAndRaise(ScrollStartDistanceProperty, ref _scrollStartDistance, value);
} }
public IInputElement? Target => _target; public override IInputElement? Target => _target;
public void Initialize(IInputElement target, IGestureRecognizerActionsDispatcher actions) public override void Initialize(IInputElement target)
{ {
_target = target; _target = target;
_actions = actions;
} }
public void PointerPressed(PointerPressedEventArgs e) public override void PointerPressed(PointerPressedEventArgs e)
{ {
if (e.Pointer.IsPrimary && if (e.Pointer.IsPrimary &&
(e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen)) (e.Pointer.Type == PointerType.Touch || e.Pointer.Type == PointerType.Pen))
@ -112,8 +110,8 @@ namespace Avalonia.Input.GestureRecognizers
_trackedRootPoint = _pointerPressedPoint = e.GetPosition((Visual?)_target); _trackedRootPoint = _pointerPressedPoint = e.GetPosition((Visual?)_target);
} }
} }
public void PointerMoved(PointerEventArgs e) public override void PointerMoved(PointerEventArgs e)
{ {
if (e.Pointer == _tracking) if (e.Pointer == _tracking)
{ {
@ -133,7 +131,7 @@ namespace Avalonia.Input.GestureRecognizers
_trackedRootPoint.X - (_trackedRootPoint.X >= rootPoint.X ? ScrollStartDistance : -ScrollStartDistance), _trackedRootPoint.X - (_trackedRootPoint.X >= rootPoint.X ? ScrollStartDistance : -ScrollStartDistance),
_trackedRootPoint.Y - (_trackedRootPoint.Y >= rootPoint.Y ? ScrollStartDistance : -ScrollStartDistance)); _trackedRootPoint.Y - (_trackedRootPoint.Y >= rootPoint.Y ? ScrollStartDistance : -ScrollStartDistance));
_actions!.Capture(e.Pointer, this); Capture(e.Pointer);
e.PreventGestureRecognition(); e.PreventGestureRecognition();
} }
@ -153,7 +151,7 @@ namespace Avalonia.Input.GestureRecognizers
} }
} }
public void PointerCaptureLost(IPointer pointer) public override void PointerCaptureLost(IPointer pointer)
{ {
if (pointer == _tracking) EndGesture(); if (pointer == _tracking) EndGesture();
} }
@ -173,7 +171,7 @@ namespace Avalonia.Input.GestureRecognizers
} }
public void PointerReleased(PointerReleasedEventArgs e) public override void PointerReleased(PointerReleasedEventArgs e)
{ {
if (e.Pointer == _tracking && _scrolling) if (e.Pointer == _tracking && _scrolling)
{ {

24
src/Avalonia.Base/Input/MouseDevice.cs

@ -163,14 +163,11 @@ namespace Avalonia.Input
device = device ?? throw new ArgumentNullException(nameof(device)); device = device ?? throw new ArgumentNullException(nameof(device));
root = root ?? throw new ArgumentNullException(nameof(root)); root = root ?? throw new ArgumentNullException(nameof(root));
IInputElement? source; if (_pointer.CapturedGestureRecognizer is GestureRecognizer gestureRecognizer)
if (_pointer.CapturedGestureRecognizer is IGestureRecognizer gestureRecognizer)
{ {
source = gestureRecognizer.Target ?? hitTest; if(gestureRecognizer.Target != null)
if(source != null)
{ {
var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, _pointer, (Visual)root, var e = new PointerEventArgs(InputElement.PointerMovedEvent, gestureRecognizer.Target, _pointer, (Visual)root,
p, timestamp, properties, inputModifiers, intermediatePoints); p, timestamp, properties, inputModifiers, intermediatePoints);
gestureRecognizer.PointerMoved(e); gestureRecognizer.PointerMoved(e);
@ -178,7 +175,7 @@ namespace Avalonia.Input
} }
} }
source = _pointer.Captured ?? hitTest; var source = _pointer.Captured ?? hitTest;
if (source is object) if (source is object)
{ {
@ -198,15 +195,12 @@ namespace Avalonia.Input
{ {
device = device ?? throw new ArgumentNullException(nameof(device)); device = device ?? throw new ArgumentNullException(nameof(device));
root = root ?? throw new ArgumentNullException(nameof(root)); root = root ?? throw new ArgumentNullException(nameof(root));
IInputElement? source; if (_pointer.CapturedGestureRecognizer is GestureRecognizer gestureRecognizer)
if (_pointer.CapturedGestureRecognizer is IGestureRecognizer gestureRecognizer)
{ {
source = gestureRecognizer.Target ?? hitTest; if (gestureRecognizer.Target != null)
if (source != null)
{ {
var e = new PointerReleasedEventArgs(source, _pointer, (Visual)root, p, timestamp, props, inputModifiers, var e = new PointerReleasedEventArgs(gestureRecognizer.Target, _pointer, (Visual)root, p, timestamp, props, inputModifiers,
_lastMouseDownButton); _lastMouseDownButton);
gestureRecognizer.PointerReleased(e); gestureRecognizer.PointerReleased(e);
@ -214,7 +208,7 @@ namespace Avalonia.Input
} }
} }
source = _pointer.Captured ?? hitTest; var source = _pointer.Captured ?? hitTest;
if (source is not null) if (source is not null)
{ {

22
src/Avalonia.Base/Input/PenDevice.cs

@ -115,14 +115,11 @@ namespace Avalonia.Input
KeyModifiers inputModifiers, IInputElement? hitTest, KeyModifiers inputModifiers, IInputElement? hitTest,
Lazy<IReadOnlyList<RawPointerPoint>?>? intermediatePoints) Lazy<IReadOnlyList<RawPointerPoint>?>? intermediatePoints)
{ {
IInputElement? source; if (pointer.CapturedGestureRecognizer is GestureRecognizer gestureRecognizer)
if (pointer.CapturedGestureRecognizer is IGestureRecognizer gestureRecognizer)
{ {
source = gestureRecognizer.Target ?? hitTest; if (gestureRecognizer.Target != null)
if (source != null)
{ {
var e = new PointerEventArgs(InputElement.PointerMovedEvent, source, pointer, (Visual)root, var e = new PointerEventArgs(InputElement.PointerMovedEvent, gestureRecognizer.Target, pointer, (Visual)root,
p, timestamp, properties, inputModifiers, intermediatePoints); p, timestamp, properties, inputModifiers, intermediatePoints);
gestureRecognizer.PointerMoved(e); gestureRecognizer.PointerMoved(e);
@ -130,7 +127,7 @@ namespace Avalonia.Input
} }
} }
source = pointer.Captured ?? hitTest; var source = pointer.Captured ?? hitTest;
if (source is not null) if (source is not null)
{ {
@ -148,14 +145,11 @@ namespace Avalonia.Input
IInputElement root, Point p, PointerPointProperties properties, IInputElement root, Point p, PointerPointProperties properties,
KeyModifiers inputModifiers, IInputElement? hitTest) KeyModifiers inputModifiers, IInputElement? hitTest)
{ {
IInputElement? source; if (pointer.CapturedGestureRecognizer is GestureRecognizer gestureRecognizer)
if (pointer.CapturedGestureRecognizer is IGestureRecognizer gestureRecognizer)
{ {
source = gestureRecognizer.Target ?? hitTest; if (gestureRecognizer.Target != null)
if (source != null)
{ {
var e = new PointerReleasedEventArgs(source, pointer, (Visual)root, p, timestamp, properties, inputModifiers, var e = new PointerReleasedEventArgs(gestureRecognizer.Target, pointer, (Visual)root, p, timestamp, properties, inputModifiers,
_lastMouseDownButton); _lastMouseDownButton);
gestureRecognizer.PointerReleased(e); gestureRecognizer.PointerReleased(e);
@ -163,7 +157,7 @@ namespace Avalonia.Input
} }
} }
source = pointer.Captured ?? hitTest; var source = pointer.Captured ?? hitTest;
if (source is not null) if (source is not null)
{ {

4
src/Avalonia.Base/Input/Pointer.cs

@ -77,7 +77,7 @@ namespace Avalonia.Input
/// <summary> /// <summary>
/// Gets the gesture recognizer that is currently capturing by the pointer, if any. /// Gets the gesture recognizer that is currently capturing by the pointer, if any.
/// </summary> /// </summary>
internal IGestureRecognizer? CapturedGestureRecognizer { get; private set; } internal GestureRecognizer? CapturedGestureRecognizer { get; private set; }
public void Dispose() public void Dispose()
{ {
@ -89,7 +89,7 @@ namespace Avalonia.Input
/// </summary> /// </summary>
/// <param name="gestureRecognizer">The gesture recognizer.</param> /// <param name="gestureRecognizer">The gesture recognizer.</param>
/// </remarks> /// </remarks>
internal void CaptureGestureRecognizer(IGestureRecognizer? gestureRecognizer) internal void CaptureGestureRecognizer(GestureRecognizer? gestureRecognizer)
{ {
if (CapturedGestureRecognizer != gestureRecognizer) if (CapturedGestureRecognizer != gestureRecognizer)
CapturedGestureRecognizer?.PointerCaptureLost(this); CapturedGestureRecognizer?.PointerCaptureLost(this);

Loading…
Cancel
Save