MenuTests.cs 64 KB

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