TouchDeviceTests.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using System;
  2. using Avalonia.Input.Raw;
  3. using Avalonia.Platform;
  4. using Avalonia.UnitTests;
  5. using Moq;
  6. using Xunit;
  7. namespace Avalonia.Input.UnitTests
  8. {
  9. public class TouchDeviceTests
  10. {
  11. [Fact]
  12. public void Tapped_Event_Is_Fired_With_Touch()
  13. {
  14. using var app = UnitTestApp(new TimeSpan(200));
  15. var root = new TestRoot();
  16. var touchDevice = new TouchDevice();
  17. var isTapped = false;
  18. var executedTimes = 0;
  19. root.Tapped += (a, e) =>
  20. {
  21. isTapped = true;
  22. executedTimes++;
  23. };
  24. TapOnce(InputManager.Instance, touchDevice, root);
  25. Assert.True(isTapped);
  26. Assert.Equal(1, executedTimes);
  27. }
  28. [Fact]
  29. public void DoubleTapped_Event_Is_Fired_With_Touch()
  30. {
  31. using var app = UnitTestApp(new TimeSpan(200));
  32. var root = new TestRoot();
  33. var touchDevice = new TouchDevice();
  34. var isDoubleTapped = false;
  35. var doubleTappedExecutedTimes = 0;
  36. var tappedExecutedTimes = 0;
  37. root.DoubleTapped += (a, e) =>
  38. {
  39. isDoubleTapped = true;
  40. doubleTappedExecutedTimes++;
  41. };
  42. root.Tapped += (a, e) =>
  43. {
  44. tappedExecutedTimes++;
  45. };
  46. TapOnce(InputManager.Instance, touchDevice, root);
  47. TapOnce(InputManager.Instance, touchDevice, root, touchPointId: 1);
  48. Assert.Equal(1, tappedExecutedTimes);
  49. Assert.True(isDoubleTapped);
  50. Assert.Equal(1, doubleTappedExecutedTimes);
  51. }
  52. [Theory]
  53. [InlineData(1)]
  54. [InlineData(2)]
  55. [InlineData(3)]
  56. [InlineData(4)]
  57. [InlineData(5)]
  58. public void PointerPressed_Counts_Clicks_Correctly(int clickCount)
  59. {
  60. using var app = UnitTestApp(new TimeSpan(200));
  61. var root = new TestRoot();
  62. var touchDevice = new TouchDevice();
  63. var pointerPressedExecutedTimes = 0;
  64. var pointerPressedClicks = 0;
  65. root.PointerPressed += (a, e) =>
  66. {
  67. pointerPressedClicks = e.ClickCount;
  68. pointerPressedExecutedTimes++;
  69. };
  70. for (int i = 0; i < clickCount; i++)
  71. {
  72. TapOnce(InputManager.Instance, touchDevice, root, touchPointId: i);
  73. }
  74. Assert.Equal(clickCount, pointerPressedExecutedTimes);
  75. Assert.Equal(pointerPressedClicks, clickCount);
  76. }
  77. [Fact]
  78. public void DoubleTapped_Not_Fired_When_Click_Too_Late()
  79. {
  80. using var app = UnitTestApp(new TimeSpan(0, 0, 0, 0, 20));
  81. var root = new TestRoot();
  82. var touchDevice = new TouchDevice();
  83. var isDoubleTapped = false;
  84. var doubleTappedExecutedTimes = 0;
  85. var tappedExecutedTimes = 0;
  86. root.DoubleTapped += (a, e) =>
  87. {
  88. isDoubleTapped = true;
  89. doubleTappedExecutedTimes++;
  90. };
  91. root.Tapped += (a, e) =>
  92. {
  93. tappedExecutedTimes++;
  94. };
  95. TapOnce(InputManager.Instance, touchDevice, root);
  96. TapOnce(InputManager.Instance, touchDevice, root, 21, 1);
  97. Assert.Equal(2, tappedExecutedTimes);
  98. Assert.False(isDoubleTapped);
  99. Assert.Equal(0, doubleTappedExecutedTimes);
  100. }
  101. [Fact]
  102. public void DoubleTapped_Not_Fired_When_Second_Click_Is_From_Different_Touch_Contact()
  103. {
  104. using var app = UnitTestApp(new TimeSpan(200));
  105. var root = new TestRoot();
  106. var touchDevice = new TouchDevice();
  107. var isDoubleTapped = false;
  108. var doubleTappedExecutedTimes = 0;
  109. var tappedExecutedTimes = 0;
  110. root.DoubleTapped += (a, e) =>
  111. {
  112. isDoubleTapped = true;
  113. doubleTappedExecutedTimes++;
  114. };
  115. root.Tapped += (a, e) =>
  116. {
  117. tappedExecutedTimes++;
  118. };
  119. SendXTouchContactsWithIds(InputManager.Instance, touchDevice, root, RawPointerEventType.TouchBegin, 0, 1);
  120. SendXTouchContactsWithIds(InputManager.Instance, touchDevice, root, RawPointerEventType.TouchEnd, 0, 1);
  121. Assert.Equal(2, tappedExecutedTimes);
  122. Assert.False(isDoubleTapped);
  123. Assert.Equal(0, doubleTappedExecutedTimes);
  124. }
  125. [Fact]
  126. public void Click_Counting_Should_Work_Correctly_With_Few_Touch_Contacts()
  127. {
  128. using var app = UnitTestApp(new TimeSpan(200));
  129. var root = new TestRoot();
  130. var touchDevice = new TouchDevice();
  131. var pointerPressedExecutedTimes = 0;
  132. var tappedExecutedTimes = 0;
  133. var isDoubleTapped = false;
  134. var doubleTappedExecutedTimes = 0;
  135. root.PointerPressed += (a, e) =>
  136. {
  137. pointerPressedExecutedTimes++;
  138. switch (pointerPressedExecutedTimes)
  139. {
  140. case <= 2:
  141. Assert.True(e.ClickCount == 1);
  142. break;
  143. case 3:
  144. Assert.True(e.ClickCount == 2);
  145. break;
  146. case 4:
  147. Assert.True(e.ClickCount == 3);
  148. break;
  149. case 5:
  150. Assert.True(e.ClickCount == 4);
  151. break;
  152. case 6:
  153. Assert.True(e.ClickCount == 5);
  154. break;
  155. case 7:
  156. Assert.True(e.ClickCount == 1);
  157. break;
  158. case 8:
  159. Assert.True(e.ClickCount == 1);
  160. break;
  161. case 9:
  162. Assert.True(e.ClickCount == 2);
  163. break;
  164. default:
  165. break;
  166. }
  167. };
  168. root.DoubleTapped += (a, e) =>
  169. {
  170. isDoubleTapped = true;
  171. doubleTappedExecutedTimes++;
  172. };
  173. root.Tapped += (a, e) =>
  174. {
  175. tappedExecutedTimes++;
  176. };
  177. SendXTouchContactsWithIds(InputManager.Instance, touchDevice, root, RawPointerEventType.TouchBegin, 0, 1);
  178. SendXTouchContactsWithIds(InputManager.Instance, touchDevice, root, RawPointerEventType.TouchEnd, 0, 1);
  179. TapOnce(InputManager.Instance, touchDevice, root, touchPointId: 2);
  180. TapOnce(InputManager.Instance, touchDevice, root, touchPointId: 3);
  181. TapOnce(InputManager.Instance, touchDevice, root, touchPointId: 4);
  182. SendXTouchContactsWithIds(InputManager.Instance, touchDevice, root, RawPointerEventType.TouchBegin, 5, 6, 7);
  183. SendXTouchContactsWithIds(InputManager.Instance, touchDevice, root, RawPointerEventType.TouchEnd, 5, 6, 7);
  184. TapOnce(InputManager.Instance, touchDevice, root, touchPointId: 8);
  185. Assert.Equal(6, tappedExecutedTimes);
  186. Assert.Equal(9, pointerPressedExecutedTimes);
  187. Assert.True(isDoubleTapped);
  188. Assert.Equal(3, doubleTappedExecutedTimes);
  189. }
  190. private IDisposable UnitTestApp(TimeSpan doubleClickTime = new TimeSpan())
  191. {
  192. var unitTestApp = UnitTestApplication.Start(
  193. new TestServices(inputManager: new InputManager(), threadingInterface: Mock.Of<IPlatformThreadingInterface>(x => x.CurrentThreadIsLoopThread == true)));
  194. var iSettingsMock = new Mock<IPlatformSettings>();
  195. iSettingsMock.Setup(x => x.GetDoubleTapTime(It.IsAny<PointerType>())).Returns(doubleClickTime);
  196. iSettingsMock.Setup(x => x.GetDoubleTapSize(It.IsAny<PointerType>())).Returns(new Size(16, 16));
  197. iSettingsMock.Setup(x => x.GetTapSize(It.IsAny<PointerType>())).Returns(new Size(16, 16));
  198. AvaloniaLocator.CurrentMutable.BindToSelf(this)
  199. .Bind<IPlatformSettings>().ToConstant(iSettingsMock.Object);
  200. return unitTestApp;
  201. }
  202. private static void SendXTouchContactsWithIds(IInputManager inputManager, TouchDevice device, IInputRoot root, RawPointerEventType type, params long[] touchPointIds)
  203. {
  204. for (int i = 0; i < touchPointIds.Length; i++)
  205. {
  206. inputManager.ProcessInput(new RawPointerEventArgs(device, 0,
  207. root,
  208. type,
  209. new Point(0, 0),
  210. RawInputModifiers.None)
  211. {
  212. RawPointerId = touchPointIds[i]
  213. });
  214. }
  215. }
  216. private static void TapOnce(IInputManager inputManager, TouchDevice device, IInputRoot root, ulong timestamp = 0, long touchPointId = 0)
  217. {
  218. inputManager.ProcessInput(new RawPointerEventArgs(device, timestamp,
  219. root,
  220. RawPointerEventType.TouchBegin,
  221. new Point(0, 0),
  222. RawInputModifiers.None)
  223. {
  224. RawPointerId = touchPointId
  225. });
  226. inputManager.ProcessInput(new RawPointerEventArgs(device, timestamp,
  227. root,
  228. RawPointerEventType.TouchEnd,
  229. new Point(0, 0),
  230. RawInputModifiers.None)
  231. {
  232. RawPointerId = touchPointId
  233. });
  234. }
  235. }
  236. }