GestureRecognizerCollection.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using Avalonia.Controls;
  4. using Avalonia.LogicalTree;
  5. using Avalonia.Reactive;
  6. namespace Avalonia.Input.GestureRecognizers
  7. {
  8. public class GestureRecognizerCollection : IReadOnlyCollection<IGestureRecognizer>, IGestureRecognizerActionsDispatcher
  9. {
  10. private readonly IInputElement _inputElement;
  11. private List<IGestureRecognizer>? _recognizers;
  12. private Dictionary<IPointer, IGestureRecognizer>? _pointerGrabs;
  13. public GestureRecognizerCollection(IInputElement inputElement)
  14. {
  15. _inputElement = inputElement;
  16. }
  17. public void Add(IGestureRecognizer recognizer)
  18. {
  19. if (_recognizers == null)
  20. {
  21. // We initialize the collection when the first recognizer is added
  22. _recognizers = new List<IGestureRecognizer>();
  23. _pointerGrabs = new Dictionary<IPointer, IGestureRecognizer>();
  24. }
  25. _recognizers.Add(recognizer);
  26. recognizer.Initialize(_inputElement, this);
  27. // Hacks to make bindings work
  28. if (_inputElement is ILogical logicalParent && recognizer is ISetLogicalParent logical)
  29. {
  30. logical.SetParent(logicalParent);
  31. if (recognizer is StyledElement styleableRecognizer
  32. && _inputElement is StyledElement styleableParent)
  33. styleableParent.GetObservable(StyledElement.TemplatedParentProperty).Subscribe(parent => styleableRecognizer.TemplatedParent = parent);
  34. }
  35. }
  36. static readonly List<IGestureRecognizer> s_Empty = new List<IGestureRecognizer>();
  37. public IEnumerator<IGestureRecognizer> GetEnumerator()
  38. => _recognizers?.GetEnumerator() ?? s_Empty.GetEnumerator();
  39. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  40. public int Count => _recognizers?.Count ?? 0;
  41. internal bool HandlePointerPressed(PointerPressedEventArgs e)
  42. {
  43. if (_recognizers == null)
  44. return false;
  45. foreach (var r in _recognizers)
  46. {
  47. if (e.Handled)
  48. break;
  49. r.PointerPressed(e);
  50. }
  51. return e.Handled;
  52. }
  53. internal bool HandlePointerReleased(PointerReleasedEventArgs e)
  54. {
  55. if (_recognizers == null)
  56. return false;
  57. if (_pointerGrabs!.TryGetValue(e.Pointer, out var capture))
  58. {
  59. capture.PointerReleased(e);
  60. }
  61. else
  62. foreach (var r in _recognizers)
  63. {
  64. if (e.Handled)
  65. break;
  66. r.PointerReleased(e);
  67. }
  68. return e.Handled;
  69. }
  70. internal bool HandlePointerMoved(PointerEventArgs e)
  71. {
  72. if (_recognizers == null)
  73. return false;
  74. if (_pointerGrabs!.TryGetValue(e.Pointer, out var capture))
  75. {
  76. capture.PointerMoved(e);
  77. }
  78. else
  79. foreach (var r in _recognizers)
  80. {
  81. if (e.Handled)
  82. break;
  83. r.PointerMoved(e);
  84. }
  85. return e.Handled;
  86. }
  87. internal void HandlePointerCaptureLost(PointerCaptureLostEventArgs e)
  88. {
  89. if (_recognizers == null)
  90. return;
  91. _pointerGrabs!.Remove(e.Pointer);
  92. foreach (var r in _recognizers)
  93. {
  94. r.PointerCaptureLost(e.Pointer);
  95. }
  96. }
  97. void IGestureRecognizerActionsDispatcher.Capture(IPointer pointer, IGestureRecognizer recognizer)
  98. {
  99. pointer.Capture(_inputElement);
  100. _pointerGrabs![pointer] = recognizer;
  101. foreach (var r in _recognizers!)
  102. {
  103. if (r != recognizer)
  104. r.PointerCaptureLost(pointer);
  105. }
  106. }
  107. }
  108. }