ApplicationMouseEnterLeaveTests.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. using System.ComponentModel;
  2. namespace Terminal.Gui.ViewMouseTests;
  3. [Trait ("Category", "Input")]
  4. public class ApplicationMouseEnterLeaveTests
  5. {
  6. private class TestView : View
  7. {
  8. public TestView ()
  9. {
  10. X = 1;
  11. Y = 1;
  12. Width = 1;
  13. Height = 1;
  14. }
  15. public bool CancelOnEnter { get; }
  16. public int OnMouseEnterCalled { get; private set; }
  17. public int OnMouseLeaveCalled { get; private set; }
  18. protected override bool OnMouseEnter (CancelEventArgs eventArgs)
  19. {
  20. OnMouseEnterCalled++;
  21. eventArgs.Cancel = CancelOnEnter;
  22. base.OnMouseEnter (eventArgs);
  23. return eventArgs.Cancel;
  24. }
  25. protected override void OnMouseLeave ()
  26. {
  27. OnMouseLeaveCalled++;
  28. base.OnMouseLeave ();
  29. }
  30. }
  31. [Fact]
  32. public void RaiseMouseEnterLeaveEvents_MouseEntersView_CallsOnMouseEnter ()
  33. {
  34. // Arrange
  35. Application.Top = new () { Frame = new (0, 0, 10, 10) };
  36. var view = new TestView ();
  37. Application.Top.Add (view);
  38. var mousePosition = new Point (1, 1);
  39. List<View> currentViewsUnderMouse = new () { view };
  40. var mouseEvent = new MouseEventArgs
  41. {
  42. Position = mousePosition,
  43. ScreenPosition = mousePosition
  44. };
  45. Application._cachedViewsUnderMouse.Clear ();
  46. try
  47. {
  48. // Act
  49. Application.RaiseMouseEnterLeaveEvents (mousePosition, currentViewsUnderMouse);
  50. // Assert
  51. Assert.Equal (1, view.OnMouseEnterCalled);
  52. }
  53. finally
  54. {
  55. // Cleanup
  56. Application.Top?.Dispose ();
  57. Application.ResetState ();
  58. }
  59. }
  60. [Fact]
  61. public void RaiseMouseEnterLeaveEvents_MouseLeavesView_CallsOnMouseLeave ()
  62. {
  63. // Arrange
  64. Application.Top = new () { Frame = new (0, 0, 10, 10) };
  65. var view = new TestView ();
  66. Application.Top.Add (view);
  67. var mousePosition = new Point (0, 0);
  68. List<View> currentViewsUnderMouse = new ();
  69. var mouseEvent = new MouseEventArgs ();
  70. Application._cachedViewsUnderMouse.Clear ();
  71. Application._cachedViewsUnderMouse.Add (view);
  72. try
  73. {
  74. // Act
  75. Application.RaiseMouseEnterLeaveEvents (mousePosition, currentViewsUnderMouse);
  76. // Assert
  77. Assert.Equal (0, view.OnMouseEnterCalled);
  78. Assert.Equal (1, view.OnMouseLeaveCalled);
  79. }
  80. finally
  81. {
  82. // Cleanup
  83. Application.Top?.Dispose ();
  84. Application.ResetState ();
  85. }
  86. }
  87. [Fact]
  88. public void RaiseMouseEnterLeaveEvents_MouseMovesBetweenAdjacentViews_CallsOnMouseEnterAndLeave ()
  89. {
  90. // Arrange
  91. Application.Top = new () { Frame = new (0, 0, 10, 10) };
  92. var view1 = new TestView (); // at 1,1 to 2,2
  93. var view2 = new TestView () // at 2,2 to 3,3
  94. {
  95. X = 2,
  96. Y = 2
  97. };
  98. Application.Top.Add (view1);
  99. Application.Top.Add (view2);
  100. Application._cachedViewsUnderMouse.Clear ();
  101. try
  102. {
  103. // Act
  104. var mousePosition = new Point (0, 0);
  105. Application.RaiseMouseEnterLeaveEvents (
  106. mousePosition,
  107. View.GetViewsUnderMouse (mousePosition));
  108. // Assert
  109. Assert.Equal (0, view1.OnMouseEnterCalled);
  110. Assert.Equal (0, view1.OnMouseLeaveCalled);
  111. Assert.Equal (0, view2.OnMouseEnterCalled);
  112. Assert.Equal (0, view2.OnMouseLeaveCalled);
  113. // Act
  114. mousePosition = new (1, 1);
  115. Application.RaiseMouseEnterLeaveEvents (
  116. mousePosition,
  117. View.GetViewsUnderMouse (mousePosition));
  118. // Assert
  119. Assert.Equal (1, view1.OnMouseEnterCalled);
  120. Assert.Equal (0, view1.OnMouseLeaveCalled);
  121. Assert.Equal (0, view2.OnMouseEnterCalled);
  122. Assert.Equal (0, view2.OnMouseLeaveCalled);
  123. // Act
  124. mousePosition = new (2, 2);
  125. Application.RaiseMouseEnterLeaveEvents (
  126. mousePosition,
  127. View.GetViewsUnderMouse (mousePosition));
  128. // Assert
  129. Assert.Equal (1, view1.OnMouseEnterCalled);
  130. Assert.Equal (1, view1.OnMouseLeaveCalled);
  131. Assert.Equal (1, view2.OnMouseEnterCalled);
  132. Assert.Equal (0, view2.OnMouseLeaveCalled);
  133. // Act
  134. mousePosition = new (3, 3);
  135. Application.RaiseMouseEnterLeaveEvents (
  136. mousePosition,
  137. View.GetViewsUnderMouse (mousePosition));
  138. // Assert
  139. Assert.Equal (1, view1.OnMouseEnterCalled);
  140. Assert.Equal (1, view1.OnMouseLeaveCalled);
  141. Assert.Equal (1, view2.OnMouseEnterCalled);
  142. Assert.Equal (1, view2.OnMouseLeaveCalled);
  143. // Act
  144. mousePosition = new (0, 0);
  145. Application.RaiseMouseEnterLeaveEvents (
  146. mousePosition,
  147. View.GetViewsUnderMouse (mousePosition));
  148. // Assert
  149. Assert.Equal (1, view1.OnMouseEnterCalled);
  150. Assert.Equal (1, view1.OnMouseLeaveCalled);
  151. Assert.Equal (1, view2.OnMouseEnterCalled);
  152. Assert.Equal (1, view2.OnMouseLeaveCalled);
  153. }
  154. finally
  155. {
  156. // Cleanup
  157. Application.Top?.Dispose ();
  158. Application.ResetState ();
  159. }
  160. }
  161. [Fact]
  162. public void RaiseMouseEnterLeaveEvents_NoViewsUnderMouse_DoesNotCallOnMouseEnterOrLeave ()
  163. {
  164. // Arrange
  165. Application.Top = new () { Frame = new (0, 0, 10, 10) };
  166. var view = new TestView ();
  167. Application.Top.Add (view);
  168. var mousePosition = new Point (0, 0);
  169. List<View> currentViewsUnderMouse = new ();
  170. var mouseEvent = new MouseEventArgs ();
  171. Application._cachedViewsUnderMouse.Clear ();
  172. try
  173. {
  174. // Act
  175. Application.RaiseMouseEnterLeaveEvents (mousePosition, currentViewsUnderMouse);
  176. // Assert
  177. Assert.Equal (0, view.OnMouseEnterCalled);
  178. Assert.Equal (0, view.OnMouseLeaveCalled);
  179. }
  180. finally
  181. {
  182. // Cleanup
  183. Application.Top?.Dispose ();
  184. Application.ResetState ();
  185. }
  186. }
  187. [Fact]
  188. public void RaiseMouseEnterLeaveEvents_MouseMovesBetweenOverlappingPeerViews_CallsOnMouseEnterAndLeave ()
  189. {
  190. // Arrange
  191. Application.Top = new () { Frame = new (0, 0, 10, 10) };
  192. var view1 = new TestView
  193. {
  194. Width = 2
  195. }; // at 1,1 to 3,2
  196. var view2 = new TestView () // at 2,2 to 4,3
  197. {
  198. Width = 2,
  199. X = 2,
  200. Y = 2
  201. };
  202. Application.Top.Add (view1);
  203. Application.Top.Add (view2);
  204. Application._cachedViewsUnderMouse.Clear ();
  205. try
  206. {
  207. // Act
  208. var mousePosition = new Point (0, 0);
  209. Application.RaiseMouseEnterLeaveEvents (
  210. mousePosition,
  211. View.GetViewsUnderMouse (mousePosition));
  212. // Assert
  213. Assert.Equal (0, view1.OnMouseEnterCalled);
  214. Assert.Equal (0, view1.OnMouseLeaveCalled);
  215. Assert.Equal (0, view2.OnMouseEnterCalled);
  216. Assert.Equal (0, view2.OnMouseLeaveCalled);
  217. // Act
  218. mousePosition = new (1, 1);
  219. Application.RaiseMouseEnterLeaveEvents (
  220. mousePosition,
  221. View.GetViewsUnderMouse (mousePosition));
  222. // Assert
  223. Assert.Equal (1, view1.OnMouseEnterCalled);
  224. Assert.Equal (0, view1.OnMouseLeaveCalled);
  225. Assert.Equal (0, view2.OnMouseEnterCalled);
  226. Assert.Equal (0, view2.OnMouseLeaveCalled);
  227. // Act
  228. mousePosition = new (2, 2);
  229. Application.RaiseMouseEnterLeaveEvents (
  230. mousePosition,
  231. View.GetViewsUnderMouse (mousePosition));
  232. // Assert
  233. Assert.Equal (1, view1.OnMouseEnterCalled);
  234. Assert.Equal (1, view1.OnMouseLeaveCalled);
  235. Assert.Equal (1, view2.OnMouseEnterCalled);
  236. Assert.Equal (0, view2.OnMouseLeaveCalled);
  237. // Act
  238. mousePosition = new (3, 3);
  239. Application.RaiseMouseEnterLeaveEvents (
  240. mousePosition,
  241. View.GetViewsUnderMouse (mousePosition));
  242. // Assert
  243. Assert.Equal (1, view1.OnMouseEnterCalled);
  244. Assert.Equal (1, view1.OnMouseLeaveCalled);
  245. Assert.Equal (1, view2.OnMouseEnterCalled);
  246. Assert.Equal (1, view2.OnMouseLeaveCalled);
  247. // Act
  248. mousePosition = new (0, 0);
  249. Application.RaiseMouseEnterLeaveEvents (
  250. mousePosition,
  251. View.GetViewsUnderMouse (mousePosition));
  252. // Assert
  253. Assert.Equal (1, view1.OnMouseEnterCalled);
  254. Assert.Equal (1, view1.OnMouseLeaveCalled);
  255. Assert.Equal (1, view2.OnMouseEnterCalled);
  256. Assert.Equal (1, view2.OnMouseLeaveCalled);
  257. // Act
  258. mousePosition = new (2, 2);
  259. Application.RaiseMouseEnterLeaveEvents (
  260. mousePosition,
  261. View.GetViewsUnderMouse (mousePosition));
  262. // Assert
  263. Assert.Equal (1, view1.OnMouseEnterCalled);
  264. Assert.Equal (1, view1.OnMouseLeaveCalled);
  265. Assert.Equal (2, view2.OnMouseEnterCalled);
  266. Assert.Equal (1, view2.OnMouseLeaveCalled);
  267. }
  268. finally
  269. {
  270. // Cleanup
  271. Application.Top?.Dispose ();
  272. Application.ResetState ();
  273. }
  274. }
  275. [Fact]
  276. public void RaiseMouseEnterLeaveEvents_MouseMovesBetweenOverlappingSubViews_CallsOnMouseEnterAndLeave ()
  277. {
  278. // Arrange
  279. Application.Top = new () { Frame = new (0, 0, 10, 10) };
  280. var view1 = new TestView
  281. {
  282. Id = "view1",
  283. Width = 2,
  284. Height = 2,
  285. Arrangement = ViewArrangement.Overlapped
  286. }; // at 1,1 to 3,3 (screen)
  287. var subView = new TestView
  288. {
  289. Id = "subView",
  290. Width = 2,
  291. Height = 2,
  292. X = 1,
  293. Y = 1,
  294. Arrangement = ViewArrangement.Overlapped
  295. }; // at 2,2 to 4,4 (screen)
  296. view1.Add (subView);
  297. Application.Top.Add (view1);
  298. Application._cachedViewsUnderMouse.Clear ();
  299. try
  300. {
  301. Assert.Equal (1, view1.FrameToScreen ().X);
  302. Assert.Equal (2, subView.FrameToScreen ().X);
  303. // Act
  304. var mousePosition = new Point (0, 0);
  305. Application.RaiseMouseEnterLeaveEvents (
  306. mousePosition,
  307. View.GetViewsUnderMouse (mousePosition));
  308. // Assert
  309. Assert.Equal (0, view1.OnMouseEnterCalled);
  310. Assert.Equal (0, view1.OnMouseLeaveCalled);
  311. Assert.Equal (0, subView.OnMouseEnterCalled);
  312. Assert.Equal (0, subView.OnMouseLeaveCalled);
  313. // Act
  314. mousePosition = new (1, 1);
  315. Application.RaiseMouseEnterLeaveEvents (
  316. mousePosition,
  317. View.GetViewsUnderMouse (mousePosition));
  318. // Assert
  319. Assert.Equal (1, view1.OnMouseEnterCalled);
  320. Assert.Equal (0, view1.OnMouseLeaveCalled);
  321. Assert.Equal (0, subView.OnMouseEnterCalled);
  322. Assert.Equal (0, subView.OnMouseLeaveCalled);
  323. // Act
  324. mousePosition = new (2, 2);
  325. Application.RaiseMouseEnterLeaveEvents (
  326. mousePosition,
  327. View.GetViewsUnderMouse (mousePosition));
  328. // Assert
  329. Assert.Equal (1, view1.OnMouseEnterCalled);
  330. Assert.Equal (0, view1.OnMouseLeaveCalled);
  331. Assert.Equal (1, subView.OnMouseEnterCalled);
  332. Assert.Equal (0, subView.OnMouseLeaveCalled);
  333. // Act
  334. mousePosition = new (0, 0);
  335. Application.RaiseMouseEnterLeaveEvents (
  336. mousePosition,
  337. View.GetViewsUnderMouse (mousePosition));
  338. // Assert
  339. Assert.Equal (1, view1.OnMouseEnterCalled);
  340. Assert.Equal (1, view1.OnMouseLeaveCalled);
  341. Assert.Equal (1, subView.OnMouseEnterCalled);
  342. Assert.Equal (1, subView.OnMouseLeaveCalled);
  343. // Act
  344. mousePosition = new (2, 2);
  345. Application.RaiseMouseEnterLeaveEvents (
  346. mousePosition,
  347. View.GetViewsUnderMouse (mousePosition));
  348. // Assert
  349. Assert.Equal (2, view1.OnMouseEnterCalled);
  350. Assert.Equal (1, view1.OnMouseLeaveCalled);
  351. Assert.Equal (2, subView.OnMouseEnterCalled);
  352. Assert.Equal (1, subView.OnMouseLeaveCalled);
  353. // Act
  354. mousePosition = new (3, 3);
  355. Application.RaiseMouseEnterLeaveEvents (
  356. mousePosition,
  357. View.GetViewsUnderMouse (mousePosition));
  358. // Assert
  359. Assert.Equal (2, view1.OnMouseEnterCalled);
  360. Assert.Equal (2, view1.OnMouseLeaveCalled);
  361. Assert.Equal (2, subView.OnMouseEnterCalled);
  362. Assert.Equal (2, subView.OnMouseLeaveCalled);
  363. // Act
  364. mousePosition = new (0, 0);
  365. Application.RaiseMouseEnterLeaveEvents (
  366. mousePosition,
  367. View.GetViewsUnderMouse (mousePosition));
  368. // Assert
  369. Assert.Equal (2, view1.OnMouseEnterCalled);
  370. Assert.Equal (2, view1.OnMouseLeaveCalled);
  371. Assert.Equal (2, subView.OnMouseEnterCalled);
  372. Assert.Equal (2, subView.OnMouseLeaveCalled);
  373. // Act
  374. mousePosition = new (2, 2);
  375. Application.RaiseMouseEnterLeaveEvents (
  376. mousePosition,
  377. View.GetViewsUnderMouse (mousePosition));
  378. // Assert
  379. Assert.Equal (3, view1.OnMouseEnterCalled);
  380. Assert.Equal (2, view1.OnMouseLeaveCalled);
  381. Assert.Equal (3, subView.OnMouseEnterCalled);
  382. Assert.Equal (2, subView.OnMouseLeaveCalled);
  383. }
  384. finally
  385. {
  386. // Cleanup
  387. Application.Top?.Dispose ();
  388. Application.ResetState ();
  389. }
  390. }
  391. }