MenuTests.cs 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Terminal.Gui;
  5. using Xunit;
  6. using Xunit.Abstractions;
  7. //using static Terminal.Gui.ViewTests.MenuTests;
  8. namespace Terminal.Gui.ViewsTests {
  9. public class MenuTests {
  10. readonly ITestOutputHelper output;
  11. public MenuTests (ITestOutputHelper output)
  12. {
  13. this.output = output;
  14. }
  15. [Fact]
  16. public void Constuctors_Defaults ()
  17. {
  18. var menu = new Menu (new MenuBar (), 0, 0, new MenuBarItem ());
  19. Assert.Equal (Colors.Menu, menu.ColorScheme);
  20. Assert.True (menu.CanFocus);
  21. Assert.False (menu.WantContinuousButtonPressed);
  22. var menuBar = new MenuBar ();
  23. Assert.Equal (0, menuBar.X);
  24. Assert.Equal (0, menuBar.Y);
  25. Assert.IsType<Dim.DimFill> (menuBar.Width);
  26. Assert.Equal (1, menuBar.Height);
  27. Assert.Empty (menuBar.Menus);
  28. Assert.Equal (Colors.Menu, menuBar.ColorScheme);
  29. Assert.True (menuBar.WantMousePositionReports);
  30. Assert.False (menuBar.IsMenuOpen);
  31. menuBar = new MenuBar (new MenuBarItem [] { });
  32. Assert.Equal (0, menuBar.X);
  33. Assert.Equal (0, menuBar.Y);
  34. Assert.IsType<Dim.DimFill> (menuBar.Width);
  35. Assert.Equal (1, menuBar.Height);
  36. Assert.Empty (menuBar.Menus);
  37. Assert.Equal (Colors.Menu, menuBar.ColorScheme);
  38. Assert.True (menuBar.WantMousePositionReports);
  39. Assert.False (menuBar.IsMenuOpen);
  40. var menuBarItem = new MenuBarItem ();
  41. Assert.Equal ("", menuBarItem.Title);
  42. Assert.Null (menuBarItem.Parent);
  43. Assert.Empty (menuBarItem.Children);
  44. menuBarItem = new MenuBarItem (new MenuBarItem [] { });
  45. Assert.Equal ("", menuBarItem.Title);
  46. Assert.Null (menuBarItem.Parent);
  47. Assert.Empty (menuBarItem.Children);
  48. menuBarItem = new MenuBarItem ("Test", new MenuBarItem [] { });
  49. Assert.Equal ("Test", menuBarItem.Title);
  50. Assert.Null (menuBarItem.Parent);
  51. Assert.Empty (menuBarItem.Children);
  52. menuBarItem = new MenuBarItem ("Test", new List<MenuItem []> ());
  53. Assert.Equal ("Test", menuBarItem.Title);
  54. Assert.Null (menuBarItem.Parent);
  55. Assert.Empty (menuBarItem.Children);
  56. menuBarItem = new MenuBarItem ("Test", "Help", null);
  57. Assert.Equal ("Test", menuBarItem.Title);
  58. Assert.Equal ("Help", menuBarItem.Help);
  59. Assert.Null (menuBarItem.Action);
  60. Assert.Null (menuBarItem.CanExecute);
  61. Assert.Null (menuBarItem.Parent);
  62. Assert.Equal (Key.Null, menuBarItem.Shortcut);
  63. var menuItem = new MenuItem ();
  64. Assert.Equal ("", menuItem.Title);
  65. Assert.Equal ("", menuItem.Help);
  66. Assert.Null (menuItem.Action);
  67. Assert.Null (menuItem.CanExecute);
  68. Assert.Null (menuItem.Parent);
  69. Assert.Equal (Key.Null, menuItem.Shortcut);
  70. menuItem = new MenuItem ("Test", "Help", Run, () => { return true; }, new MenuItem (), Key.F1);
  71. Assert.Equal ("Test", menuItem.Title);
  72. Assert.Equal ("Help", menuItem.Help);
  73. Assert.Equal (Run, menuItem.Action);
  74. Assert.NotNull (menuItem.CanExecute);
  75. Assert.NotNull (menuItem.Parent);
  76. Assert.Equal (Key.F1, menuItem.Shortcut);
  77. void Run () { }
  78. }
  79. [Fact]
  80. public void Exceptions ()
  81. {
  82. Assert.Throws<ArgumentNullException> (() => new MenuBarItem ("Test", (MenuItem [])null, null));
  83. Assert.Throws<ArgumentNullException> (() => new MenuBarItem ("Test", (List<MenuItem []>)null, null));
  84. }
  85. [Fact]
  86. [AutoInitShutdown]
  87. public void MenuOpening_MenuOpened_MenuClosing_Events ()
  88. {
  89. var miAction = "";
  90. var isMenuClosed = true;
  91. var cancelClosing = false;
  92. var menu = new MenuBar (new MenuBarItem [] {
  93. new MenuBarItem ("_File", new MenuItem [] {
  94. new MenuItem ("_New", "Creates new file.", New)
  95. })
  96. });
  97. menu.MenuOpening += (s, e) => {
  98. Assert.Equal ("_File", e.CurrentMenu.Title);
  99. Assert.Equal ("_New", e.CurrentMenu.Children [0].Title);
  100. Assert.Equal ("Creates new file.", e.CurrentMenu.Children [0].Help);
  101. Assert.Equal (New, e.CurrentMenu.Children [0].Action);
  102. e.CurrentMenu.Children [0].Action ();
  103. Assert.Equal ("New", miAction);
  104. e.NewMenuBarItem = new MenuBarItem ("_Edit", new MenuItem [] {
  105. new MenuItem ("_Copy", "Copies the selection.", Copy)
  106. });
  107. };
  108. menu.MenuOpened += (s, e) => {
  109. var mi = e.MenuItem;
  110. Assert.Equal ("_Edit", mi.Parent.Title);
  111. Assert.Equal ("_Copy", mi.Title);
  112. Assert.Equal ("Copies the selection.", mi.Help);
  113. Assert.Equal (Copy, mi.Action);
  114. mi.Action ();
  115. Assert.Equal ("Copy", miAction);
  116. };
  117. menu.MenuClosing += (s, e) => {
  118. Assert.False (isMenuClosed);
  119. if (cancelClosing) {
  120. e.Cancel = true;
  121. isMenuClosed = false;
  122. } else isMenuClosed = true;
  123. };
  124. Application.Top.Add (menu);
  125. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  126. Assert.True (menu.IsMenuOpen);
  127. isMenuClosed = !menu.IsMenuOpen;
  128. Assert.False (isMenuClosed);
  129. Application.Top.Redraw (Application.Top.Bounds);
  130. var expected = @"
  131. Edit
  132. ┌──────────────────────────────┐
  133. │ Copy Copies the selection. │
  134. └──────────────────────────────┘
  135. ";
  136. TestHelpers.AssertDriverContentsAre (expected, output);
  137. cancelClosing = true;
  138. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  139. Assert.True (menu.IsMenuOpen);
  140. Assert.False (isMenuClosed);
  141. Application.Top.Redraw (Application.Top.Bounds);
  142. expected = @"
  143. Edit
  144. ┌──────────────────────────────┐
  145. │ Copy Copies the selection. │
  146. └──────────────────────────────┘
  147. ";
  148. TestHelpers.AssertDriverContentsAre (expected, output);
  149. cancelClosing = false;
  150. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  151. Assert.False (menu.IsMenuOpen);
  152. Assert.True (isMenuClosed);
  153. Application.Top.Redraw (Application.Top.Bounds);
  154. expected = @"
  155. Edit
  156. ";
  157. TestHelpers.AssertDriverContentsAre (expected, output);
  158. void New () => miAction = "New";
  159. void Copy () => miAction = "Copy";
  160. }
  161. [Fact, AutoInitShutdown]
  162. public void MenuOpened_On_Disabled_MenuItem ()
  163. {
  164. MenuItem miCurrent = null;
  165. Menu mCurrent = null;
  166. var menu = new MenuBar (new MenuBarItem [] {
  167. new MenuBarItem ("_File", new MenuItem [] {
  168. new MenuBarItem ("_New", new MenuItem [] {
  169. new MenuItem ("_New doc", "Creates new doc.", null, () => false)
  170. }),
  171. null,
  172. new MenuItem ("_Save", "Saves the file.", null, null)
  173. })
  174. });
  175. menu.MenuOpened += (s, e) => {
  176. miCurrent = e.MenuItem;
  177. mCurrent = menu.openMenu;
  178. };
  179. menu.UseKeysUpDownAsKeysLeftRight = true;
  180. Application.Top.Add (menu);
  181. // open the menu
  182. Assert.True (menu.MouseEvent (new MouseEvent () {
  183. X = 1,
  184. Y = 0,
  185. Flags = MouseFlags.Button1Pressed,
  186. View = menu
  187. }));
  188. Assert.True (menu.IsMenuOpen);
  189. Assert.Equal ("_File", miCurrent.Parent.Title);
  190. Assert.Equal ("_New", miCurrent.Title);
  191. Assert.True (mCurrent.MouseEvent (new MouseEvent () {
  192. X = 1,
  193. Y = 1,
  194. Flags = MouseFlags.ReportMousePosition,
  195. View = mCurrent
  196. }));
  197. Assert.True (menu.IsMenuOpen);
  198. Assert.Equal ("_File", miCurrent.Parent.Title);
  199. Assert.Equal ("_New", miCurrent.Title);
  200. Assert.True (mCurrent.MouseEvent (new MouseEvent () {
  201. X = 1,
  202. Y = 2,
  203. Flags = MouseFlags.ReportMousePosition,
  204. View = mCurrent
  205. }));
  206. Assert.True (menu.IsMenuOpen);
  207. Assert.Equal ("_File", miCurrent.Parent.Title);
  208. Assert.Equal ("_New", miCurrent.Title);
  209. Assert.True (mCurrent.MouseEvent (new MouseEvent () {
  210. X = 1,
  211. Y = 3,
  212. Flags = MouseFlags.ReportMousePosition,
  213. View = mCurrent
  214. }));
  215. Assert.True (menu.IsMenuOpen);
  216. Assert.Equal ("_File", miCurrent.Parent.Title);
  217. Assert.Equal ("_Save", miCurrent.Title);
  218. // close the menu
  219. Assert.True (menu.MouseEvent (new MouseEvent () {
  220. X = 1,
  221. Y = 0,
  222. Flags = MouseFlags.Button1Pressed,
  223. View = menu
  224. }));
  225. Assert.False (menu.IsMenuOpen);
  226. // open the menu
  227. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  228. Assert.True (menu.IsMenuOpen);
  229. Assert.Equal ("_New", miCurrent.Parent.Title);
  230. Assert.Equal ("_New doc", miCurrent.Title);
  231. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  232. Assert.True (menu.IsMenuOpen);
  233. Assert.Equal ("_File", miCurrent.Parent.Title);
  234. Assert.Equal ("_Save", miCurrent.Title);
  235. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  236. Assert.True (menu.IsMenuOpen);
  237. Assert.Equal ("_File", miCurrent.Parent.Title);
  238. Assert.Equal ("_New", miCurrent.Title);
  239. // close the menu
  240. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  241. Assert.False (menu.IsMenuOpen);
  242. }
  243. [Fact]
  244. [AutoInitShutdown]
  245. public void MouseEvent_Test ()
  246. {
  247. MenuItem miCurrent = null;
  248. Menu mCurrent = null;
  249. var menu = new MenuBar (new MenuBarItem [] {
  250. new MenuBarItem ("_File", new MenuItem [] {
  251. new MenuItem ("_New", "", null),
  252. new MenuItem ("_Open", "", null),
  253. new MenuItem ("_Save", "", null)
  254. }),
  255. new MenuBarItem ("_Edit", new MenuItem [] {
  256. new MenuItem ("_Copy", "", null),
  257. new MenuItem ("C_ut", "", null),
  258. new MenuItem ("_Paste", "", null)
  259. })
  260. });
  261. menu.MenuOpened += (s, e) => {
  262. miCurrent = e.MenuItem;
  263. mCurrent = menu.openCurrentMenu;
  264. };
  265. Application.Top.Add (menu);
  266. Assert.True (menu.MouseEvent (new MouseEvent () {
  267. X = 10,
  268. Y = 0,
  269. Flags = MouseFlags.Button1Pressed,
  270. View = menu
  271. }));
  272. Assert.True (menu.IsMenuOpen);
  273. Assert.Equal ("_Edit", miCurrent.Parent.Title);
  274. Assert.Equal ("_Copy", miCurrent.Title);
  275. Assert.True (mCurrent.MouseEvent (new MouseEvent () {
  276. X = 10,
  277. Y = 3,
  278. Flags = MouseFlags.ReportMousePosition,
  279. View = mCurrent
  280. }));
  281. Assert.True (menu.IsMenuOpen);
  282. Assert.Equal ("_Edit", miCurrent.Parent.Title);
  283. Assert.Equal ("_Paste", miCurrent.Title);
  284. for (int i = 2; i >= -1; i--) {
  285. if (i == -1) Assert.False (mCurrent.MouseEvent (new MouseEvent () {
  286. X = 10,
  287. Y = i,
  288. Flags = MouseFlags.ReportMousePosition,
  289. View = menu
  290. }));
  291. else Assert.True (mCurrent.MouseEvent (new MouseEvent () {
  292. X = 10,
  293. Y = i,
  294. Flags = MouseFlags.ReportMousePosition,
  295. View = mCurrent
  296. }));
  297. Assert.True (menu.IsMenuOpen);
  298. if (i == 2) {
  299. Assert.Equal ("_Edit", miCurrent.Parent.Title);
  300. Assert.Equal ("C_ut", miCurrent.Title);
  301. } else if (i == 1) {
  302. Assert.Equal ("_Edit", miCurrent.Parent.Title);
  303. Assert.Equal ("_Copy", miCurrent.Title);
  304. } else if (i == 0) {
  305. Assert.Equal ("_Edit", miCurrent.Parent.Title);
  306. Assert.Equal ("_Copy", miCurrent.Title);
  307. } else {
  308. Assert.Equal ("_Edit", miCurrent.Parent.Title);
  309. Assert.Equal ("_Copy", miCurrent.Title);
  310. }
  311. }
  312. }
  313. [Fact]
  314. [AutoInitShutdown]
  315. public void KeyBindings_Command ()
  316. {
  317. var miAction = "";
  318. MenuItem mbiCurrent = null;
  319. MenuItem miCurrent = null;
  320. Menu mCurrent = null;
  321. var menu = new MenuBar (new MenuBarItem [] {
  322. new MenuBarItem ("_File", new MenuItem [] {
  323. new MenuItem ("_New", "", () => miAction ="New"),
  324. new MenuItem ("_Open", "", () => miAction ="Open"),
  325. new MenuItem ("_Save", "", () => miAction ="Save"),
  326. null,
  327. new MenuItem ("_Quit", "", () => miAction ="Quit"),
  328. }),
  329. new MenuBarItem ("_Edit", new MenuItem [] {
  330. new MenuItem ("_Copy", "", () => miAction ="Copy"),
  331. new MenuItem ("C_ut", "", () => miAction ="Cut"),
  332. new MenuItem ("_Paste", "", () => miAction ="Paste"),
  333. new MenuBarItem ("_Find and Replace", new MenuItem [] {
  334. new MenuItem ("F_ind", "", null),
  335. new MenuItem ("_Replace", "", null)
  336. }),
  337. new MenuItem ("_Select All", "", () => miAction ="Select All")
  338. }),
  339. new MenuBarItem ("_About", "Top-Level", () => miAction ="About")
  340. });
  341. menu.MenuOpening += (s, e) => mbiCurrent = e.CurrentMenu;
  342. menu.MenuOpened += (s, e) => {
  343. miCurrent = e.MenuItem;
  344. mCurrent = menu.openCurrentMenu;
  345. };
  346. menu.MenuClosing += (s, e) => {
  347. mbiCurrent = null;
  348. miCurrent = null;
  349. mCurrent = null;
  350. };
  351. menu.UseKeysUpDownAsKeysLeftRight = true;
  352. Application.Top.Add (menu);
  353. Application.Begin (Application.Top);
  354. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  355. Assert.True (menu.IsMenuOpen);
  356. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  357. Assert.Equal ("_New", GetCurrentMenuTitle ());
  358. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
  359. Assert.True (menu.IsMenuOpen);
  360. Assert.Equal ("_About", GetCurrentMenuBarItemTitle ());
  361. Assert.Equal ("_About", GetCurrentMenuTitle ());
  362. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  363. Assert.True (menu.IsMenuOpen);
  364. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  365. Assert.Equal ("_New", GetCurrentMenuTitle ());
  366. Assert.True (menu.ProcessKey (new KeyEvent (Key.Esc, new KeyModifiers ())));
  367. Assert.False (menu.IsMenuOpen);
  368. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  369. Assert.Equal ("None", GetCurrentMenuTitle ());
  370. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  371. Assert.True (menu.IsMenuOpen);
  372. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  373. Assert.Equal ("_New", GetCurrentMenuTitle ());
  374. Assert.True (menu.ProcessKey (new KeyEvent (Key.C | Key.CtrlMask, new KeyModifiers ())));
  375. Assert.False (menu.IsMenuOpen);
  376. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  377. Assert.Equal ("None", GetCurrentMenuTitle ());
  378. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  379. Assert.True (menu.IsMenuOpen);
  380. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  381. Assert.Equal ("_New", GetCurrentMenuTitle ());
  382. Assert.True (menu.ProcessKey (new KeyEvent (Key.Esc, new KeyModifiers ())));
  383. Assert.False (menu.IsMenuOpen);
  384. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  385. Assert.Equal ("None", GetCurrentMenuTitle ());
  386. Assert.True (menu.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  387. Assert.True (menu.IsMenuOpen);
  388. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  389. Assert.Equal ("_New", GetCurrentMenuTitle ());
  390. Assert.False (mCurrent.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ())));
  391. Assert.True (menu.IsMenuOpen);
  392. Assert.True (Application.Top.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ())));
  393. Assert.False (menu.IsMenuOpen);
  394. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  395. Assert.Equal ("None", GetCurrentMenuTitle ());
  396. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  397. Assert.True (menu.IsMenuOpen);
  398. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  399. Assert.Equal ("_New", GetCurrentMenuTitle ());
  400. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  401. Assert.True (menu.IsMenuOpen);
  402. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  403. Assert.Equal ("_Quit", GetCurrentMenuTitle ());
  404. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  405. Assert.True (menu.IsMenuOpen);
  406. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  407. Assert.Equal ("_New", GetCurrentMenuTitle ());
  408. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
  409. Assert.True (menu.IsMenuOpen);
  410. Assert.Equal ("_About", GetCurrentMenuBarItemTitle ());
  411. Assert.Equal ("_About", GetCurrentMenuTitle ());
  412. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  413. Assert.True (menu.IsMenuOpen);
  414. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  415. Assert.Equal ("_New", GetCurrentMenuTitle ());
  416. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.Esc, new KeyModifiers ())));
  417. Assert.False (menu.IsMenuOpen);
  418. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  419. Assert.Equal ("None", GetCurrentMenuTitle ());
  420. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  421. Assert.True (menu.IsMenuOpen);
  422. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  423. Assert.Equal ("_New", GetCurrentMenuTitle ());
  424. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  425. Assert.False (menu.IsMenuOpen);
  426. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  427. Assert.Equal ("None", GetCurrentMenuTitle ());
  428. Application.MainLoop.MainIteration ();
  429. Assert.Equal ("New", miAction);
  430. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  431. Assert.True (menu.IsMenuOpen);
  432. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  433. Assert.Equal ("_New", GetCurrentMenuTitle ());
  434. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
  435. Assert.True (menu.IsMenuOpen);
  436. Assert.Equal ("_About", GetCurrentMenuBarItemTitle ());
  437. Assert.Equal ("_About", GetCurrentMenuTitle ());
  438. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  439. Assert.False (menu.IsMenuOpen);
  440. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  441. Assert.Equal ("None", GetCurrentMenuTitle ());
  442. Application.MainLoop.MainIteration ();
  443. Assert.Equal ("About", miAction);
  444. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  445. Assert.True (menu.IsMenuOpen);
  446. Assert.Equal ("_File", GetCurrentMenuBarItemTitle ());
  447. Assert.Equal ("_New", GetCurrentMenuTitle ());
  448. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  449. Assert.True (menu.IsMenuOpen);
  450. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  451. Assert.Equal ("_Copy", GetCurrentMenuTitle ());
  452. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  453. Assert.True (menu.IsMenuOpen);
  454. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  455. Assert.Equal ("C_ut", GetCurrentMenuTitle ());
  456. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  457. Assert.True (menu.IsMenuOpen);
  458. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  459. Assert.Equal ("_Edit", GetCurrenParenttMenuItemTitle ());
  460. Assert.Equal ("_Paste", GetCurrentMenuTitle ());
  461. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  462. Assert.True (menu.IsMenuOpen);
  463. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  464. Assert.Equal ("_Find and Replace", GetCurrenParenttMenuItemTitle ());
  465. Assert.Equal ("F_ind", GetCurrentMenuTitle ());
  466. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  467. Assert.True (menu.IsMenuOpen);
  468. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  469. Assert.Equal ("_Find and Replace", GetCurrenParenttMenuItemTitle ());
  470. Assert.Equal ("_Replace", GetCurrentMenuTitle ());
  471. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  472. Assert.True (menu.IsMenuOpen);
  473. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  474. Assert.Equal ("_Find and Replace", GetCurrenParenttMenuItemTitle ());
  475. Assert.Equal ("F_ind", GetCurrentMenuTitle ());
  476. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
  477. Assert.True (menu.IsMenuOpen);
  478. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  479. Assert.Equal ("_Edit", GetCurrenParenttMenuItemTitle ());
  480. Assert.Equal ("_Find and Replace", GetCurrentMenuTitle ());
  481. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ())));
  482. Assert.True (menu.IsMenuOpen);
  483. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  484. Assert.Equal ("_Edit", GetCurrenParenttMenuItemTitle ());
  485. Assert.Equal ("_Select All", GetCurrentMenuTitle ());
  486. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  487. Assert.True (menu.IsMenuOpen);
  488. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  489. Assert.Equal ("_Find and Replace", GetCurrenParenttMenuItemTitle ());
  490. Assert.Equal ("F_ind", GetCurrentMenuTitle ());
  491. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  492. Assert.True (menu.IsMenuOpen);
  493. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  494. Assert.Equal ("_Edit", GetCurrenParenttMenuItemTitle ());
  495. Assert.Equal ("_Find and Replace", GetCurrentMenuTitle ());
  496. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  497. Assert.True (menu.IsMenuOpen);
  498. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  499. Assert.Equal ("_Edit", GetCurrenParenttMenuItemTitle ());
  500. Assert.Equal ("_Paste", GetCurrentMenuTitle ());
  501. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  502. Assert.True (menu.IsMenuOpen);
  503. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  504. Assert.Equal ("C_ut", GetCurrentMenuTitle ());
  505. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
  506. Assert.True (menu.IsMenuOpen);
  507. Assert.Equal ("_Edit", GetCurrentMenuBarItemTitle ());
  508. Assert.Equal ("_Copy", GetCurrentMenuTitle ());
  509. Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  510. Assert.False (menu.IsMenuOpen);
  511. Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ());
  512. Assert.Equal ("None", GetCurrentMenuTitle ());
  513. Application.MainLoop.MainIteration ();
  514. Assert.Equal ("Copy", miAction);
  515. string GetCurrentMenuBarItemTitle ()
  516. {
  517. return mbiCurrent != null ? mbiCurrent.Title.ToString () : "Closed";
  518. }
  519. string GetCurrenParenttMenuItemTitle ()
  520. {
  521. return miCurrent?.Parent != null ? miCurrent.Parent.Title.ToString () : "None";
  522. }
  523. string GetCurrentMenuTitle ()
  524. {
  525. return miCurrent != null ? miCurrent.Title.ToString () : "None";
  526. }
  527. }
  528. [Fact, AutoInitShutdown]
  529. public void DrawFrame_With_Positive_Positions ()
  530. {
  531. var menu = new MenuBar (new MenuBarItem [] {
  532. new MenuBarItem (new MenuItem [] {
  533. new MenuItem ("One", "", null),
  534. new MenuItem ("Two", "", null)
  535. })
  536. });
  537. Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
  538. menu.OpenMenu ();
  539. Application.Begin (Application.Top);
  540. var expected = @"
  541. ┌──────┐
  542. │ One │
  543. │ Two │
  544. └──────┘
  545. ";
  546. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  547. Assert.Equal (new Rect (0, 1, 8, 4), pos);
  548. }
  549. [Fact, AutoInitShutdown]
  550. public void DrawFrame_With_Negative_Positions ()
  551. {
  552. var menu = new MenuBar (new MenuBarItem [] {
  553. new MenuBarItem (new MenuItem [] {
  554. new MenuItem ("One", "", null),
  555. new MenuItem ("Two", "", null)
  556. })
  557. }) {
  558. X = -1,
  559. Y = -1
  560. };
  561. Assert.Equal (new Point (-1, -1), new Point (menu.Frame.X, menu.Frame.Y));
  562. menu.OpenMenu ();
  563. Application.Begin (Application.Top);
  564. var expected = @"
  565. ──────┐
  566. One │
  567. Two │
  568. ──────┘
  569. ";
  570. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  571. Assert.Equal (new Rect (0, 0, 7, 4), pos);
  572. menu.CloseAllMenus ();
  573. menu.Frame = new Rect (-1, -2, menu.Frame.Width, menu.Frame.Height);
  574. menu.OpenMenu ();
  575. Application.Refresh ();
  576. expected = @"
  577. One │
  578. Two │
  579. ──────┘
  580. ";
  581. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  582. Assert.Equal (new Rect (1, 0, 7, 3), pos);
  583. menu.CloseAllMenus ();
  584. menu.Frame = new Rect (0, 0, menu.Frame.Width, menu.Frame.Height);
  585. ((FakeDriver)Application.Driver).SetBufferSize (7, 5);
  586. menu.OpenMenu ();
  587. Application.Refresh ();
  588. expected = @"
  589. ┌──────
  590. │ One
  591. │ Two
  592. └──────
  593. ";
  594. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  595. Assert.Equal (new Rect (0, 1, 7, 4), pos);
  596. menu.CloseAllMenus ();
  597. menu.Frame = new Rect (0, 0, menu.Frame.Width, menu.Frame.Height);
  598. ((FakeDriver)Application.Driver).SetBufferSize (7, 3);
  599. menu.OpenMenu ();
  600. Application.Refresh ();
  601. expected = @"
  602. ┌──────
  603. │ One
  604. │ Two
  605. ";
  606. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  607. Assert.Equal (new Rect (0, 0, 7, 3), pos);
  608. }
  609. [Fact, AutoInitShutdown]
  610. public void UseSubMenusSingleFrame_False_By_Keyboard ()
  611. {
  612. var menu = new MenuBar (new MenuBarItem [] {
  613. new MenuBarItem ("Numbers", new MenuItem [] {
  614. new MenuItem ("One", "", null),
  615. new MenuBarItem ("Two", new MenuItem [] {
  616. new MenuItem ("Sub-Menu 1", "", null),
  617. new MenuItem ("Sub-Menu 2", "", null)
  618. }),
  619. new MenuItem ("Three", "", null),
  620. })
  621. });
  622. menu.UseKeysUpDownAsKeysLeftRight = true;
  623. Application.Top.Add (menu);
  624. Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
  625. Assert.False (menu.UseSubMenusSingleFrame);
  626. Application.Top.Redraw (Application.Top.Bounds);
  627. var expected = @"
  628. Numbers
  629. ";
  630. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  631. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null)));
  632. Application.Top.Redraw (Application.Top.Bounds);
  633. expected = @"
  634. Numbers
  635. ┌────────┐
  636. │ One │
  637. │ Two ►│
  638. │ Three │
  639. └────────┘
  640. ";
  641. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  642. Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null)));
  643. Application.Top.Redraw (Application.Top.Bounds);
  644. expected = @"
  645. Numbers
  646. ┌────────┐
  647. │ One │
  648. │ Two ►│┌─────────────┐
  649. │ Three ││ Sub-Menu 1 │
  650. └────────┘│ Sub-Menu 2 │
  651. └─────────────┘
  652. ";
  653. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  654. Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.CursorLeft, null)));
  655. Application.Top.Redraw (Application.Top.Bounds);
  656. expected = @"
  657. Numbers
  658. ┌────────┐
  659. │ One │
  660. │ Two ►│
  661. │ Three │
  662. └────────┘
  663. ";
  664. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  665. Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null)));
  666. Application.Top.Redraw (Application.Top.Bounds);
  667. expected = @"
  668. Numbers
  669. ";
  670. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  671. }
  672. [Fact, AutoInitShutdown]
  673. public void UseSubMenusSingleFrame_False_By_Mouse ()
  674. {
  675. var menu = new MenuBar (new MenuBarItem [] {
  676. new MenuBarItem ("Numbers", new MenuItem [] {
  677. new MenuItem ("One", "", null),
  678. new MenuBarItem ("Two", new MenuItem [] {
  679. new MenuItem ("Sub-Menu 1", "", null),
  680. new MenuItem ("Sub-Menu 2", "", null)
  681. }),
  682. new MenuItem ("Three", "", null),
  683. })
  684. });
  685. Application.Top.Add (menu);
  686. Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
  687. Assert.False (menu.UseSubMenusSingleFrame);
  688. Application.Top.Redraw (Application.Top.Bounds);
  689. var expected = @"
  690. Numbers
  691. ";
  692. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  693. Assert.Equal (new Rect (1, 0, 8, 1), pos);
  694. Assert.True (menu.MouseEvent (new MouseEvent () {
  695. X = 1,
  696. Y = 0,
  697. Flags = MouseFlags.Button1Pressed,
  698. View = menu
  699. }));
  700. Application.Top.Redraw (Application.Top.Bounds);
  701. expected = @"
  702. Numbers
  703. ┌────────┐
  704. │ One │
  705. │ Two ►│
  706. │ Three │
  707. └────────┘
  708. ";
  709. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  710. Assert.Equal (new Rect (1, 0, 10, 6), pos);
  711. Assert.False (menu.MouseEvent (new MouseEvent () {
  712. X = 1,
  713. Y = 3,
  714. Flags = MouseFlags.ReportMousePosition,
  715. View = Application.Top.Subviews [1]
  716. }));
  717. Application.Top.Redraw (Application.Top.Bounds);
  718. expected = @"
  719. Numbers
  720. ┌────────┐
  721. │ One │
  722. │ Two ►│┌─────────────┐
  723. │ Three ││ Sub-Menu 1 │
  724. └────────┘│ Sub-Menu 2 │
  725. └─────────────┘
  726. ";
  727. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  728. Assert.Equal (new Rect (1, 0, 25, 7), pos);
  729. Assert.False (menu.MouseEvent (new MouseEvent () {
  730. X = 1,
  731. Y = 2,
  732. Flags = MouseFlags.ReportMousePosition,
  733. View = Application.Top.Subviews [1]
  734. }));
  735. Application.Top.Redraw (Application.Top.Bounds);
  736. expected = @"
  737. Numbers
  738. ┌────────┐
  739. │ One │
  740. │ Two ►│
  741. │ Three │
  742. └────────┘
  743. ";
  744. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  745. Assert.Equal (new Rect (1, 0, 10, 6), pos);
  746. Assert.False (menu.MouseEvent (new MouseEvent () {
  747. X = 70,
  748. Y = 2,
  749. Flags = MouseFlags.Button1Clicked,
  750. View = Application.Top
  751. }));
  752. Application.Top.Redraw (Application.Top.Bounds);
  753. expected = @"
  754. Numbers
  755. ";
  756. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  757. Assert.Equal (new Rect (1, 0, 8, 1), pos);
  758. }
  759. [Fact, AutoInitShutdown]
  760. public void UseSubMenusSingleFrame_True_By_Keyboard ()
  761. {
  762. var menu = new MenuBar (new MenuBarItem [] {
  763. new MenuBarItem ("Numbers", new MenuItem [] {
  764. new MenuItem ("One", "", null),
  765. new MenuBarItem ("Two", new MenuItem [] {
  766. new MenuItem ("Sub-Menu 1", "", null),
  767. new MenuItem ("Sub-Menu 2", "", null)
  768. }),
  769. new MenuItem ("Three", "", null),
  770. })
  771. });
  772. Application.Top.Add (menu);
  773. Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
  774. Assert.False (menu.UseSubMenusSingleFrame);
  775. menu.UseSubMenusSingleFrame = true;
  776. Assert.True (menu.UseSubMenusSingleFrame);
  777. Application.Top.Redraw (Application.Top.Bounds);
  778. var expected = @"
  779. Numbers
  780. ";
  781. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  782. Assert.Equal (new Rect (1, 0, 8, 1), pos);
  783. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null)));
  784. Application.Top.Redraw (Application.Top.Bounds);
  785. expected = @"
  786. Numbers
  787. ┌────────┐
  788. │ One │
  789. │ Two ►│
  790. │ Three │
  791. └────────┘
  792. ";
  793. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  794. Assert.Equal (new Rect (1, 0, 10, 6), pos);
  795. Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null)));
  796. Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Enter, null)));
  797. Application.Top.Redraw (Application.Top.Bounds);
  798. expected = @"
  799. Numbers
  800. ┌─────────────┐
  801. │◄ Two │
  802. ├─────────────┤
  803. │ Sub-Menu 1 │
  804. │ Sub-Menu 2 │
  805. └─────────────┘
  806. ";
  807. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  808. Assert.Equal (new Rect (1, 0, 15, 7), pos);
  809. Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.Enter, null)));
  810. Application.Top.Redraw (Application.Top.Bounds);
  811. expected = @"
  812. Numbers
  813. ┌────────┐
  814. │ One │
  815. │ Two ►│
  816. │ Three │
  817. └────────┘
  818. ";
  819. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  820. Assert.Equal (new Rect (1, 0, 10, 6), pos);
  821. Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null)));
  822. Application.Top.Redraw (Application.Top.Bounds);
  823. expected = @"
  824. Numbers
  825. ";
  826. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  827. Assert.Equal (new Rect (1, 0, 8, 1), pos);
  828. }
  829. [Fact, AutoInitShutdown]
  830. public void UseSubMenusSingleFrame_True_By_Mouse ()
  831. {
  832. var menu = new MenuBar (new MenuBarItem [] {
  833. new MenuBarItem ("Numbers", new MenuItem [] {
  834. new MenuItem ("One", "", null),
  835. new MenuBarItem ("Two", new MenuItem [] {
  836. new MenuItem ("Sub-Menu 1", "", null),
  837. new MenuItem ("Sub-Menu 2", "", null)
  838. }),
  839. new MenuItem ("Three", "", null),
  840. })
  841. });
  842. Application.Top.Add (menu);
  843. Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
  844. Assert.False (menu.UseSubMenusSingleFrame);
  845. menu.UseSubMenusSingleFrame = true;
  846. Assert.True (menu.UseSubMenusSingleFrame);
  847. Application.Top.Redraw (Application.Top.Bounds);
  848. var expected = @"
  849. Numbers
  850. ";
  851. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  852. Assert.Equal (new Rect (1, 0, 8, 1), pos);
  853. Assert.True (menu.MouseEvent (new MouseEvent () {
  854. X = 1,
  855. Y = 0,
  856. Flags = MouseFlags.Button1Pressed,
  857. View = menu
  858. }));
  859. Application.Top.Redraw (Application.Top.Bounds);
  860. expected = @"
  861. Numbers
  862. ┌────────┐
  863. │ One │
  864. │ Two ►│
  865. │ Three │
  866. └────────┘
  867. ";
  868. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  869. Assert.Equal (new Rect (1, 0, 10, 6), pos);
  870. Assert.False (menu.MouseEvent (new MouseEvent () {
  871. X = 1,
  872. Y = 3,
  873. Flags = MouseFlags.Button1Clicked,
  874. View = Application.Top.Subviews [1]
  875. }));
  876. Application.Top.Redraw (Application.Top.Bounds);
  877. expected = @"
  878. Numbers
  879. ┌─────────────┐
  880. │◄ Two │
  881. ├─────────────┤
  882. │ Sub-Menu 1 │
  883. │ Sub-Menu 2 │
  884. └─────────────┘
  885. ";
  886. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  887. Assert.Equal (new Rect (1, 0, 15, 7), pos);
  888. Assert.False (menu.MouseEvent (new MouseEvent () {
  889. X = 1,
  890. Y = 2,
  891. Flags = MouseFlags.Button1Clicked,
  892. View = Application.Top.Subviews [2]
  893. }));
  894. Application.Top.Redraw (Application.Top.Bounds);
  895. expected = @"
  896. Numbers
  897. ┌────────┐
  898. │ One │
  899. │ Two ►│
  900. │ Three │
  901. └────────┘
  902. ";
  903. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  904. Assert.Equal (new Rect (1, 0, 10, 6), pos);
  905. Assert.False (menu.MouseEvent (new MouseEvent () {
  906. X = 70,
  907. Y = 2,
  908. Flags = MouseFlags.Button1Clicked,
  909. View = Application.Top
  910. }));
  911. Application.Top.Redraw (Application.Top.Bounds);
  912. expected = @"
  913. Numbers
  914. ";
  915. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  916. Assert.Equal (new Rect (1, 0, 8, 1), pos);
  917. }
  918. [Fact, AutoInitShutdown]
  919. public void HotKey_MenuBar_OnKeyDown_OnKeyUp_ProcessHotKey_ProcessKey ()
  920. {
  921. var newAction = false;
  922. var copyAction = false;
  923. var menu = new MenuBar (new MenuBarItem [] {
  924. new MenuBarItem ("_File", new MenuItem [] {
  925. new MenuItem ("_New", "", () => newAction = true)
  926. }),
  927. new MenuBarItem ("_Edit", new MenuItem [] {
  928. new MenuItem ("_Copy", "", () => copyAction = true)
  929. })
  930. });
  931. Application.Top.Add (menu);
  932. Assert.False (newAction);
  933. Assert.False (copyAction);
  934. Assert.False (menu.OnKeyDown (new (Key.AltMask, new KeyModifiers () { Alt = true })));
  935. Assert.True (menu.OnKeyUp (new (Key.AltMask, new KeyModifiers () { Alt = true })));
  936. Assert.True (menu.IsMenuOpen);
  937. Application.Top.Redraw (Application.Top.Bounds);
  938. var expected = @"
  939. File Edit
  940. ";
  941. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  942. Assert.Equal (new Rect (1, 0, 11, 1), pos);
  943. Assert.True (menu.ProcessKey (new (Key.N, null)));
  944. Application.MainLoop.MainIteration ();
  945. Assert.True (newAction);
  946. Assert.True (menu.ProcessHotKey (new (Key.AltMask, new KeyModifiers () { Alt = true })));
  947. Assert.True (menu.IsMenuOpen);
  948. Application.Top.Redraw (Application.Top.Bounds);
  949. expected = @"
  950. File Edit
  951. ";
  952. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  953. Assert.Equal (new Rect (1, 0, 11, 1), pos);
  954. Assert.True (menu.ProcessKey (new (Key.CursorRight, null)));
  955. Assert.True (menu.ProcessKey (new (Key.C, null)));
  956. Application.MainLoop.MainIteration ();
  957. Assert.True (copyAction);
  958. }
  959. // Defines the expected strings for a Menu. Currently supports
  960. // - MenuBar with any number of MenuItems
  961. // - Each top-level MenuItem can have a SINGLE sub-menu
  962. //
  963. // TODO: Enable multiple sub-menus
  964. // TODO: Enable checked sub-menus
  965. // TODO: Enable sub-menus with sub-menus (perhaps better to put this in a separate class with focused unit tests?)
  966. //
  967. // E.g:
  968. //
  969. // File Edit
  970. // New Copy
  971. public class ExpectedMenuBar : MenuBar {
  972. FakeDriver d = (FakeDriver)Application.Driver;
  973. // Each MenuBar title has a 1 space pad on each side
  974. // See `static int leftPadding` and `static int rightPadding` on line 1037 of Menu.cs
  975. public string MenuBarText {
  976. get {
  977. string txt = string.Empty;
  978. foreach (var m in Menus)
  979. txt += " " + m.Title.ToString () + " ";
  980. return txt;
  981. }
  982. }
  983. // The expected strings when the menu is closed
  984. public string ClosedMenuText => MenuBarText + "\n";
  985. // Padding for the X of the sub menu Frane
  986. // Menu.cs - Line 1239 in `internal void OpenMenu` is where the Menu is created
  987. string padding (int i)
  988. {
  989. int n = 0;
  990. while (i > 0) {
  991. n += Menus [i - 1].TitleLength + 2;
  992. i--;
  993. }
  994. return new string (' ', n);
  995. }
  996. // Define expected menu frame
  997. // "┌──────┐"
  998. // "│ New │"
  999. // "└──────┘"
  1000. //
  1001. // The width of the Frame is determined in Menu.cs line 144, where `Width` is calculated
  1002. // 1 space before the Title and 2 spaces after the Title/Check/Help
  1003. public string expectedTopRow (int i) => $"{d.ULCorner}{new string (d.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3)}{d.URCorner} \n";
  1004. // The 3 spaces at end are a result of Menu.cs line 1062 where `pos` is calculated (` + spacesAfterTitle`)
  1005. public string expectedMenuItemRow (int i) => $"{d.VLine} {Menus [i].Children [0].Title} {d.VLine} \n";
  1006. public string expectedBottomRow (int i) => $"{d.LLCorner}{new string (d.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3)}{d.LRCorner} \n";
  1007. // The fulll expected string for an open sub menu
  1008. public string expectedSubMenuOpen (int i) => ClosedMenuText +
  1009. (Menus [i].Children.Length > 0 ?
  1010. padding (i) + expectedTopRow (i) +
  1011. padding (i) + expectedMenuItemRow (i) +
  1012. padding (i) + expectedBottomRow (i)
  1013. :
  1014. "");
  1015. public ExpectedMenuBar (MenuBarItem [] menus) : base (menus)
  1016. {
  1017. }
  1018. }
  1019. [Fact, AutoInitShutdown]
  1020. public void MenuBar_Submenus_Alignment_Correct ()
  1021. {
  1022. // Define the expected menu
  1023. var expectedMenu = new ExpectedMenuBar (new MenuBarItem [] {
  1024. new MenuBarItem ("File", new MenuItem [] {
  1025. new MenuItem ("Really Long Sub Menu", "", null)
  1026. }),
  1027. new MenuBarItem ("123", new MenuItem [] {
  1028. new MenuItem ("Copy", "", null)
  1029. }),
  1030. new MenuBarItem ("Format", new MenuItem [] {
  1031. new MenuItem ("Word Wrap", "", null)
  1032. }),
  1033. new MenuBarItem ("Help", new MenuItem [] {
  1034. new MenuItem ("About", "", null)
  1035. }),
  1036. new MenuBarItem ("1", new MenuItem [] {
  1037. new MenuItem ("2", "", null)
  1038. }),
  1039. new MenuBarItem ("3", new MenuItem [] {
  1040. new MenuItem ("2", "", null)
  1041. }),
  1042. new MenuBarItem ("Last one", new MenuItem [] {
  1043. new MenuItem ("Test", "", null)
  1044. })
  1045. });
  1046. var items = new MenuBarItem [expectedMenu.Menus.Length];
  1047. for (var i = 0; i < expectedMenu.Menus.Length; i++) items [i] = new MenuBarItem (expectedMenu.Menus [i].Title, new MenuItem [] {
  1048. new MenuItem (expectedMenu.Menus [i].Children [0].Title, "", null)
  1049. });
  1050. var menu = new MenuBar (items);
  1051. Application.Top.Add (menu);
  1052. Application.Top.Redraw (Application.Top.Bounds);
  1053. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1054. for (var i = 0; i < expectedMenu.Menus.Length; i++) {
  1055. menu.OpenMenu (i);
  1056. Assert.True (menu.IsMenuOpen);
  1057. Application.Top.Redraw (Application.Top.Bounds);
  1058. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (i), output);
  1059. }
  1060. }
  1061. [Fact, AutoInitShutdown]
  1062. public void HotKey_MenuBar_ProcessHotKey_Menu_ProcessKey ()
  1063. {
  1064. var newAction = false;
  1065. var copyAction = false;
  1066. // Define the expected menu
  1067. var expectedMenu = new ExpectedMenuBar (new MenuBarItem [] {
  1068. new MenuBarItem ("File", new MenuItem [] {
  1069. new MenuItem ("New", "", null)
  1070. }),
  1071. new MenuBarItem ("Edit", new MenuItem [] {
  1072. new MenuItem ("Copy", "", null)
  1073. })
  1074. });
  1075. // The real menu
  1076. var menu = new MenuBar (new MenuBarItem [] {
  1077. new MenuBarItem ("_" + expectedMenu.Menus[0].Title, new MenuItem [] {
  1078. new MenuItem ("_" + expectedMenu.Menus[0].Children[0].Title, "", () => newAction = true)
  1079. }),
  1080. new MenuBarItem ("_" + expectedMenu.Menus[1].Title, new MenuItem [] {
  1081. new MenuItem ("_" + expectedMenu.Menus[1].Children[0].Title, "", () => copyAction = true)
  1082. }),
  1083. });
  1084. Application.Top.Add (menu);
  1085. Assert.False (newAction);
  1086. Assert.False (copyAction);
  1087. Assert.True (menu.ProcessHotKey (new (Key.AltMask | Key.F, new KeyModifiers () { Alt = true })));
  1088. Assert.True (menu.IsMenuOpen);
  1089. Application.Top.Redraw (Application.Top.Bounds);
  1090. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1091. Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.N, null)));
  1092. Application.MainLoop.MainIteration ();
  1093. Assert.True (newAction);
  1094. Assert.True (menu.ProcessHotKey (new (Key.AltMask | Key.E, new KeyModifiers () { Alt = true })));
  1095. Assert.True (menu.IsMenuOpen);
  1096. Application.Top.Redraw (Application.Top.Bounds);
  1097. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (1), output);
  1098. Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.C, null)));
  1099. Application.MainLoop.MainIteration ();
  1100. Assert.True (copyAction);
  1101. }
  1102. [Fact, AutoInitShutdown]
  1103. public void MenuBar_Position_And_Size_With_HotKeys_Is_The_Same_As_Without_HotKeys ()
  1104. {
  1105. // Define the expected menu
  1106. var expectedMenu = new ExpectedMenuBar (new MenuBarItem [] {
  1107. new MenuBarItem ("File", new MenuItem [] {
  1108. new MenuItem ("12", "", null)
  1109. }),
  1110. new MenuBarItem ("Edit", new MenuItem [] {
  1111. new MenuItem ("Copy", "", null)
  1112. })
  1113. });
  1114. // Test without HotKeys first
  1115. var menu = new MenuBar (new MenuBarItem [] {
  1116. new MenuBarItem (expectedMenu.Menus[0].Title, new MenuItem [] {
  1117. new MenuItem (expectedMenu.Menus[0].Children[0].Title, "", null)
  1118. }),
  1119. new MenuBarItem (expectedMenu.Menus[1].Title, new MenuItem [] {
  1120. new MenuItem (expectedMenu.Menus[1].Children[0].Title, "", null)
  1121. })
  1122. });
  1123. Application.Top.Add (menu);
  1124. // Open first
  1125. Assert.True (menu.ProcessHotKey (new (Key.F9, new KeyModifiers ())));
  1126. Assert.True (menu.IsMenuOpen);
  1127. Application.Top.Redraw (Application.Top.Bounds);
  1128. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1129. // Open second
  1130. Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.CursorRight, null)));
  1131. Assert.True (menu.IsMenuOpen);
  1132. Application.Top.Redraw (Application.Top.Bounds);
  1133. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (1), output);
  1134. // Close menu
  1135. Assert.True (menu.ProcessHotKey (new (Key.F9, new KeyModifiers ())));
  1136. Assert.False (menu.IsMenuOpen);
  1137. Application.Top.Redraw (Application.Top.Bounds);
  1138. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1139. Application.Top.Remove (menu);
  1140. // Now test WITH HotKeys
  1141. menu = new MenuBar (new MenuBarItem [] {
  1142. new MenuBarItem ("_" + expectedMenu.Menus[0].Title, new MenuItem [] {
  1143. new MenuItem ("_" + expectedMenu.Menus[0].Children[0].Title, "", null)
  1144. }),
  1145. new MenuBarItem ("_" + expectedMenu.Menus[1].Title, new MenuItem [] {
  1146. new MenuItem ("_" + expectedMenu.Menus[1].Children[0].Title, "", null)
  1147. }),
  1148. });
  1149. Application.Top.Add (menu);
  1150. // Open first
  1151. Assert.True (menu.ProcessHotKey (new (Key.F9, new KeyModifiers ())));
  1152. Assert.True (menu.IsMenuOpen);
  1153. Application.Top.Redraw (Application.Top.Bounds);
  1154. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1155. // Open second
  1156. Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.CursorRight, null)));
  1157. Assert.True (menu.IsMenuOpen);
  1158. Application.Top.Redraw (Application.Top.Bounds);
  1159. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (1), output);
  1160. // Close menu
  1161. Assert.True (menu.ProcessHotKey (new (Key.F9, new KeyModifiers ())));
  1162. Assert.False (menu.IsMenuOpen);
  1163. Application.Top.Redraw (Application.Top.Bounds);
  1164. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1165. }
  1166. [Fact, AutoInitShutdown]
  1167. public void MenuBar_ButtonPressed_Open_The_Menu_ButtonPressed_Again_Close_The_Menu ()
  1168. {
  1169. // Define the expected menu
  1170. var expectedMenu = new ExpectedMenuBar (new MenuBarItem [] {
  1171. new MenuBarItem ("File", new MenuItem [] {
  1172. new MenuItem ("Open", "", null)
  1173. }),
  1174. new MenuBarItem ("Edit", new MenuItem [] {
  1175. new MenuItem ("Copy", "", null)
  1176. })
  1177. });
  1178. // Test without HotKeys first
  1179. var menu = new MenuBar (new MenuBarItem [] {
  1180. new MenuBarItem ("_" + expectedMenu.Menus[0].Title, new MenuItem [] {
  1181. new MenuItem ("_" + expectedMenu.Menus[0].Children[0].Title, "", null)
  1182. }),
  1183. new MenuBarItem ("_" + expectedMenu.Menus[1].Title, new MenuItem [] {
  1184. new MenuItem ("_" + expectedMenu.Menus[1].Children[0].Title, "", null)
  1185. }),
  1186. });
  1187. Application.Top.Add (menu);
  1188. Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
  1189. Assert.True (menu.IsMenuOpen);
  1190. Application.Top.Redraw (Application.Top.Bounds);
  1191. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1192. Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
  1193. Assert.False (menu.IsMenuOpen);
  1194. Application.Top.Redraw (Application.Top.Bounds);
  1195. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1196. }
  1197. [Fact]
  1198. public void UseKeysUpDownAsKeysLeftRight_And_UseSubMenusSingleFrame_Cannot_Be_Both_True ()
  1199. {
  1200. var menu = new MenuBar ();
  1201. Assert.False (menu.UseKeysUpDownAsKeysLeftRight);
  1202. Assert.False (menu.UseSubMenusSingleFrame);
  1203. menu.UseKeysUpDownAsKeysLeftRight = true;
  1204. Assert.True (menu.UseKeysUpDownAsKeysLeftRight);
  1205. Assert.False (menu.UseSubMenusSingleFrame);
  1206. menu.UseSubMenusSingleFrame = true;
  1207. Assert.False (menu.UseKeysUpDownAsKeysLeftRight);
  1208. Assert.True (menu.UseSubMenusSingleFrame);
  1209. }
  1210. [Fact, AutoInitShutdown]
  1211. public void Parent_MenuItem_Stay_Focused_If_Child_MenuItem_Is_Empty_By_Mouse ()
  1212. {
  1213. // File Edit Format
  1214. //┌──────┐ ┌───────┐
  1215. //│ New │ │ Wrap │
  1216. //└──────┘ └───────┘
  1217. // Define the expected menu
  1218. var expectedMenu = new ExpectedMenuBar (new MenuBarItem [] {
  1219. new MenuBarItem ("File", new MenuItem [] {
  1220. new MenuItem ("New", "", null)
  1221. }),
  1222. new MenuBarItem ("Edit", new MenuItem [] {}),
  1223. new MenuBarItem ("Format", new MenuItem [] {
  1224. new MenuItem ("Wrap", "", null)
  1225. })
  1226. });
  1227. var menu = new MenuBar (new MenuBarItem [] {
  1228. new MenuBarItem (expectedMenu.Menus[0].Title, new MenuItem [] {
  1229. new MenuItem (expectedMenu.Menus[0].Children[0].Title, "", null)
  1230. }),
  1231. new MenuBarItem (expectedMenu.Menus[1].Title, new MenuItem [] {}),
  1232. new MenuBarItem (expectedMenu.Menus[2].Title, new MenuItem [] {
  1233. new MenuItem (expectedMenu.Menus[2].Children[0].Title, "", null)
  1234. })
  1235. });
  1236. var tf = new TextField () { Y = 2, Width = 10 };
  1237. Application.Top.Add (menu, tf);
  1238. Application.Begin (Application.Top);
  1239. Assert.True (tf.HasFocus);
  1240. Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
  1241. Assert.True (menu.IsMenuOpen);
  1242. Assert.False (tf.HasFocus);
  1243. Application.Top.Redraw (Application.Top.Bounds);
  1244. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1245. Assert.True (menu.MouseEvent (new MouseEvent () { X = 8, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }));
  1246. Assert.True (menu.IsMenuOpen);
  1247. Assert.False (tf.HasFocus);
  1248. Application.Top.Redraw (Application.Top.Bounds);
  1249. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (1), output);
  1250. Assert.True (menu.MouseEvent (new MouseEvent () { X = 15, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }));
  1251. Assert.True (menu.IsMenuOpen);
  1252. Assert.False (tf.HasFocus);
  1253. Application.Top.Redraw (Application.Top.Bounds);
  1254. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (2), output);
  1255. Assert.True (menu.MouseEvent (new MouseEvent () { X = 8, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }));
  1256. Assert.True (menu.IsMenuOpen);
  1257. Assert.False (tf.HasFocus);
  1258. Application.Top.Redraw (Application.Top.Bounds);
  1259. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1260. Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }));
  1261. Assert.True (menu.IsMenuOpen);
  1262. Assert.False (tf.HasFocus);
  1263. Application.Top.Redraw (Application.Top.Bounds);
  1264. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1265. Assert.True (menu.MouseEvent (new MouseEvent () { X = 8, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
  1266. Assert.False (menu.IsMenuOpen);
  1267. Assert.True (tf.HasFocus);
  1268. Application.Top.Redraw (Application.Top.Bounds);
  1269. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1270. }
  1271. [Fact, AutoInitShutdown]
  1272. public void Parent_MenuItem_Stay_Focused_If_Child_MenuItem_Is_Empty_By_Keyboard ()
  1273. {
  1274. var expectedMenu = new ExpectedMenuBar (new MenuBarItem [] {
  1275. new MenuBarItem ("File", new MenuItem [] {
  1276. new MenuItem ("New", "", null)
  1277. }),
  1278. new MenuBarItem ("Edit", Array.Empty<MenuItem> ()),
  1279. new MenuBarItem ("Format", new MenuItem [] {
  1280. new MenuItem ("Wrap", "", null)
  1281. })
  1282. });
  1283. var items = new MenuBarItem [expectedMenu.Menus.Length];
  1284. for (var i = 0; i < expectedMenu.Menus.Length; i++) items [i] = new MenuBarItem (expectedMenu.Menus [i].Title, expectedMenu.Menus [i].Children.Length > 0
  1285. ? new MenuItem [] {
  1286. new MenuItem (expectedMenu.Menus [i].Children [0].Title, "", null),
  1287. }
  1288. : Array.Empty<MenuItem> ());
  1289. var menu = new MenuBar (items);
  1290. var tf = new TextField () { Y = 2, Width = 10 };
  1291. Application.Top.Add (menu, tf);
  1292. Application.Begin (Application.Top);
  1293. Assert.True (tf.HasFocus);
  1294. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1295. Assert.True (menu.IsMenuOpen);
  1296. Assert.False (tf.HasFocus);
  1297. Application.Top.Redraw (Application.Top.Bounds);
  1298. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1299. // Right - Edit has no sub menu; this tests that no sub menu shows
  1300. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1301. Assert.True (menu.IsMenuOpen);
  1302. Assert.False (tf.HasFocus);
  1303. Application.Top.Redraw (Application.Top.Bounds);
  1304. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (1), output);
  1305. // Right - Format
  1306. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1307. Assert.True (menu.IsMenuOpen);
  1308. Assert.False (tf.HasFocus);
  1309. Application.Top.Redraw (Application.Top.Bounds);
  1310. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (2), output);
  1311. // Left - Edit
  1312. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
  1313. Assert.True (menu.IsMenuOpen);
  1314. Assert.False (tf.HasFocus);
  1315. Application.Top.Redraw (Application.Top.Bounds);
  1316. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (1), output);
  1317. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
  1318. Assert.True (menu.IsMenuOpen);
  1319. Assert.False (tf.HasFocus);
  1320. Application.Top.Redraw (Application.Top.Bounds);
  1321. TestHelpers.AssertDriverContentsAre (expectedMenu.expectedSubMenuOpen (0), output);
  1322. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1323. Assert.False (menu.IsMenuOpen);
  1324. Assert.True (tf.HasFocus);
  1325. Application.Top.Redraw (Application.Top.Bounds);
  1326. TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output);
  1327. }
  1328. [Fact, AutoInitShutdown]
  1329. public void Key_Open_And_Close_The_MenuBar ()
  1330. {
  1331. var menu = new MenuBar (new MenuBarItem [] {
  1332. new MenuBarItem ("File", new MenuItem [] {
  1333. new MenuItem ("New", "", null)
  1334. })
  1335. });
  1336. Application.Top.Add (menu);
  1337. Application.Begin (Application.Top);
  1338. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1339. Assert.True (menu.IsMenuOpen);
  1340. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1341. Assert.False (menu.IsMenuOpen);
  1342. menu.Key = Key.F10 | Key.ShiftMask;
  1343. Assert.False (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1344. Assert.False (menu.IsMenuOpen);
  1345. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F10 | Key.ShiftMask, new KeyModifiers ())));
  1346. Assert.True (menu.IsMenuOpen);
  1347. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F10 | Key.ShiftMask, new KeyModifiers ())));
  1348. Assert.False (menu.IsMenuOpen);
  1349. }
  1350. [Fact, AutoInitShutdown]
  1351. public void Disabled_MenuItem_Is_Never_Selected ()
  1352. {
  1353. var menu = new MenuBar (new MenuBarItem [] {
  1354. new MenuBarItem ("Menu", new MenuItem [] {
  1355. new MenuItem ("Enabled 1", "", null),
  1356. new MenuItem ("Disabled", "", null, () => false),
  1357. null,
  1358. new MenuItem ("Enabled 2", "", null)
  1359. })
  1360. });
  1361. var top = Application.Top;
  1362. top.Add (menu);
  1363. Application.Begin (top);
  1364. var attributes = new Attribute [] {
  1365. // 0
  1366. menu.ColorScheme.Normal,
  1367. // 1
  1368. menu.ColorScheme.Focus,
  1369. // 2
  1370. menu.ColorScheme.Disabled
  1371. };
  1372. TestHelpers.AssertDriverColorsAre (@"
  1373. 00000000000000", attributes);
  1374. Assert.True (menu.MouseEvent (new MouseEvent {
  1375. X = 0,
  1376. Y = 0,
  1377. Flags = MouseFlags.Button1Pressed,
  1378. View = menu
  1379. }));
  1380. top.Redraw (top.Bounds);
  1381. TestHelpers.AssertDriverColorsAre (@"
  1382. 11111100000000
  1383. 00000000000000
  1384. 01111111111110
  1385. 02222222222220
  1386. 00000000000000
  1387. 00000000000000
  1388. 00000000000000", attributes);
  1389. Assert.True (top.Subviews [1].MouseEvent (new MouseEvent {
  1390. X = 0,
  1391. Y = 2,
  1392. Flags = MouseFlags.Button1Clicked,
  1393. View = top.Subviews [1]
  1394. }));
  1395. top.Subviews [1].Redraw (top.Bounds);
  1396. TestHelpers.AssertDriverColorsAre (@"
  1397. 11111100000000
  1398. 00000000000000
  1399. 01111111111110
  1400. 02222222222220
  1401. 00000000000000
  1402. 00000000000000
  1403. 00000000000000", attributes);
  1404. Assert.True (top.Subviews [1].MouseEvent (new MouseEvent {
  1405. X = 0,
  1406. Y = 2,
  1407. Flags = MouseFlags.ReportMousePosition,
  1408. View = top.Subviews [1]
  1409. }));
  1410. top.Subviews [1].Redraw (top.Bounds);
  1411. TestHelpers.AssertDriverColorsAre (@"
  1412. 11111100000000
  1413. 00000000000000
  1414. 01111111111110
  1415. 02222222222220
  1416. 00000000000000
  1417. 00000000000000
  1418. 00000000000000", attributes);
  1419. }
  1420. [Fact, AutoInitShutdown]
  1421. public void MenuBar_With_Action_But_Without_MenuItems_Not_Throw ()
  1422. {
  1423. var menu = new MenuBar (
  1424. menus: new []
  1425. {
  1426. new MenuBarItem { Title = "Test 1", Action = () => { } },
  1427. new MenuBarItem { Title = "Test 2", Action = () => { } },
  1428. });
  1429. Application.Top.Add (menu);
  1430. Application.Begin (Application.Top);
  1431. Assert.False (Application.Top.OnKeyDown (new KeyEvent (Key.AltMask, new KeyModifiers { Alt = true })));
  1432. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1433. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1434. }
  1435. [Fact, AutoInitShutdown]
  1436. public void MenuBar_In_Window_Without_Other_Views ()
  1437. {
  1438. var win = new Window ();
  1439. var menu = new MenuBar (new MenuBarItem [] {
  1440. new MenuBarItem ("File", new MenuItem [] {
  1441. new MenuItem ("New", "", null)
  1442. }),
  1443. new MenuBarItem ("Edit", new MenuItem [] {
  1444. new MenuBarItem ("Delete", new MenuItem [] {
  1445. new MenuItem ("All", "", null),
  1446. new MenuItem ("Selected", "", null)
  1447. })
  1448. })
  1449. }); ;
  1450. win.Add (menu);
  1451. var top = Application.Top;
  1452. top.Add (win);
  1453. Application.Begin (top);
  1454. ((FakeDriver)Application.Driver).SetBufferSize (40, 8);
  1455. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1456. ┌──────────────────────────────────────┐
  1457. │ File Edit │
  1458. │ │
  1459. │ │
  1460. │ │
  1461. │ │
  1462. │ │
  1463. └──────────────────────────────────────┘", output);
  1464. Assert.True (win.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1465. top.Redraw (top.Bounds);
  1466. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1467. ┌──────────────────────────────────────┐
  1468. │ File Edit │
  1469. │┌──────┐ │
  1470. ││ New │ │
  1471. │└──────┘ │
  1472. │ │
  1473. │ │
  1474. └──────────────────────────────────────┘", output);
  1475. Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1476. top.Redraw (top.Bounds);
  1477. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1478. ┌──────────────────────────────────────┐
  1479. │ File Edit │
  1480. │ ┌─────────┐ │
  1481. │ │ Delete ►│ │
  1482. │ └─────────┘ │
  1483. │ │
  1484. │ │
  1485. └──────────────────────────────────────┘", output);
  1486. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1487. top.Redraw (top.Bounds);
  1488. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1489. ┌──────────────────────────────────────┐
  1490. │ File Edit │
  1491. │ ┌─────────┐ │
  1492. │ │ Delete ►│┌───────────┐ │
  1493. │ └─────────┘│ All │ │
  1494. │ │ Selected │ │
  1495. │ └───────────┘ │
  1496. └──────────────────────────────────────┘", output);
  1497. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
  1498. top.Redraw (top.Bounds);
  1499. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1500. ┌──────────────────────────────────────┐
  1501. │ File Edit │
  1502. │┌──────┐ │
  1503. ││ New │ │
  1504. │└──────┘ │
  1505. │ │
  1506. │ │
  1507. └──────────────────────────────────────┘", output);
  1508. }
  1509. [Fact, AutoInitShutdown]
  1510. public void AllowNullChecked_Get_Set ()
  1511. {
  1512. var mi = new MenuItem ("Check this out 你", "", null) {
  1513. CheckType = MenuItemCheckStyle.Checked
  1514. };
  1515. mi.Action = mi.ToggleChecked;
  1516. var menu = new MenuBar (new MenuBarItem [] {
  1517. new MenuBarItem("Nullable Checked",new MenuItem [] {
  1518. mi
  1519. })
  1520. });
  1521. new CheckBox ();
  1522. var top = Application.Top;
  1523. top.Add (menu);
  1524. Application.Begin (top);
  1525. Assert.False (mi.Checked);
  1526. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1527. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  1528. Application.MainLoop.MainIteration ();
  1529. Assert.True (mi.Checked);
  1530. Assert.True (menu.MouseEvent (new MouseEvent () {
  1531. X = 0,
  1532. Y = 0,
  1533. Flags = MouseFlags.Button1Pressed,
  1534. View = menu
  1535. }));
  1536. Assert.True (menu.openMenu.MouseEvent (new MouseEvent () {
  1537. X = 0,
  1538. Y = 1,
  1539. Flags = MouseFlags.Button1Clicked,
  1540. View = menu.openMenu
  1541. }));
  1542. Application.MainLoop.MainIteration ();
  1543. Assert.False (mi.Checked);
  1544. mi.AllowNullChecked = true;
  1545. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1546. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  1547. Application.MainLoop.MainIteration ();
  1548. Assert.Null (mi.Checked);
  1549. Assert.True (menu.MouseEvent (new MouseEvent () {
  1550. X = 0,
  1551. Y = 0,
  1552. Flags = MouseFlags.Button1Pressed,
  1553. View = menu
  1554. }));
  1555. Application.Refresh ();
  1556. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1557. Nullable Checked
  1558. ┌──────────────────────┐
  1559. │ ⍰ Check this out 你 │
  1560. └──────────────────────┘", output);
  1561. Assert.True (menu.openMenu.MouseEvent (new MouseEvent () {
  1562. X = 0,
  1563. Y = 1,
  1564. Flags = MouseFlags.Button1Clicked,
  1565. View = menu.openMenu
  1566. }));
  1567. Application.MainLoop.MainIteration ();
  1568. Assert.True (mi.Checked);
  1569. Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
  1570. Assert.True (menu.openMenu.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ())));
  1571. Application.MainLoop.MainIteration ();
  1572. Assert.False (mi.Checked);
  1573. Assert.True (menu.MouseEvent (new MouseEvent () {
  1574. X = 0,
  1575. Y = 0,
  1576. Flags = MouseFlags.Button1Pressed,
  1577. View = menu
  1578. }));
  1579. Assert.True (menu.openMenu.MouseEvent (new MouseEvent () {
  1580. X = 0,
  1581. Y = 1,
  1582. Flags = MouseFlags.Button1Clicked,
  1583. View = menu.openMenu
  1584. }));
  1585. Application.MainLoop.MainIteration ();
  1586. Assert.Null (mi.Checked);
  1587. mi.AllowNullChecked = false;
  1588. Assert.False (mi.Checked);
  1589. mi.CheckType = MenuItemCheckStyle.NoCheck;
  1590. Assert.Throws<InvalidOperationException> (mi.ToggleChecked);
  1591. mi.CheckType = MenuItemCheckStyle.Radio;
  1592. Assert.Throws<InvalidOperationException> (mi.ToggleChecked);
  1593. }
  1594. }
  1595. }