ContextMenuTests.cs 35 KB

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