ContextMenuTests.cs 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364
  1. using System.Globalization;
  2. using Xunit.Abstractions;
  3. //using GraphViewTests = Terminal.Gui.Views.GraphViewTests;
  4. namespace Terminal.Gui.ViewsTests;
  5. public class ContextMenuTests
  6. {
  7. private readonly ITestOutputHelper _output;
  8. public ContextMenuTests (ITestOutputHelper output) { _output = output; }
  9. [Fact]
  10. [AutoInitShutdown]
  11. public void ContextMenu_Constructors ()
  12. {
  13. var cm = new ContextMenu ();
  14. Assert.Equal (Point.Empty, cm.Position);
  15. Assert.Empty (cm.MenuItems.Children);
  16. Assert.Null (cm.Host);
  17. cm.Position = new Point (20, 10);
  18. cm.MenuItems = new MenuBarItem (
  19. [
  20. new MenuItem ("First", "", null)
  21. ]
  22. );
  23. Assert.Equal (new Point (20, 10), cm.Position);
  24. Assert.Single (cm.MenuItems.Children);
  25. cm = new ContextMenu
  26. {
  27. Position = new Point (5, 10),
  28. MenuItems = new MenuBarItem (
  29. new [] { new MenuItem ("One", "", null), new MenuItem ("Two", "", null) }
  30. )
  31. };
  32. Assert.Equal (new Point (5, 10), cm.Position);
  33. Assert.Equal (2, cm.MenuItems.Children.Length);
  34. Assert.Null (cm.Host);
  35. cm = new ContextMenu
  36. {
  37. Host = new View { X = 5, Y = 10 },
  38. Position = new Point (5, 10),
  39. MenuItems = new MenuBarItem (
  40. new [] { new MenuItem ("One", "", null), new MenuItem ("Two", "", null) }
  41. )
  42. };
  43. Assert.Equal (new Point (5, 10), cm.Position);
  44. Assert.Equal (2, cm.MenuItems.Children.Length);
  45. Assert.NotNull (cm.Host);
  46. }
  47. [Fact]
  48. [AutoInitShutdown]
  49. public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
  50. {
  51. var cm = new ContextMenu
  52. {
  53. Position = new Point (10, 5),
  54. MenuItems = new MenuBarItem (
  55. [
  56. new MenuItem ("One", "", null),
  57. new MenuItem ("Two", "", null)
  58. ]
  59. )
  60. };
  61. var menu = new MenuBar
  62. {
  63. Menus =
  64. [
  65. new MenuBarItem ("File", "", null),
  66. new MenuBarItem ("Edit", "", null)
  67. ]
  68. };
  69. Application.Top.Add (menu);
  70. Application.Begin (Application.Top);
  71. Assert.Null (Application.MouseGrabView);
  72. cm.Show ();
  73. Assert.True (ContextMenu.IsShow);
  74. Assert.Equal (cm.MenuBar, Application.MouseGrabView);
  75. Assert.False (menu.IsMenuOpen);
  76. Assert.True (menu.NewKeyDownEvent (menu.Key));
  77. Assert.False (ContextMenu.IsShow);
  78. Assert.Equal (menu, Application.MouseGrabView);
  79. Assert.True (menu.IsMenuOpen);
  80. cm.Show ();
  81. Assert.True (ContextMenu.IsShow);
  82. Assert.Equal (cm.MenuBar, Application.MouseGrabView);
  83. Assert.False (menu.IsMenuOpen);
  84. #if SUPPORT_ALT_TO_ACTIVATE_MENU
  85. Assert.True (Application.Top.ProcessKeyUp (new (Key.AltMask)));
  86. Assert.False (ContextMenu.IsShow);
  87. Assert.Equal (menu, Application.MouseGrabView);
  88. Assert.True (menu.IsMenuOpen);
  89. #endif
  90. cm.Show ();
  91. Assert.True (ContextMenu.IsShow);
  92. Assert.Equal (cm.MenuBar, Application.MouseGrabView);
  93. Assert.False (menu.IsMenuOpen);
  94. Assert.False (menu.OnMouseEvent (new MouseEvent { X = 1, Flags = MouseFlags.ReportMousePosition, View = menu }));
  95. Assert.True (ContextMenu.IsShow);
  96. Assert.Equal (cm.MenuBar, Application.MouseGrabView);
  97. Assert.False (menu.IsMenuOpen);
  98. Assert.True (menu.OnMouseEvent (new MouseEvent { X = 1, Flags = MouseFlags.Button1Clicked, View = menu }));
  99. Assert.False (ContextMenu.IsShow);
  100. Assert.Equal (menu, Application.MouseGrabView);
  101. Assert.True (menu.IsMenuOpen);
  102. }
  103. [Fact]
  104. [AutoInitShutdown]
  105. public void ContextMenu_On_Toplevel_With_A_MenuBar_TextField_StatusBar ()
  106. {
  107. Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US");
  108. var menu = new MenuBar
  109. {
  110. Menus =
  111. [
  112. new MenuBarItem ("File", "", null),
  113. new MenuBarItem ("Edit", "", null)
  114. ]
  115. };
  116. var label = new Label { X = 2, Y = 3, Text = "Label:" };
  117. var tf = new TextField { X = Pos.Right (label) + 1, Y = Pos.Top (label), Width = 20, Text = "TextField" };
  118. var statusBar = new StatusBar (
  119. [
  120. new StatusItem (KeyCode.F1, "~F1~ Help", null),
  121. new StatusItem (KeyCode.CtrlMask | KeyCode.Q, "~^Q~ Quit", null)
  122. ]
  123. );
  124. Application.Top.Add (menu, label, tf, statusBar);
  125. ((FakeDriver)Application.Driver).SetBufferSize (45, 17);
  126. Application.Begin (Application.Top);
  127. Assert.Equal (new Rectangle (9, 3, 20, 1), tf.Frame);
  128. Assert.True (tf.HasFocus);
  129. tf.ContextMenu.Show ();
  130. Assert.True (ContextMenu.IsShow);
  131. Assert.Equal (new Point (9, 3), tf.ContextMenu.Position);
  132. Application.Top.Draw ();
  133. var expected = @"
  134. File Edit
  135. Label: TextField
  136. ┌─────────────────────┐
  137. │ Select All Ctrl+T │
  138. │ Delete All Ctrl+R │
  139. │ Copy Ctrl+C │
  140. │ Cut Ctrl+X │
  141. │ Paste Ctrl+V │
  142. │ Undo Ctrl+Z │
  143. │ Redo Ctrl+Y │
  144. └─────────────────────┘
  145. F1 Help │ ^Q Quit
  146. ";
  147. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  148. Assert.Equal (new Rectangle (1, 0, 32, 17), pos);
  149. }
  150. [Fact]
  151. [AutoInitShutdown]
  152. public void ContextMenu_On_Toplevel_With_A_MenuBar_Window_TextField_StatusBar ()
  153. {
  154. Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US");
  155. var menu = new MenuBar
  156. {
  157. Menus =
  158. [
  159. new MenuBarItem ("File", "", null),
  160. new MenuBarItem ("Edit", "", null)
  161. ]
  162. };
  163. var label = new Label { X = 2, Y = 3, Text = "Label:" };
  164. var tf = new TextField { X = Pos.Right (label) + 1, Y = Pos.Top (label), Width = 20, Text = "TextField" };
  165. var win = new Window ();
  166. win.Add (label, tf);
  167. var statusBar = new StatusBar (
  168. new []
  169. {
  170. new StatusItem (KeyCode.F1, "~F1~ Help", null),
  171. new StatusItem (KeyCode.CtrlMask | KeyCode.Q, "~^Q~ Quit", null)
  172. }
  173. );
  174. Application.Top.Add (menu, win, statusBar);
  175. Application.Begin (Application.Top);
  176. ((FakeDriver)Application.Driver).SetBufferSize (44, 17);
  177. Assert.Equal (new Rectangle (9, 3, 20, 1), tf.Frame);
  178. Assert.True (tf.HasFocus);
  179. tf.ContextMenu.Show ();
  180. Assert.True (ContextMenu.IsShow);
  181. Assert.Equal (new Point (10, 5), tf.ContextMenu.Position);
  182. Application.Top.Draw ();
  183. var expected = @"
  184. File Edit
  185. ┌──────────────────────────────────────────┐
  186. │ │
  187. │ │
  188. │ │
  189. │ Label: TextField │
  190. │ ┌─────────────────────┐ │
  191. │ │ Select All Ctrl+T │ │
  192. │ │ Delete All Ctrl+R │ │
  193. │ │ Copy Ctrl+C │ │
  194. │ │ Cut Ctrl+X │ │
  195. │ │ Paste Ctrl+V │ │
  196. │ │ Undo Ctrl+Z │ │
  197. │ │ Redo Ctrl+Y │ │
  198. │ └─────────────────────┘ │
  199. └──────────────────────────────────────────┘
  200. F1 Help │ ^Q Quit
  201. ";
  202. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  203. Assert.Equal (new Rectangle (1, 0, 44, 17), pos);
  204. }
  205. [Fact]
  206. [AutoInitShutdown]
  207. public void Draw_A_ContextMenu_Over_A_Borderless_Top ()
  208. {
  209. ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
  210. Assert.Equal (new Rectangle (0, 0, 20, 15), Application.Driver.Clip);
  211. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  212. var top = new Toplevel { X = 2, Y = 2, Width = 15, Height = 4 };
  213. top.Add (new TextField { X = Pos.Center (), Width = 10, Text = "Test" });
  214. RunState rs = Application.Begin (top);
  215. Assert.Equal (new Rectangle (2, 2, 15, 4), top.Frame);
  216. Assert.Equal (top, Application.Top);
  217. TestHelpers.AssertDriverContentsWithFrameAre (
  218. @"
  219. Test",
  220. _output
  221. );
  222. Application.OnMouseEvent (
  223. new MouseEventEventArgs (
  224. new MouseEvent { X = 8, Y = 2, Flags = MouseFlags.Button3Clicked }
  225. )
  226. );
  227. var firstIteration = false;
  228. Application.RunIteration (ref rs, ref firstIteration);
  229. TestHelpers.AssertDriverContentsWithFrameAre (
  230. @"
  231. Test
  232. ┌───────────────────
  233. │ Select All Ctrl+
  234. │ Delete All Ctrl+
  235. │ Copy Ctrl+
  236. │ Cut Ctrl+
  237. │ Paste Ctrl+
  238. │ Undo Ctrl+
  239. │ Redo Ctrl+
  240. └───────────────────",
  241. _output
  242. );
  243. Application.End (rs);
  244. }
  245. [Fact]
  246. [AutoInitShutdown]
  247. public void Draw_A_ContextMenu_Over_A_Dialog ()
  248. {
  249. Toplevel top = Application.Top;
  250. var win = new Window ();
  251. top.Add (win);
  252. Application.Begin (top);
  253. ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
  254. Assert.Equal (new Rectangle (0, 0, 20, 15), win.Frame);
  255. TestHelpers.AssertDriverContentsWithFrameAre (
  256. @"
  257. ┌──────────────────┐
  258. │ │
  259. │ │
  260. │ │
  261. │ │
  262. │ │
  263. │ │
  264. │ │
  265. │ │
  266. │ │
  267. │ │
  268. │ │
  269. │ │
  270. │ │
  271. └──────────────────┘",
  272. _output
  273. );
  274. // Don't use Dialog here as it has more layout logic. Use Window instead.
  275. var dialog = new Window { X = 2, Y = 2, Width = 15, Height = 4 };
  276. dialog.Add (new TextField { X = Pos.Center (), Width = 10, Text = "Test" });
  277. RunState rs = Application.Begin (dialog);
  278. Assert.Equal (new Rectangle (2, 2, 15, 4), dialog.Frame);
  279. TestHelpers.AssertDriverContentsWithFrameAre (
  280. @"
  281. ┌──────────────────┐
  282. │ │
  283. │ ┌─────────────┐ │
  284. │ │ Test │ │
  285. │ │ │ │
  286. │ └─────────────┘ │
  287. │ │
  288. │ │
  289. │ │
  290. │ │
  291. │ │
  292. │ │
  293. │ │
  294. │ │
  295. └──────────────────┘",
  296. _output
  297. );
  298. Application.OnMouseEvent (
  299. new MouseEventEventArgs (
  300. new MouseEvent { X = 9, Y = 3, Flags = MouseFlags.Button3Clicked }
  301. )
  302. );
  303. var firstIteration = false;
  304. Application.RunIteration (ref rs, ref firstIteration);
  305. TestHelpers.AssertDriverContentsWithFrameAre (
  306. @"
  307. ┌──────────────────┐
  308. │ │
  309. │ ┌─────────────┐ │
  310. │ │ Test │ │
  311. ┌───────────────────
  312. │ Select All Ctrl+
  313. │ Delete All Ctrl+
  314. │ Copy Ctrl+
  315. │ Cut Ctrl+
  316. │ Paste Ctrl+
  317. │ Undo Ctrl+
  318. │ Redo Ctrl+
  319. └───────────────────
  320. │ │
  321. └──────────────────┘",
  322. _output
  323. );
  324. Application.End (rs);
  325. }
  326. [Fact]
  327. [AutoInitShutdown]
  328. public void Draw_A_ContextMenu_Over_A_Top_Dialog ()
  329. {
  330. ((FakeDriver)Application.Driver).SetBufferSize (20, 15);
  331. Assert.Equal (new Rectangle (0, 0, 20, 15), Application.Driver.Clip);
  332. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  333. // Don't use Dialog here as it has more layout logic. Use Window instead.
  334. var dialog = new Window { X = 2, Y = 2, Width = 15, Height = 4 };
  335. dialog.Add (new TextField { X = Pos.Center (), Width = 10, Text = "Test" });
  336. RunState rs = Application.Begin (dialog);
  337. Assert.Equal (new Rectangle (2, 2, 15, 4), dialog.Frame);
  338. Assert.Equal (dialog, Application.Top);
  339. TestHelpers.AssertDriverContentsWithFrameAre (
  340. @"
  341. ┌─────────────┐
  342. │ Test │
  343. │ │
  344. └─────────────┘",
  345. _output
  346. );
  347. Application.OnMouseEvent (
  348. new MouseEventEventArgs (
  349. new MouseEvent { X = 9, Y = 3, Flags = MouseFlags.Button3Clicked }
  350. )
  351. );
  352. var firstIteration = false;
  353. Application.RunIteration (ref rs, ref firstIteration);
  354. TestHelpers.AssertDriverContentsWithFrameAre (
  355. @"
  356. ┌─────────────┐
  357. │ Test │
  358. ┌───────────────────
  359. │ Select All Ctrl+
  360. │ Delete All Ctrl+
  361. │ Copy Ctrl+
  362. │ Cut Ctrl+
  363. │ Paste Ctrl+
  364. │ Undo Ctrl+
  365. │ Redo Ctrl+
  366. └───────────────────",
  367. _output
  368. );
  369. Application.End (rs);
  370. }
  371. [Fact]
  372. [AutoInitShutdown]
  373. public void ForceMinimumPosToZero_True_False ()
  374. {
  375. var cm = new ContextMenu
  376. {
  377. Position = new Point (-1, -2),
  378. MenuItems = new MenuBarItem (
  379. [
  380. new MenuItem ("One", "", null),
  381. new MenuItem ("Two", "", null)
  382. ]
  383. )
  384. };
  385. Assert.Equal (new Point (-1, -2), cm.Position);
  386. cm.Show ();
  387. Assert.Equal (new Point (-1, -2), cm.Position);
  388. Application.Begin (Application.Top);
  389. var expected = @"
  390. ┌──────┐
  391. │ One │
  392. │ Two │
  393. └──────┘
  394. ";
  395. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  396. Assert.Equal (new Rectangle (0, 1, 8, 4), pos);
  397. cm.ForceMinimumPosToZero = false;
  398. cm.Show ();
  399. Assert.Equal (new Point (-1, -2), cm.Position);
  400. Application.Refresh ();
  401. expected = @"
  402. One │
  403. Two │
  404. ──────┘
  405. ";
  406. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  407. Assert.Equal (new Rectangle (1, 0, 7, 3), pos);
  408. }
  409. [Fact]
  410. [AutoInitShutdown]
  411. public void Hide_Is_Invoke_At_Container_Closing ()
  412. {
  413. var cm = new ContextMenu
  414. {
  415. Position = new Point (80, 25),
  416. MenuItems = new MenuBarItem (
  417. [
  418. new MenuItem ("One", "", null),
  419. new MenuItem ("Two", "", null)
  420. ]
  421. )
  422. };
  423. Toplevel top = Application.Top;
  424. Application.Begin (top);
  425. top.Running = true;
  426. Assert.False (ContextMenu.IsShow);
  427. cm.Show ();
  428. Assert.True (ContextMenu.IsShow);
  429. top.RequestStop ();
  430. Assert.False (ContextMenu.IsShow);
  431. }
  432. [Fact]
  433. [AutoInitShutdown]
  434. public void Key_Open_And_Close_The_ContextMenu ()
  435. {
  436. var tf = new TextField ();
  437. Application.Top.Add (tf);
  438. Application.Begin (Application.Top);
  439. Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey));
  440. Assert.True (tf.ContextMenu.MenuBar.IsMenuOpen);
  441. Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey));
  442. Assert.Null (tf.ContextMenu.MenuBar);
  443. }
  444. [Fact]
  445. [AutoInitShutdown]
  446. public void KeyChanged_Event ()
  447. {
  448. var oldKey = Key.Empty;
  449. var cm = new ContextMenu ();
  450. cm.KeyChanged += (s, e) => oldKey = e.OldKey;
  451. cm.Key = Key.Space.WithCtrl;
  452. Assert.Equal (Key.Space.WithCtrl, cm.Key);
  453. Assert.Equal (ContextMenu.DefaultKey, oldKey);
  454. }
  455. [Fact]
  456. [AutoInitShutdown]
  457. public void MenuItens_Changing ()
  458. {
  459. var cm = new ContextMenu
  460. {
  461. Position = new Point (10, 5),
  462. MenuItems = new MenuBarItem (
  463. [
  464. new MenuItem ("One", "", null),
  465. new MenuItem ("Two", "", null)
  466. ]
  467. )
  468. };
  469. cm.Show ();
  470. Application.Begin (Application.Top);
  471. var expected = @"
  472. ┌──────┐
  473. │ One │
  474. │ Two │
  475. └──────┘
  476. ";
  477. TestHelpers.AssertDriverContentsAre (expected, _output);
  478. cm.MenuItems = new MenuBarItem (
  479. [
  480. new MenuItem ("First", "", null),
  481. new MenuItem ("Second", "", null),
  482. new MenuItem ("Third", "", null)
  483. ]
  484. );
  485. cm.Show ();
  486. Application.Refresh ();
  487. expected = @"
  488. ┌─────────┐
  489. │ First │
  490. │ Second │
  491. │ Third │
  492. └─────────┘
  493. ";
  494. TestHelpers.AssertDriverContentsAre (expected, _output);
  495. }
  496. [Fact]
  497. [AutoInitShutdown]
  498. public void Menus_And_SubMenus_Always_Try_To_Be_On_Screen ()
  499. {
  500. var cm = new ContextMenu
  501. {
  502. Position = new Point (-1, -2),
  503. MenuItems = new MenuBarItem (
  504. [
  505. new MenuItem ("One", "", null),
  506. new MenuItem ("Two", "", null),
  507. new MenuItem ("Three", "", null),
  508. new MenuBarItem (
  509. "Four",
  510. [
  511. new MenuItem ("SubMenu1", "", null),
  512. new MenuItem ("SubMenu2", "", null),
  513. new MenuItem ("SubMenu3", "", null),
  514. new MenuItem ("SubMenu4", "", null),
  515. new MenuItem ("SubMenu5", "", null),
  516. new MenuItem ("SubMenu6", "", null),
  517. new MenuItem ("SubMenu7", "", null)
  518. ]
  519. ),
  520. new MenuItem ("Five", "", null),
  521. new MenuItem ("Six", "", null)
  522. ]
  523. )
  524. };
  525. Assert.Equal (new Point (-1, -2), cm.Position);
  526. cm.Show ();
  527. Assert.Equal (new Point (-1, -2), cm.Position);
  528. Toplevel top = Application.Top;
  529. Application.Begin (top);
  530. TestHelpers.AssertDriverContentsWithFrameAre (
  531. @"
  532. ┌────────┐
  533. │ One │
  534. │ Two │
  535. │ Three │
  536. │ Four ►│
  537. │ Five │
  538. │ Six │
  539. └────────┘
  540. ",
  541. _output
  542. );
  543. Assert.True (
  544. top.Subviews [0]
  545. .OnMouseEvent (
  546. new MouseEvent { X = 0, Y = 4, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
  547. )
  548. );
  549. Application.Refresh ();
  550. Assert.Equal (new Point (-1, -2), cm.Position);
  551. TestHelpers.AssertDriverContentsWithFrameAre (
  552. @"
  553. ┌────────┐
  554. │ One │
  555. │ Two │
  556. │ Three │
  557. │ Four ►│┌───────────┐
  558. │ Five ││ SubMenu1 │
  559. │ Six ││ SubMenu2 │
  560. └────────┘│ SubMenu3 │
  561. │ SubMenu4 │
  562. │ SubMenu5 │
  563. │ SubMenu6 │
  564. │ SubMenu7 │
  565. └───────────┘
  566. ",
  567. _output
  568. );
  569. ((FakeDriver)Application.Driver).SetBufferSize (40, 20);
  570. cm.Position = new Point (41, -2);
  571. cm.Show ();
  572. Application.Refresh ();
  573. Assert.Equal (new Point (41, -2), cm.Position);
  574. TestHelpers.AssertDriverContentsWithFrameAre (
  575. @"
  576. ┌────────┐
  577. │ One │
  578. │ Two │
  579. │ Three │
  580. │ Four ►│
  581. │ Five │
  582. │ Six │
  583. └────────┘
  584. ",
  585. _output
  586. );
  587. Assert.True (
  588. top.Subviews [0]
  589. .OnMouseEvent (
  590. new MouseEvent { X = 30, Y = 4, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
  591. )
  592. );
  593. Application.Refresh ();
  594. Assert.Equal (new Point (41, -2), cm.Position);
  595. TestHelpers.AssertDriverContentsWithFrameAre (
  596. @"
  597. ┌────────┐
  598. │ One │
  599. │ Two │
  600. │ Three │
  601. ┌───────────┐│ Four ►│
  602. │ SubMenu1 ││ Five │
  603. │ SubMenu2 ││ Six │
  604. │ SubMenu3 │└────────┘
  605. │ SubMenu4 │
  606. │ SubMenu5 │
  607. │ SubMenu6 │
  608. │ SubMenu7 │
  609. └───────────┘
  610. ",
  611. _output
  612. );
  613. cm.Position = new Point (41, 9);
  614. cm.Show ();
  615. Application.Refresh ();
  616. Assert.Equal (new Point (41, 9), cm.Position);
  617. TestHelpers.AssertDriverContentsWithFrameAre (
  618. @"
  619. ┌────────┐
  620. │ One │
  621. │ Two │
  622. │ Three │
  623. │ Four ►│
  624. │ Five │
  625. │ Six │
  626. └────────┘
  627. ",
  628. _output
  629. );
  630. Assert.True (
  631. top.Subviews [0]
  632. .OnMouseEvent (
  633. new MouseEvent { X = 30, Y = 4, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
  634. )
  635. );
  636. Application.Refresh ();
  637. Assert.Equal (new Point (41, 9), cm.Position);
  638. TestHelpers.AssertDriverContentsWithFrameAre (
  639. @"
  640. ┌────────┐
  641. ┌───────────┐│ One │
  642. │ SubMenu1 ││ Two │
  643. │ SubMenu2 ││ Three │
  644. │ SubMenu3 ││ Four ►│
  645. │ SubMenu4 ││ Five │
  646. │ SubMenu5 ││ Six │
  647. │ SubMenu6 │└────────┘
  648. │ SubMenu7 │
  649. └───────────┘
  650. ",
  651. _output
  652. );
  653. cm.Position = new Point (41, 22);
  654. cm.Show ();
  655. Application.Refresh ();
  656. Assert.Equal (new Point (41, 22), cm.Position);
  657. TestHelpers.AssertDriverContentsWithFrameAre (
  658. @"
  659. ┌────────┐
  660. │ One │
  661. │ Two │
  662. │ Three │
  663. │ Four ►│
  664. │ Five │
  665. │ Six │
  666. └────────┘
  667. ",
  668. _output
  669. );
  670. Assert.True (
  671. top.Subviews [0]
  672. .OnMouseEvent (
  673. new MouseEvent { X = 30, Y = 4, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
  674. )
  675. );
  676. Application.Refresh ();
  677. Assert.Equal (new Point (41, 22), cm.Position);
  678. TestHelpers.AssertDriverContentsWithFrameAre (
  679. @"
  680. ┌───────────┐
  681. │ SubMenu1 │┌────────┐
  682. │ SubMenu2 ││ One │
  683. │ SubMenu3 ││ Two │
  684. │ SubMenu4 ││ Three │
  685. │ SubMenu5 ││ Four ►│
  686. │ SubMenu6 ││ Five │
  687. │ SubMenu7 ││ Six │
  688. └───────────┘└────────┘
  689. ",
  690. _output
  691. );
  692. ((FakeDriver)Application.Driver).SetBufferSize (18, 8);
  693. cm.Position = new Point (19, 10);
  694. cm.Show ();
  695. Application.Refresh ();
  696. Assert.Equal (new Point (19, 10), cm.Position);
  697. TestHelpers.AssertDriverContentsWithFrameAre (
  698. @"
  699. ┌────────┐
  700. │ One │
  701. │ Two │
  702. │ Three │
  703. │ Four ►│
  704. │ Five │
  705. │ Six │
  706. └────────┘
  707. ",
  708. _output
  709. );
  710. Assert.True (
  711. top.Subviews [0]
  712. .OnMouseEvent (
  713. new MouseEvent { X = 30, Y = 4, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
  714. )
  715. );
  716. Application.Refresh ();
  717. Assert.Equal (new Point (19, 10), cm.Position);
  718. TestHelpers.AssertDriverContentsWithFrameAre (
  719. @"
  720. ┌───────────┐────┐
  721. │ SubMenu1 │ │
  722. │ SubMenu2 │ │
  723. │ SubMenu3 │ee │
  724. │ SubMenu4 │r ►│
  725. │ SubMenu5 │e │
  726. │ SubMenu6 │ │
  727. │ SubMenu7 │────┘
  728. ",
  729. _output
  730. );
  731. }
  732. [Fact]
  733. [AutoInitShutdown]
  734. public void MouseFlags_Changing ()
  735. {
  736. var lbl = new Label { Text = "Original" };
  737. var cm = new ContextMenu ();
  738. lbl.MouseClick += (s, e) =>
  739. {
  740. if (e.MouseEvent.Flags == cm.MouseFlags)
  741. {
  742. lbl.Text = "Replaced";
  743. e.Handled = true;
  744. }
  745. };
  746. Toplevel top = Application.Top;
  747. top.Add (lbl);
  748. Application.Begin (top);
  749. Assert.True (lbl.OnMouseEvent (new MouseEvent { Flags = cm.MouseFlags }));
  750. Assert.Equal ("Replaced", lbl.Text);
  751. lbl.Text = "Original";
  752. cm.MouseFlags = MouseFlags.Button2Clicked;
  753. Assert.True (lbl.OnMouseEvent (new MouseEvent { Flags = cm.MouseFlags }));
  754. Assert.Equal ("Replaced", lbl.Text);
  755. }
  756. [Fact]
  757. [AutoInitShutdown]
  758. public void MouseFlagsChanged_Event ()
  759. {
  760. var oldMouseFlags = new MouseFlags ();
  761. var cm = new ContextMenu ();
  762. cm.MouseFlagsChanged += (s, e) => oldMouseFlags = e.OldValue;
  763. cm.MouseFlags = MouseFlags.Button2Clicked;
  764. Assert.Equal (MouseFlags.Button2Clicked, cm.MouseFlags);
  765. Assert.Equal (MouseFlags.Button3Clicked, oldMouseFlags);
  766. }
  767. [Fact]
  768. [AutoInitShutdown]
  769. public void Position_Changing ()
  770. {
  771. var cm = new ContextMenu
  772. {
  773. Position = new Point (10, 5),
  774. MenuItems = new MenuBarItem (
  775. [
  776. new MenuItem ("One", "", null),
  777. new MenuItem ("Two", "", null)
  778. ]
  779. )
  780. };
  781. cm.Show ();
  782. Application.Begin (Application.Top);
  783. var expected = @"
  784. ┌──────┐
  785. │ One │
  786. │ Two │
  787. └──────┘
  788. ";
  789. TestHelpers.AssertDriverContentsAre (expected, _output);
  790. cm.Position = new Point (5, 10);
  791. cm.Show ();
  792. Application.Refresh ();
  793. expected = @"
  794. ┌──────┐
  795. │ One │
  796. │ Two │
  797. └──────┘
  798. ";
  799. TestHelpers.AssertDriverContentsAre (expected, _output);
  800. }
  801. [Fact]
  802. [AutoInitShutdown]
  803. public void RequestStop_While_ContextMenu_Is_Open_Does_Not_Throws ()
  804. {
  805. ContextMenu cm = Create_ContextMenu_With_Two_MenuItem (10, 5);
  806. Toplevel top = Application.Top;
  807. var isMenuAllClosed = false;
  808. MenuBarItem mi = null;
  809. int iterations = -1;
  810. Application.Iteration += (s, a) =>
  811. {
  812. iterations++;
  813. if (iterations == 0)
  814. {
  815. cm.Show ();
  816. Assert.True (ContextMenu.IsShow);
  817. mi = cm.MenuBar.Menus [0];
  818. mi.Action = () =>
  819. {
  820. var dialog1 = new Dialog ();
  821. Application.Run (dialog1);
  822. Assert.False (ContextMenu.IsShow);
  823. Assert.True (isMenuAllClosed);
  824. };
  825. cm.MenuBar.MenuAllClosed += (_, _) => isMenuAllClosed = true;
  826. }
  827. else if (iterations == 1)
  828. {
  829. mi.Action ();
  830. }
  831. else if (iterations == 2)
  832. {
  833. Application.RequestStop ();
  834. }
  835. else if (iterations == 3)
  836. {
  837. isMenuAllClosed = false;
  838. cm.Show ();
  839. Assert.True (ContextMenu.IsShow);
  840. cm.MenuBar.MenuAllClosed += (_, _) => isMenuAllClosed = true;
  841. }
  842. else if (iterations == 4)
  843. {
  844. Exception exception = Record.Exception (() => Application.RequestStop ());
  845. Assert.Null (exception);
  846. }
  847. else
  848. {
  849. Application.RequestStop ();
  850. }
  851. };
  852. var isTopClosed = false;
  853. top.Closing += (_, _) =>
  854. {
  855. var dialog2 = new Dialog ();
  856. Application.Run (dialog2);
  857. Assert.False (ContextMenu.IsShow);
  858. Assert.True (isMenuAllClosed);
  859. isTopClosed = true;
  860. };
  861. Application.Run ();
  862. Assert.True (isTopClosed);
  863. Assert.False (ContextMenu.IsShow);
  864. Assert.True (isMenuAllClosed);
  865. }
  866. [Fact]
  867. [AutoInitShutdown]
  868. public void Show_Display_At_Zero_If_The_Toplevel_Height_Is_Less_Than_The_Menu_Height ()
  869. {
  870. ((FakeDriver)Application.Driver).SetBufferSize (80, 3);
  871. var cm = new ContextMenu
  872. {
  873. Position = Point.Empty,
  874. MenuItems = new MenuBarItem (
  875. [
  876. new MenuItem ("One", "", null),
  877. new MenuItem ("Two", "", null)
  878. ]
  879. )
  880. };
  881. Assert.Equal (Point.Empty, cm.Position);
  882. cm.Show ();
  883. Assert.Equal (Point.Empty, cm.Position);
  884. Application.Begin (Application.Top);
  885. var expected = @"
  886. ┌──────┐
  887. │ One │
  888. │ Two │";
  889. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  890. Assert.Equal (new Rectangle (0, 0, 8, 3), pos);
  891. cm.Hide ();
  892. Assert.Equal (Point.Empty, cm.Position);
  893. }
  894. [Fact]
  895. [AutoInitShutdown]
  896. public void Show_Display_At_Zero_If_The_Toplevel_Width_Is_Less_Than_The_Menu_Width ()
  897. {
  898. ((FakeDriver)Application.Driver).SetBufferSize (5, 25);
  899. var cm = new ContextMenu
  900. {
  901. Position = Point.Empty,
  902. MenuItems = new MenuBarItem (
  903. [
  904. new MenuItem ("One", "", null),
  905. new MenuItem ("Two", "", null)
  906. ]
  907. )
  908. };
  909. Assert.Equal (Point.Empty, cm.Position);
  910. cm.Show ();
  911. Assert.Equal (Point.Empty, cm.Position);
  912. Application.Begin (Application.Top);
  913. var expected = @"
  914. ┌────
  915. │ One
  916. │ Two
  917. └────";
  918. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  919. Assert.Equal (new Rectangle (0, 1, 5, 4), pos);
  920. cm.Hide ();
  921. Assert.Equal (Point.Empty, cm.Position);
  922. }
  923. [Fact]
  924. [AutoInitShutdown]
  925. public void Show_Display_Below_The_Bottom_Host_If_Has_Enough_Space ()
  926. {
  927. var view = new View
  928. {
  929. X = 10,
  930. Y = 5,
  931. Width = 10,
  932. Height = 1,
  933. Text = "View"
  934. };
  935. var cm = new ContextMenu
  936. {
  937. Host = view,
  938. Position = new Point (10, 5),
  939. MenuItems = new MenuBarItem (
  940. [
  941. new MenuItem ("One", "", null),
  942. new MenuItem ("Two", "", null)
  943. ]
  944. )
  945. };
  946. Application.Top.Add (view);
  947. Application.Begin (Application.Top);
  948. Assert.Equal (new Point (10, 5), cm.Position);
  949. cm.Show ();
  950. Application.Top.Draw ();
  951. Assert.Equal (new Point (10, 5), cm.Position);
  952. var expected = @"
  953. View
  954. ┌──────┐
  955. │ One │
  956. │ Two │
  957. └──────┘
  958. ";
  959. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  960. Assert.Equal (new Rectangle (10, 5, 18, 5), pos);
  961. cm.Hide ();
  962. Assert.Equal (new Point (10, 5), cm.Position);
  963. cm.Host.X = 5;
  964. cm.Host.Y = 10;
  965. cm.Host.Height = 3;
  966. cm.Show ();
  967. Application.Top.Draw ();
  968. Assert.Equal (new Point (5, 12), cm.Position);
  969. expected = @"
  970. View
  971. ┌──────┐
  972. │ One │
  973. │ Two │
  974. └──────┘
  975. ";
  976. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  977. Assert.Equal (new Rectangle (5, 10, 13, 7), pos);
  978. cm.Hide ();
  979. Assert.Equal (new Point (5, 12), cm.Position);
  980. }
  981. [Fact]
  982. [AutoInitShutdown]
  983. public void Show_Ensures_Display_Inside_The_Container_But_Preserves_Position ()
  984. {
  985. var cm = new ContextMenu
  986. {
  987. Position = new Point (80, 25),
  988. MenuItems = new MenuBarItem (
  989. [
  990. new MenuItem ("One", "", null),
  991. new MenuItem ("Two", "", null)
  992. ]
  993. )
  994. };
  995. Assert.Equal (new Point (80, 25), cm.Position);
  996. cm.Show ();
  997. Assert.Equal (new Point (80, 25), cm.Position);
  998. Application.Begin (Application.Top);
  999. var expected = @"
  1000. ┌──────┐
  1001. │ One │
  1002. │ Two │
  1003. └──────┘
  1004. ";
  1005. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  1006. Assert.Equal (new Rectangle (72, 21, 80, 4), pos);
  1007. cm.Hide ();
  1008. Assert.Equal (new Point (80, 25), cm.Position);
  1009. }
  1010. [Fact]
  1011. [AutoInitShutdown]
  1012. public void Show_Ensures_Display_Inside_The_Container_Without_Overlap_The_Host ()
  1013. {
  1014. var view = new View
  1015. {
  1016. X = Pos.AnchorEnd (10),
  1017. Y = Pos.AnchorEnd (1),
  1018. Width = 10,
  1019. Height = 1,
  1020. Text = "View"
  1021. };
  1022. var cm = new ContextMenu
  1023. {
  1024. Host = view,
  1025. MenuItems = new MenuBarItem (
  1026. [
  1027. new MenuItem ("One", "", null),
  1028. new MenuItem ("Two", "", null)
  1029. ]
  1030. )
  1031. };
  1032. Application.Top.Add (view);
  1033. Application.Begin (Application.Top);
  1034. Assert.Equal (new Rectangle (70, 24, 10, 1), view.Frame);
  1035. Assert.Equal (Point.Empty, cm.Position);
  1036. cm.Show ();
  1037. Assert.Equal (new Point (70, 24), cm.Position);
  1038. Application.Top.Draw ();
  1039. var expected = @"
  1040. ┌──────┐
  1041. │ One │
  1042. │ Two │
  1043. └──────┘
  1044. View
  1045. ";
  1046. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  1047. Assert.Equal (new Rectangle (70, 20, 78, 5), pos);
  1048. cm.Hide ();
  1049. Assert.Equal (new Point (70, 24), cm.Position);
  1050. }
  1051. [Fact]
  1052. [AutoInitShutdown]
  1053. public void Show_Hide_IsShow ()
  1054. {
  1055. ContextMenu cm = Create_ContextMenu_With_Two_MenuItem (10, 5);
  1056. cm.Show ();
  1057. Assert.True (ContextMenu.IsShow);
  1058. Application.Begin (Application.Top);
  1059. var expected = @"
  1060. ┌──────┐
  1061. │ One │
  1062. │ Two │
  1063. └──────┘
  1064. ";
  1065. TestHelpers.AssertDriverContentsAre (expected, _output);
  1066. cm.Hide ();
  1067. Assert.False (ContextMenu.IsShow);
  1068. Application.Refresh ();
  1069. expected = "";
  1070. TestHelpers.AssertDriverContentsAre (expected, _output);
  1071. }
  1072. [Fact]
  1073. [AutoInitShutdown]
  1074. public void UseSubMenusSingleFrame_True_By_Mouse ()
  1075. {
  1076. var cm = new ContextMenu
  1077. {
  1078. Position = new Point (5, 10),
  1079. MenuItems = new MenuBarItem (
  1080. "Numbers",
  1081. [
  1082. new MenuItem ("One", "", null),
  1083. new MenuBarItem (
  1084. "Two",
  1085. [
  1086. new MenuItem (
  1087. "Sub-Menu 1",
  1088. "",
  1089. null
  1090. ),
  1091. new MenuItem ("Sub-Menu 2", "", null)
  1092. ]
  1093. ),
  1094. new MenuItem ("Three", "", null)
  1095. ]
  1096. ),
  1097. UseSubMenusSingleFrame = true
  1098. };
  1099. cm.Show ();
  1100. RunState rs = Application.Begin (Application.Top);
  1101. Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame);
  1102. TestHelpers.AssertDriverContentsWithFrameAre (
  1103. @"
  1104. ┌────────┐
  1105. │ One │
  1106. │ Two ►│
  1107. │ Three │
  1108. └────────┘",
  1109. _output
  1110. );
  1111. Application.OnMouseEvent (
  1112. new MouseEventEventArgs (
  1113. new MouseEvent { X = 5, Y = 13, Flags = MouseFlags.Button1Clicked }
  1114. )
  1115. );
  1116. var firstIteration = false;
  1117. Application.RunIteration (ref rs, ref firstIteration);
  1118. Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame);
  1119. Assert.Equal (new Rectangle (5, 11, 15, 6), Application.Top.Subviews [1].Frame);
  1120. TestHelpers.AssertDriverContentsWithFrameAre (
  1121. @"
  1122. ┌─────────────┐
  1123. │◄ Two │
  1124. ├─────────────┤
  1125. │ Sub-Menu 1 │
  1126. │ Sub-Menu 2 │
  1127. └─────────────┘",
  1128. _output
  1129. );
  1130. Application.OnMouseEvent (
  1131. new MouseEventEventArgs (
  1132. new MouseEvent { X = 5, Y = 12, Flags = MouseFlags.Button1Clicked }
  1133. )
  1134. );
  1135. firstIteration = false;
  1136. Application.RunIteration (ref rs, ref firstIteration);
  1137. Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame);
  1138. TestHelpers.AssertDriverContentsWithFrameAre (
  1139. @"
  1140. ┌────────┐
  1141. │ One │
  1142. │ Two ►│
  1143. │ Three │
  1144. └────────┘",
  1145. _output
  1146. );
  1147. Application.End (rs);
  1148. }
  1149. private ContextMenu Create_ContextMenu_With_Two_MenuItem (int x, int y)
  1150. {
  1151. return new ContextMenu
  1152. {
  1153. Position = new Point (x, y),
  1154. MenuItems = new MenuBarItem (
  1155. new MenuItem [] { new ("One", "", null), new ("Two", "", null) }
  1156. )
  1157. };
  1158. }
  1159. }