MouseTestHelper.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using Avalonia.Input;
  2. using Avalonia.Interactivity;
  3. using Avalonia.VisualTree;
  4. namespace Avalonia.UnitTests
  5. {
  6. public class MouseTestHelper(PointerType pointerType = PointerType.Mouse)
  7. {
  8. private readonly Pointer _pointer = new Pointer(Pointer.GetNextFreeId(), pointerType, true);
  9. private ulong _nextStamp = 1;
  10. private ulong Timestamp() => _nextStamp++;
  11. private RawInputModifiers _pressedButtons;
  12. public IInputElement Captured => _pointer.Captured;
  13. private RawInputModifiers Convert(MouseButton mouseButton)
  14. {
  15. return mouseButton switch
  16. {
  17. MouseButton.Left => RawInputModifiers.LeftMouseButton,
  18. MouseButton.Right => RawInputModifiers.RightMouseButton,
  19. MouseButton.Middle => RawInputModifiers.MiddleMouseButton,
  20. _ => RawInputModifiers.None,
  21. };
  22. }
  23. private int ButtonCount(PointerPointProperties props)
  24. {
  25. var rv = 0;
  26. if (props.IsLeftButtonPressed)
  27. rv++;
  28. if (props.IsMiddleButtonPressed)
  29. rv++;
  30. if (props.IsRightButtonPressed)
  31. rv++;
  32. return rv;
  33. }
  34. private MouseButton _pressedButton;
  35. public void Down(Interactive target, MouseButton mouseButton = MouseButton.Left, Point position = default,
  36. KeyModifiers modifiers = default, int clickCount = 1)
  37. {
  38. Down(target, target, mouseButton, position, modifiers, clickCount);
  39. }
  40. public void Down(Interactive target, Interactive source, MouseButton mouseButton = MouseButton.Left,
  41. Point position = default, KeyModifiers modifiers = default, int clickCount = 1)
  42. {
  43. _pressedButtons |= Convert(mouseButton);
  44. var props = new PointerPointProperties((RawInputModifiers)_pressedButtons,
  45. mouseButton == MouseButton.Left ? PointerUpdateKind.LeftButtonPressed
  46. : mouseButton == MouseButton.Middle ? PointerUpdateKind.MiddleButtonPressed
  47. : mouseButton == MouseButton.Right ? PointerUpdateKind.RightButtonPressed : PointerUpdateKind.Other
  48. );
  49. if (ButtonCount(props) > 1)
  50. Move(target, source, position);
  51. else
  52. {
  53. _pressedButton = mouseButton;
  54. _pointer.Capture((IInputElement)target);
  55. source.RaiseEvent(new PointerPressedEventArgs(source, _pointer, GetRoot(target), position, Timestamp(), props,
  56. modifiers, clickCount));
  57. }
  58. }
  59. public void Move(Interactive target, in Point position, KeyModifiers modifiers = default) => Move(target, target, position, modifiers);
  60. public void Move(Interactive target, Interactive source, in Point position, KeyModifiers modifiers = default)
  61. {
  62. target.RaiseEvent(new PointerEventArgs(InputElement.PointerMovedEvent, source, _pointer, GetRoot(target), position,
  63. Timestamp(), new PointerPointProperties((RawInputModifiers)_pressedButtons, PointerUpdateKind.Other), modifiers));
  64. }
  65. public void Up(Interactive target, MouseButton mouseButton = MouseButton.Left, Point position = default,
  66. KeyModifiers modifiers = default)
  67. => Up(target, target, mouseButton, position, modifiers);
  68. public void Up(Interactive target, Interactive source, MouseButton mouseButton = MouseButton.Left,
  69. Point position = default, KeyModifiers modifiers = default)
  70. {
  71. var conv = Convert(mouseButton);
  72. _pressedButtons = (_pressedButtons | conv) ^ conv;
  73. var props = new PointerPointProperties((RawInputModifiers)_pressedButtons,
  74. mouseButton == MouseButton.Left ? PointerUpdateKind.LeftButtonReleased
  75. : mouseButton == MouseButton.Middle ? PointerUpdateKind.MiddleButtonReleased
  76. : mouseButton == MouseButton.Right ? PointerUpdateKind.RightButtonReleased : PointerUpdateKind.Other
  77. );
  78. if (ButtonCount(props) == 0)
  79. {
  80. target.RaiseEvent(new PointerReleasedEventArgs(source, _pointer, GetRoot(target), position,
  81. Timestamp(), props, modifiers, _pressedButton));
  82. _pointer.Capture(null);
  83. }
  84. else
  85. Move(target, source, position);
  86. }
  87. public void Click(Interactive target, MouseButton button = MouseButton.Left, Point position = default,
  88. KeyModifiers modifiers = default)
  89. => Click(target, target, button, position, modifiers);
  90. public void Click(Interactive target, Interactive source, MouseButton button = MouseButton.Left,
  91. Point position = default, KeyModifiers modifiers = default)
  92. {
  93. Down(target, source, button, position, modifiers);
  94. var captured = (_pointer.Captured as Interactive) ?? source;
  95. Up(captured, captured, button, position, modifiers);
  96. }
  97. public void DoubleClick(Interactive target, MouseButton button = MouseButton.Left, Point position = default,
  98. KeyModifiers modifiers = default)
  99. => DoubleClick(target, target, button, position, modifiers);
  100. public void DoubleClick(Interactive target, Interactive source, MouseButton button = MouseButton.Left,
  101. Point position = default, KeyModifiers modifiers = default)
  102. {
  103. Down(target, source, button, position, modifiers, clickCount: 1);
  104. var captured = (_pointer.Captured as Interactive) ?? source;
  105. Up(captured, captured, button, position, modifiers);
  106. Down(target, source, button, position, modifiers, clickCount: 2);
  107. }
  108. public void Enter(Interactive target)
  109. {
  110. target.RaiseEvent(new PointerEventArgs(InputElement.PointerEnteredEvent, target, _pointer, (Visual)target, default,
  111. Timestamp(), new PointerPointProperties((RawInputModifiers)_pressedButtons, PointerUpdateKind.Other), KeyModifiers.None));
  112. }
  113. public void Leave(Interactive target)
  114. {
  115. target.RaiseEvent(new PointerEventArgs(InputElement.PointerExitedEvent, target, _pointer, (Visual)target, default,
  116. Timestamp(), new PointerPointProperties((RawInputModifiers)_pressedButtons, PointerUpdateKind.Other), KeyModifiers.None));
  117. }
  118. private Visual GetRoot(Interactive source)
  119. {
  120. return ((source as Visual)?.GetVisualRoot() as Visual) ?? (Visual)source;
  121. }
  122. }
  123. }