TouchDeviceTests.cs 10.0 KB

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