ToplevelTests.cs 91 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071
  1. using Xunit.Abstractions;
  2. namespace Terminal.Gui.ViewsTests;
  3. public class ToplevelTests
  4. {
  5. private readonly ITestOutputHelper _output;
  6. public ToplevelTests (ITestOutputHelper output) { _output = output; }
  7. [Fact]
  8. [AutoInitShutdown]
  9. public void Constructor_Default ()
  10. {
  11. var top = new Toplevel ();
  12. Assert.Equal (Colors.ColorSchemes ["TopLevel"], top.ColorScheme);
  13. Assert.Equal ("Fill(0)", top.Width.ToString ());
  14. Assert.Equal ("Fill(0)", top.Height.ToString ());
  15. Assert.False (top.Running);
  16. Assert.False (top.Modal);
  17. Assert.Null (top.MenuBar);
  18. Assert.Null (top.StatusBar);
  19. Assert.False (top.IsOverlappedContainer);
  20. Assert.False (top.IsOverlapped);
  21. }
  22. #if BROKE_IN_2927
  23. // BUGBUG: The name of this test does not match what it does.
  24. [Fact]
  25. [AutoInitShutdown]
  26. public void Application_Top_GetLocationThatFits_To_Driver_Rows_And_Cols ()
  27. {
  28. var iterations = 0;
  29. Application.Iteration += (s, a) =>
  30. {
  31. switch (iterations)
  32. {
  33. case 0:
  34. Assert.False (Application.Top.AutoSize);
  35. Assert.Equal ("Top1", Application.Top.Text);
  36. Assert.Equal (0, Application.Top.Frame.X);
  37. Assert.Equal (0, Application.Top.Frame.Y);
  38. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  39. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  40. Application.OnKeyPressed (new (Key.CtrlMask | Key.R));
  41. break;
  42. case 1:
  43. Assert.Equal ("Top2", Application.Top.Text);
  44. Assert.Equal (0, Application.Top.Frame.X);
  45. Assert.Equal (0, Application.Top.Frame.Y);
  46. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  47. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  48. Application.OnKeyPressed (new (Key.CtrlMask | Key.C));
  49. break;
  50. case 3:
  51. Assert.Equal ("Top1", Application.Top.Text);
  52. Assert.Equal (0, Application.Top.Frame.X);
  53. Assert.Equal (0, Application.Top.Frame.Y);
  54. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  55. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  56. Application.OnKeyPressed (new (Key.CtrlMask | Key.R));
  57. break;
  58. case 4:
  59. Assert.Equal ("Top2", Application.Top.Text);
  60. Assert.Equal (0, Application.Top.Frame.X);
  61. Assert.Equal (0, Application.Top.Frame.Y);
  62. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  63. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  64. Application.OnKeyPressed (new (Key.CtrlMask | Key.C));
  65. break;
  66. case 6:
  67. Assert.Equal ("Top1", Application.Top.Text);
  68. Assert.Equal (0, Application.Top.Frame.X);
  69. Assert.Equal (0, Application.Top.Frame.Y);
  70. Assert.Equal (Application.Driver.Cols, Application.Top.Frame.Width);
  71. Assert.Equal (Application.Driver.Rows, Application.Top.Frame.Height);
  72. Application.OnKeyPressed (new (Key.CtrlMask | Key.Q));
  73. break;
  74. }
  75. iterations++;
  76. };
  77. Application.Run (Top1 ());
  78. Toplevel Top1 ()
  79. {
  80. var top = Application.Top;
  81. top.Text = "Top1";
  82. var menu = new MenuBar (
  83. new MenuBarItem []
  84. {
  85. new MenuBarItem (
  86. "_Options",
  87. new MenuItem []
  88. {
  89. new MenuItem (
  90. "_Run Top2",
  91. "",
  92. () => Application.Run (Top2 ()),
  93. null,
  94. null,
  95. Key.CtrlMask | Key.R
  96. ),
  97. new MenuItem (
  98. "_Quit",
  99. "",
  100. () => Application
  101. .RequestStop (),
  102. null,
  103. null,
  104. Key.CtrlMask | Key.Q
  105. )
  106. }
  107. )
  108. }
  109. );
  110. top.Add (menu);
  111. var statusBar = new StatusBar (
  112. new []
  113. {
  114. new StatusItem (
  115. Key.CtrlMask | Key.R,
  116. "~^R~ Run Top2",
  117. () => Application.Run (Top2 ())
  118. ),
  119. new StatusItem (
  120. Application.QuitKey,
  121. $"{Application.QuitKey} to Quit",
  122. () => Application.RequestStop ()
  123. )
  124. }
  125. );
  126. top.Add (statusBar);
  127. var t1 = new Toplevel ();
  128. top.Add (t1);
  129. return top;
  130. }
  131. Toplevel Top2 ()
  132. {
  133. var top = new Toplevel (Application.Top.Frame);
  134. top.Text = "Top2";
  135. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  136. var menu = new MenuBar (
  137. new MenuBarItem []
  138. {
  139. new MenuBarItem (
  140. "_Stage",
  141. new MenuItem []
  142. {
  143. new MenuItem (
  144. "_Close",
  145. "",
  146. () => Application
  147. .RequestStop (),
  148. null,
  149. null,
  150. Key.CtrlMask | Key.C
  151. )
  152. }
  153. )
  154. }
  155. );
  156. top.Add (menu);
  157. var statusBar = new StatusBar (
  158. new []
  159. {
  160. new StatusItem (
  161. Key.CtrlMask | Key.C,
  162. "~^C~ Close",
  163. () => Application.RequestStop ()
  164. ),
  165. }
  166. );
  167. top.Add (statusBar);
  168. win.Add (
  169. new ListView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }
  170. );
  171. top.Add (win);
  172. return top;
  173. }
  174. }
  175. #endif
  176. [Fact]
  177. [AutoInitShutdown]
  178. public void Internal_Tests ()
  179. {
  180. var top = new Toplevel ();
  181. var eventInvoked = "";
  182. top.ChildUnloaded += (s, e) => eventInvoked = "ChildUnloaded";
  183. top.OnChildUnloaded (top);
  184. Assert.Equal ("ChildUnloaded", eventInvoked);
  185. top.ChildLoaded += (s, e) => eventInvoked = "ChildLoaded";
  186. top.OnChildLoaded (top);
  187. Assert.Equal ("ChildLoaded", eventInvoked);
  188. top.Closed += (s, e) => eventInvoked = "Closed";
  189. top.OnClosed (top);
  190. Assert.Equal ("Closed", eventInvoked);
  191. top.Closing += (s, e) => eventInvoked = "Closing";
  192. top.OnClosing (new ToplevelClosingEventArgs (top));
  193. Assert.Equal ("Closing", eventInvoked);
  194. top.AllChildClosed += (s, e) => eventInvoked = "AllChildClosed";
  195. top.OnAllChildClosed ();
  196. Assert.Equal ("AllChildClosed", eventInvoked);
  197. top.ChildClosed += (s, e) => eventInvoked = "ChildClosed";
  198. top.OnChildClosed (top);
  199. Assert.Equal ("ChildClosed", eventInvoked);
  200. top.Deactivate += (s, e) => eventInvoked = "Deactivate";
  201. top.OnDeactivate (top);
  202. Assert.Equal ("Deactivate", eventInvoked);
  203. top.Activate += (s, e) => eventInvoked = "Activate";
  204. top.OnActivate (top);
  205. Assert.Equal ("Activate", eventInvoked);
  206. top.Loaded += (s, e) => eventInvoked = "Loaded";
  207. top.OnLoaded ();
  208. Assert.Equal ("Loaded", eventInvoked);
  209. top.Ready += (s, e) => eventInvoked = "Ready";
  210. top.OnReady ();
  211. Assert.Equal ("Ready", eventInvoked);
  212. top.Unloaded += (s, e) => eventInvoked = "Unloaded";
  213. top.OnUnloaded ();
  214. Assert.Equal ("Unloaded", eventInvoked);
  215. top.AddMenuStatusBar (new MenuBar ());
  216. Assert.NotNull (top.MenuBar);
  217. top.AddMenuStatusBar (new StatusBar ());
  218. Assert.NotNull (top.StatusBar);
  219. top.RemoveMenuStatusBar (top.MenuBar);
  220. Assert.Null (top.MenuBar);
  221. top.RemoveMenuStatusBar (top.StatusBar);
  222. Assert.Null (top.StatusBar);
  223. Application.Begin (top);
  224. Assert.Equal (top, Application.Top);
  225. // Application.Top without menu and status bar.
  226. View supView = top.GetLocationThatFits (top, 2, 2, out int nx, out int ny, out MenuBar mb, out StatusBar sb);
  227. Assert.Equal (Application.Top, supView);
  228. Assert.Equal (0, nx);
  229. Assert.Equal (0, ny);
  230. Assert.Null (mb);
  231. Assert.Null (sb);
  232. top.AddMenuStatusBar (new MenuBar ());
  233. Assert.NotNull (top.MenuBar);
  234. // Application.Top with a menu and without status bar.
  235. top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
  236. Assert.Equal (0, nx);
  237. Assert.Equal (1, ny);
  238. Assert.NotNull (mb);
  239. Assert.Null (sb);
  240. top.AddMenuStatusBar (new StatusBar ());
  241. Assert.NotNull (top.StatusBar);
  242. // Application.Top with a menu and status bar.
  243. top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
  244. Assert.Equal (0, nx);
  245. // The available height is lower than the Application.Top height minus
  246. // the menu bar and status bar, then the top can go beyond the bottom
  247. Assert.Equal (2, ny);
  248. Assert.NotNull (mb);
  249. Assert.NotNull (sb);
  250. top.RemoveMenuStatusBar (top.MenuBar);
  251. Assert.Null (top.MenuBar);
  252. // Application.Top without a menu and with a status bar.
  253. top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
  254. Assert.Equal (0, nx);
  255. // The available height is lower than the Application.Top height minus
  256. // the status bar, then the top can go beyond the bottom
  257. Assert.Equal (2, ny);
  258. Assert.Null (mb);
  259. Assert.NotNull (sb);
  260. top.RemoveMenuStatusBar (top.StatusBar);
  261. Assert.Null (top.StatusBar);
  262. Assert.Null (top.MenuBar);
  263. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  264. top.Add (win);
  265. top.LayoutSubviews ();
  266. // The SuperView is always the same regardless of the caller.
  267. supView = top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  268. Assert.Equal (Application.Top, supView);
  269. supView = win.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  270. Assert.Equal (Application.Top, supView);
  271. // Application.Top without menu and status bar.
  272. top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  273. Assert.Equal (0, nx);
  274. Assert.Equal (0, ny);
  275. Assert.Null (mb);
  276. Assert.Null (sb);
  277. top.AddMenuStatusBar (new MenuBar ());
  278. Assert.NotNull (top.MenuBar);
  279. // Application.Top with a menu and without status bar.
  280. top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
  281. Assert.Equal (0, nx);
  282. Assert.Equal (1, ny);
  283. Assert.NotNull (mb);
  284. Assert.Null (sb);
  285. top.AddMenuStatusBar (new StatusBar ());
  286. Assert.NotNull (top.StatusBar);
  287. // Application.Top with a menu and status bar.
  288. top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
  289. Assert.Equal (0, nx);
  290. // The available height is lower than the Application.Top height minus
  291. // the menu bar and status bar, then the top can go beyond the bottom
  292. Assert.Equal (20, ny);
  293. Assert.NotNull (mb);
  294. Assert.NotNull (sb);
  295. top.RemoveMenuStatusBar (top.MenuBar);
  296. top.RemoveMenuStatusBar (top.StatusBar);
  297. Assert.Null (top.StatusBar);
  298. Assert.Null (top.MenuBar);
  299. top.Remove (win);
  300. win = new Window { Width = 60, Height = 15 };
  301. top.Add (win);
  302. // Application.Top without menu and status bar.
  303. top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
  304. Assert.Equal (0, nx);
  305. Assert.Equal (0, ny);
  306. Assert.Null (mb);
  307. Assert.Null (sb);
  308. top.AddMenuStatusBar (new MenuBar ());
  309. Assert.NotNull (top.MenuBar);
  310. // Application.Top with a menu and without status bar.
  311. top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
  312. Assert.Equal (2, nx);
  313. Assert.Equal (2, ny);
  314. Assert.NotNull (mb);
  315. Assert.Null (sb);
  316. top.AddMenuStatusBar (new StatusBar ());
  317. Assert.NotNull (top.StatusBar);
  318. // Application.Top with a menu and status bar.
  319. top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
  320. Assert.Equal (20, nx); // 20+60=80
  321. Assert.Equal (9, ny); // 9+15+1(mb)=25
  322. Assert.NotNull (mb);
  323. Assert.NotNull (sb);
  324. top.PositionToplevels ();
  325. Assert.Equal (new Rectangle (0, 1, 60, 15), win.Frame);
  326. Assert.Null (Toplevel._dragPosition);
  327. win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
  328. Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
  329. win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
  330. Assert.Null (Toplevel._dragPosition);
  331. win.CanFocus = false;
  332. win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
  333. Assert.Null (Toplevel._dragPosition);
  334. }
  335. [Fact]
  336. [AutoInitShutdown]
  337. public void KeyBindings_Command ()
  338. {
  339. var isRunning = false;
  340. var win1 = new Window { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
  341. var lblTf1W1 = new Label { Id = "lblTf1W1", Text = "Enter text in TextField on Win1:" };
  342. var tf1W1 = new TextField
  343. {
  344. Id = "tf1W1", X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill (), Text = "Text1 on Win1"
  345. };
  346. var lblTvW1 = new Label
  347. {
  348. Id = "lblTvW1", Y = Pos.Bottom (lblTf1W1) + 1, Text = "Enter text in TextView on Win1:"
  349. };
  350. var tvW1 = new TextView
  351. {
  352. Id = "tvW1",
  353. X = Pos.Left (tf1W1),
  354. Width = Dim.Fill (),
  355. Height = 2,
  356. Text = "First line Win1\nSecond line Win1"
  357. };
  358. var lblTf2W1 = new Label
  359. {
  360. Id = "lblTf2W1", Y = Pos.Bottom (lblTvW1) + 1, Text = "Enter text in TextField on Win1:"
  361. };
  362. var tf2W1 = new TextField { Id = "tf2W1", X = Pos.Left (tf1W1), Width = Dim.Fill (), Text = "Text2 on Win1" };
  363. win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1);
  364. var win2 = new Window
  365. {
  366. Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50f), Height = Dim.Fill ()
  367. };
  368. var lblTf1W2 = new Label { Id = "lblTf1W2", Text = "Enter text in TextField on Win2:" };
  369. var tf1W2 = new TextField
  370. {
  371. Id = "tf1W2", X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill (), Text = "Text1 on Win2"
  372. };
  373. var lblTvW2 = new Label
  374. {
  375. Id = "lblTvW2", Y = Pos.Bottom (lblTf1W2) + 1, Text = "Enter text in TextView on Win2:"
  376. };
  377. var tvW2 = new TextView
  378. {
  379. Id = "tvW2",
  380. X = Pos.Left (tf1W2),
  381. Width = Dim.Fill (),
  382. Height = 2,
  383. Text = "First line Win1\nSecond line Win2"
  384. };
  385. var lblTf2W2 = new Label
  386. {
  387. Id = "lblTf2W2", Y = Pos.Bottom (lblTvW2) + 1, Text = "Enter text in TextField on Win2:"
  388. };
  389. var tf2W2 = new TextField { Id = "tf2W2", X = Pos.Left (tf1W2), Width = Dim.Fill (), Text = "Text2 on Win2" };
  390. win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2);
  391. Toplevel top = Application.Top;
  392. top.Add (win1, win2);
  393. top.Loaded += (s, e) => isRunning = true;
  394. top.Closing += (s, e) => isRunning = false;
  395. Application.Begin (top);
  396. top.Running = true;
  397. Assert.Equal (new Rectangle (0, 0, 40, 25), win1.Frame);
  398. Assert.Equal (new Rectangle (41, 0, 40, 25), win2.Frame);
  399. Assert.Equal (win1, top.Focused);
  400. Assert.Equal (tf1W1, top.MostFocused);
  401. Assert.True (isRunning);
  402. Assert.True (Application.OnKeyDown (Application.QuitKey));
  403. Assert.False (isRunning);
  404. Assert.True (Application.OnKeyDown (Key.Z.WithCtrl));
  405. Assert.True (Application.OnKeyDown (Key.F5)); // refresh
  406. Assert.True (Application.OnKeyDown (Key.Tab));
  407. Assert.Equal (win1, top.Focused);
  408. Assert.Equal (tvW1, top.MostFocused);
  409. Assert.True (Application.OnKeyDown (Key.Tab));
  410. Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  411. Assert.True (Application.OnKeyDown (Key.Tab.WithShift));
  412. Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  413. Assert.True (Application.OnKeyDown (Key.Tab.WithCtrl));
  414. Assert.Equal (win1, top.Focused);
  415. Assert.Equal (tf2W1, top.MostFocused);
  416. Assert.True (Application.OnKeyDown (Key.Tab));
  417. Assert.Equal (win1, top.Focused);
  418. Assert.Equal (tf1W1, top.MostFocused);
  419. Assert.True (Application.OnKeyDown (Key.CursorRight));
  420. Assert.Equal (win1, top.Focused);
  421. Assert.Equal (tf1W1, top.MostFocused);
  422. Assert.True (Application.OnKeyDown (Key.CursorDown));
  423. Assert.Equal (win1, top.Focused);
  424. Assert.Equal (tvW1, top.MostFocused);
  425. #if UNIX_KEY_BINDINGS
  426. Assert.True (Application.OnKeyDown (new (Key.I.WithCtrl)));
  427. Assert.Equal (win1, top.Focused);
  428. Assert.Equal (tf2W1, top.MostFocused);
  429. #endif
  430. Assert.True (Application.OnKeyDown (Key.Tab.WithShift));
  431. Assert.Equal (win1, top.Focused);
  432. Assert.Equal (tvW1, top.MostFocused);
  433. Assert.True (Application.OnKeyDown (Key.CursorLeft));
  434. Assert.Equal (win1, top.Focused);
  435. Assert.Equal (tf1W1, top.MostFocused);
  436. Assert.True (Application.OnKeyDown (Key.CursorUp));
  437. Assert.Equal (win1, top.Focused);
  438. Assert.Equal (tf2W1, top.MostFocused);
  439. Assert.True (Application.OnKeyDown (Key.Tab.WithCtrl));
  440. Assert.Equal (win2, top.Focused);
  441. Assert.Equal (tf1W2, top.MostFocused);
  442. Assert.True (Application.OnKeyDown (Key.Tab.WithCtrl.WithShift));
  443. Assert.Equal (win1, top.Focused);
  444. Assert.Equal (tf2W1, top.MostFocused);
  445. Assert.True (Application.OnKeyDown (Application.AlternateForwardKey));
  446. Assert.Equal (win2, top.Focused);
  447. Assert.Equal (tf1W2, top.MostFocused);
  448. Assert.True (Application.OnKeyDown (Application.AlternateBackwardKey));
  449. Assert.Equal (win1, top.Focused);
  450. Assert.Equal (tf2W1, top.MostFocused);
  451. Assert.True (Application.OnKeyDown (Key.CursorUp));
  452. Assert.Equal (win1, top.Focused);
  453. Assert.Equal (tvW1, top.MostFocused);
  454. #if UNIX_KEY_BINDINGS
  455. Assert.True (Application.OnKeyDown (new (Key.B.WithCtrl)));
  456. #else
  457. Assert.True (Application.OnKeyDown (Key.CursorLeft));
  458. #endif
  459. Assert.Equal (win1, top.Focused);
  460. Assert.Equal (tf1W1, top.MostFocused);
  461. Assert.True (Application.OnKeyDown (Key.CursorDown));
  462. Assert.Equal (win1, top.Focused);
  463. Assert.Equal (tvW1, top.MostFocused);
  464. Assert.Equal (Point.Empty, tvW1.CursorPosition);
  465. Assert.True (Application.OnKeyDown (Key.End.WithCtrl));
  466. Assert.Equal (win1, top.Focused);
  467. Assert.Equal (tvW1, top.MostFocused);
  468. Assert.Equal (new Point (16, 1), tvW1.CursorPosition);
  469. #if UNIX_KEY_BINDINGS
  470. Assert.True (Application.OnKeyDown (new (Key.F.WithCtrl)));
  471. #else
  472. Assert.True (Application.OnKeyDown (Key.CursorRight));
  473. #endif
  474. Assert.Equal (win1, top.Focused);
  475. Assert.Equal (tf2W1, top.MostFocused);
  476. #if UNIX_KEY_BINDINGS
  477. Assert.True (Application.OnKeyDown (new (Key.L.WithCtrl)));
  478. #else
  479. Assert.True (Application.OnKeyDown (Key.F5));
  480. #endif
  481. }
  482. [Fact]
  483. [AutoInitShutdown]
  484. public void KeyBindings_Command_With_OverlappedTop ()
  485. {
  486. Toplevel top = Application.Top;
  487. Assert.Null (Application.OverlappedTop);
  488. top.IsOverlappedContainer = true;
  489. Application.Begin (top);
  490. Assert.Equal (Application.Top, Application.OverlappedTop);
  491. var isRunning = true;
  492. var win1 = new Window { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () };
  493. var lblTf1W1 = new Label { Text = "Enter text in TextField on Win1:" };
  494. var tf1W1 = new TextField { X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill (), Text = "Text1 on Win1" };
  495. var lblTvW1 = new Label { Y = Pos.Bottom (lblTf1W1) + 1, Text = "Enter text in TextView on Win1:" };
  496. var tvW1 = new TextView
  497. {
  498. X = Pos.Left (tf1W1), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win1"
  499. };
  500. var lblTf2W1 = new Label { Y = Pos.Bottom (lblTvW1) + 1, Text = "Enter text in TextField on Win1:" };
  501. var tf2W1 = new TextField { X = Pos.Left (tf1W1), Width = Dim.Fill (), Text = "Text2 on Win1" };
  502. win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1);
  503. var win2 = new Window { Id = "win2", Width = Dim.Percent (50f), Height = Dim.Fill () };
  504. var lblTf1W2 = new Label { Text = "Enter text in TextField on Win2:" };
  505. var tf1W2 = new TextField { X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill (), Text = "Text1 on Win2" };
  506. var lblTvW2 = new Label { Y = Pos.Bottom (lblTf1W2) + 1, Text = "Enter text in TextView on Win2:" };
  507. var tvW2 = new TextView
  508. {
  509. X = Pos.Left (tf1W2), Width = Dim.Fill (), Height = 2, Text = "First line Win1\nSecond line Win2"
  510. };
  511. var lblTf2W2 = new Label { Y = Pos.Bottom (lblTvW2) + 1, Text = "Enter text in TextField on Win2:" };
  512. var tf2W2 = new TextField { X = Pos.Left (tf1W2), Width = Dim.Fill (), Text = "Text2 on Win2" };
  513. win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2);
  514. win1.Closing += (s, e) => isRunning = false;
  515. Assert.Null (top.Focused);
  516. Assert.Equal (top, Application.Current);
  517. Assert.True (top.IsCurrentTop);
  518. Assert.Equal (top, Application.OverlappedTop);
  519. Application.Begin (win1);
  520. Assert.Equal (new Rectangle (0, 0, 40, 25), win1.Frame);
  521. Assert.NotEqual (top, Application.Current);
  522. Assert.False (top.IsCurrentTop);
  523. Assert.Equal (win1, Application.Current);
  524. Assert.True (win1.IsCurrentTop);
  525. Assert.True (win1.IsOverlapped);
  526. Assert.Null (top.Focused);
  527. Assert.Null (top.MostFocused);
  528. Assert.Equal (tf1W1, win1.MostFocused);
  529. Assert.True (win1.IsOverlapped);
  530. Assert.Single (Application.OverlappedChildren);
  531. Application.Begin (win2);
  532. Assert.Equal (new Rectangle (0, 0, 40, 25), win2.Frame);
  533. Assert.NotEqual (top, Application.Current);
  534. Assert.False (top.IsCurrentTop);
  535. Assert.Equal (win2, Application.Current);
  536. Assert.True (win2.IsCurrentTop);
  537. Assert.True (win2.IsOverlapped);
  538. Assert.Null (top.Focused);
  539. Assert.Null (top.MostFocused);
  540. Assert.Equal (tf1W2, win2.MostFocused);
  541. Assert.Equal (2, Application.OverlappedChildren.Count);
  542. Application.MoveToOverlappedChild (win1);
  543. Assert.Equal (win1, Application.Current);
  544. Assert.Equal (win1, Application.OverlappedChildren [0]);
  545. win1.Running = true;
  546. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.QuitKey));
  547. Assert.False (isRunning);
  548. Assert.False (win1.Running);
  549. Assert.Equal (win1, Application.OverlappedChildren [0]);
  550. Assert.True (
  551. Application.OverlappedChildren [0].NewKeyDownEvent (Key.Z.WithCtrl)
  552. );
  553. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.F5)); // refresh
  554. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
  555. Assert.True (win1.IsCurrentTop);
  556. Assert.Equal (tvW1, win1.MostFocused);
  557. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
  558. Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  559. Assert.True (
  560. Application.OverlappedChildren [0]
  561. .NewKeyDownEvent (Key.Tab.WithShift)
  562. );
  563. Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
  564. Assert.True (
  565. Application.OverlappedChildren [0]
  566. .NewKeyDownEvent (Key.Tab.WithCtrl)
  567. );
  568. Assert.Equal (win1, Application.OverlappedChildren [0]);
  569. Assert.Equal (tf2W1, win1.MostFocused);
  570. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
  571. Assert.Equal (win1, Application.OverlappedChildren [0]);
  572. Assert.Equal (tf1W1, win1.MostFocused);
  573. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorRight));
  574. Assert.Equal (win1, Application.OverlappedChildren [0]);
  575. Assert.Equal (tf1W1, win1.MostFocused);
  576. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown));
  577. Assert.Equal (win1, Application.OverlappedChildren [0]);
  578. Assert.Equal (tvW1, win1.MostFocused);
  579. #if UNIX_KEY_BINDINGS
  580. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.I.WithCtrl)));
  581. Assert.Equal (win1, Application.OverlappedChildren [0]);
  582. Assert.Equal (tf2W1, win1.MostFocused);
  583. #endif
  584. Assert.True (
  585. Application.OverlappedChildren [0]
  586. .NewKeyDownEvent (Key.Tab.WithShift)
  587. );
  588. Assert.Equal (win1, Application.OverlappedChildren [0]);
  589. Assert.Equal (tvW1, win1.MostFocused);
  590. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorLeft));
  591. Assert.Equal (win1, Application.OverlappedChildren [0]);
  592. Assert.Equal (tf1W1, win1.MostFocused);
  593. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorUp));
  594. Assert.Equal (win1, Application.OverlappedChildren [0]);
  595. Assert.Equal (tf2W1, win1.MostFocused);
  596. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
  597. Assert.Equal (win1, Application.OverlappedChildren [0]);
  598. Assert.Equal (tf1W1, win1.MostFocused);
  599. Assert.True (
  600. Application.OverlappedChildren [0]
  601. .NewKeyDownEvent (Key.Tab.WithCtrl)
  602. );
  603. Assert.Equal (win2, Application.OverlappedChildren [0]);
  604. Assert.Equal (tf1W2, win2.MostFocused);
  605. tf2W2.SetFocus ();
  606. Assert.True (tf2W2.HasFocus);
  607. Assert.True (
  608. Application.OverlappedChildren [0]
  609. .NewKeyDownEvent (Key.Tab.WithCtrl.WithShift)
  610. );
  611. Assert.Equal (win1, Application.OverlappedChildren [0]);
  612. Assert.Equal (tf1W1, win1.MostFocused);
  613. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateForwardKey));
  614. Assert.Equal (win2, Application.OverlappedChildren [0]);
  615. Assert.Equal (tf2W2, win2.MostFocused);
  616. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateBackwardKey));
  617. Assert.Equal (win1, Application.OverlappedChildren [0]);
  618. Assert.Equal (tf1W1, win1.MostFocused);
  619. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown));
  620. Assert.Equal (win1, Application.OverlappedChildren [0]);
  621. Assert.Equal (tvW1, win1.MostFocused);
  622. #if UNIX_KEY_BINDINGS
  623. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.B.WithCtrl)));
  624. #else
  625. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorLeft));
  626. #endif
  627. Assert.Equal (win1, Application.OverlappedChildren [0]);
  628. Assert.Equal (tf1W1, win1.MostFocused);
  629. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown));
  630. Assert.Equal (win1, Application.OverlappedChildren [0]);
  631. Assert.Equal (tvW1, win1.MostFocused);
  632. Assert.Equal (Point.Empty, tvW1.CursorPosition);
  633. Assert.True (
  634. Application.OverlappedChildren [0]
  635. .NewKeyDownEvent (Key.End.WithCtrl)
  636. );
  637. Assert.Equal (win1, Application.OverlappedChildren [0]);
  638. Assert.Equal (tvW1, win1.MostFocused);
  639. Assert.Equal (new Point (16, 1), tvW1.CursorPosition);
  640. #if UNIX_KEY_BINDINGS
  641. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.F.WithCtrl)));
  642. #else
  643. Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorRight));
  644. #endif
  645. Assert.Equal (win1, Application.OverlappedChildren [0]);
  646. Assert.Equal (tf2W1, win1.MostFocused);
  647. #if UNIX_KEY_BINDINGS
  648. Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.L.WithCtrl)));
  649. #endif
  650. }
  651. [Fact]
  652. public void Added_Event_Should_Not_Be_Used_To_Initialize_Toplevel_Events ()
  653. {
  654. Key alternateForwardKey = default;
  655. Key alternateBackwardKey = default;
  656. Key quitKey = default;
  657. var wasAdded = false;
  658. var view = new View ();
  659. view.Added += View_Added;
  660. void View_Added (object sender, SuperViewChangedEventArgs e)
  661. {
  662. Assert.Throws<NullReferenceException> (
  663. () =>
  664. Application.Top.AlternateForwardKeyChanged +=
  665. (s, e) => alternateForwardKey = (KeyCode)e.OldKey
  666. );
  667. Assert.Throws<NullReferenceException> (
  668. () =>
  669. Application.Top.AlternateBackwardKeyChanged +=
  670. (s, e) => alternateBackwardKey = (KeyCode)e.OldKey
  671. );
  672. Assert.Throws<NullReferenceException> (
  673. () =>
  674. Application.Top.QuitKeyChanged += (s, e) =>
  675. quitKey = (KeyCode)e.OldKey
  676. );
  677. Assert.False (wasAdded);
  678. wasAdded = true;
  679. view.Added -= View_Added;
  680. }
  681. var win = new Window ();
  682. win.Add (view);
  683. Application.Init (new FakeDriver ());
  684. Toplevel top = Application.Top;
  685. top.Add (win);
  686. Assert.True (wasAdded);
  687. Application.Shutdown ();
  688. }
  689. [Fact]
  690. [AutoInitShutdown]
  691. public void AlternateForwardKeyChanged_AlternateBackwardKeyChanged_QuitKeyChanged_Events ()
  692. {
  693. Key alternateForwardKey = KeyCode.Null;
  694. Key alternateBackwardKey = KeyCode.Null;
  695. Key quitKey = KeyCode.Null;
  696. var view = new View ();
  697. view.Initialized += View_Initialized;
  698. void View_Initialized (object sender, EventArgs e)
  699. {
  700. Application.Top.AlternateForwardKeyChanged += (s, e) => alternateForwardKey = e.OldKey;
  701. Application.Top.AlternateBackwardKeyChanged += (s, e) => alternateBackwardKey = e.OldKey;
  702. Application.Top.QuitKeyChanged += (s, e) => quitKey = e.OldKey;
  703. }
  704. var win = new Window ();
  705. win.Add (view);
  706. Toplevel top = Application.Top;
  707. top.Add (win);
  708. Application.Begin (top);
  709. Assert.Equal (KeyCode.Null, alternateForwardKey);
  710. Assert.Equal (KeyCode.Null, alternateBackwardKey);
  711. Assert.Equal (KeyCode.Null, quitKey);
  712. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey);
  713. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey);
  714. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey);
  715. Application.AlternateForwardKey = KeyCode.A;
  716. Application.AlternateBackwardKey = KeyCode.B;
  717. Application.QuitKey = KeyCode.C;
  718. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, alternateForwardKey);
  719. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, alternateBackwardKey);
  720. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, quitKey);
  721. Assert.Equal (KeyCode.A, Application.AlternateForwardKey);
  722. Assert.Equal (KeyCode.B, Application.AlternateBackwardKey);
  723. Assert.Equal (KeyCode.C, Application.QuitKey);
  724. // Replacing the defaults keys to avoid errors on others unit tests that are using it.
  725. Application.AlternateForwardKey = Key.PageDown.WithCtrl;
  726. Application.AlternateBackwardKey = Key.PageUp.WithCtrl;
  727. Application.QuitKey = Key.Q.WithCtrl;
  728. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey);
  729. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey);
  730. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey);
  731. }
  732. [Fact]
  733. [AutoInitShutdown]
  734. public void Mouse_Drag_On_Top_With_Superview_Null ()
  735. {
  736. var win = new Window ();
  737. Toplevel top = Application.Top;
  738. top.Add (win);
  739. int iterations = -1;
  740. Window testWindow;
  741. Application.Iteration += (s, a) =>
  742. {
  743. iterations++;
  744. if (iterations == 0)
  745. {
  746. ((FakeDriver)Application.Driver).SetBufferSize (15, 7);
  747. // Don't use MessageBox here; it's too complicated for this unit test; just use Window
  748. testWindow = new Window
  749. {
  750. Text = "Hello",
  751. X = 2,
  752. Y = 2,
  753. Width = 10,
  754. Height = 3
  755. };
  756. Application.Run (testWindow);
  757. }
  758. else if (iterations == 1)
  759. {
  760. TestHelpers.AssertDriverContentsWithFrameAre (
  761. @"
  762. ┌─────────────┐
  763. │ │
  764. │ ┌────────┐ │
  765. │ │Hello │ │
  766. │ └────────┘ │
  767. │ │
  768. └─────────────┘
  769. ",
  770. _output
  771. );
  772. }
  773. else if (iterations == 2)
  774. {
  775. Assert.Null (Application.MouseGrabView);
  776. // Grab the mouse
  777. Application.OnMouseEvent (
  778. new MouseEventEventArgs (
  779. new MouseEvent { X = 3, Y = 2, Flags = MouseFlags.Button1Pressed }
  780. )
  781. );
  782. Assert.Equal (Application.Current, Application.MouseGrabView);
  783. Assert.Equal (new Rectangle (2, 2, 10, 3), Application.MouseGrabView.Frame);
  784. }
  785. else if (iterations == 3)
  786. {
  787. Assert.Equal (Application.Current, Application.MouseGrabView);
  788. // Drag to left
  789. Application.OnMouseEvent (
  790. new MouseEventEventArgs (
  791. new MouseEvent
  792. {
  793. X = 2,
  794. Y = 2,
  795. Flags = MouseFlags.Button1Pressed
  796. | MouseFlags.ReportMousePosition
  797. }
  798. )
  799. );
  800. Application.Refresh ();
  801. Assert.Equal (Application.Current, Application.MouseGrabView);
  802. Assert.Equal (new Rectangle (1, 2, 10, 3), Application.MouseGrabView.Frame);
  803. }
  804. else if (iterations == 4)
  805. {
  806. Assert.Equal (Application.Current, Application.MouseGrabView);
  807. TestHelpers.AssertDriverContentsWithFrameAre (
  808. @"
  809. ┌─────────────┐
  810. │ │
  811. │┌────────┐ │
  812. ││Hello │ │
  813. │└────────┘ │
  814. │ │
  815. └─────────────┘",
  816. _output
  817. );
  818. Assert.Equal (Application.Current, Application.MouseGrabView);
  819. }
  820. else if (iterations == 5)
  821. {
  822. Assert.Equal (Application.Current, Application.MouseGrabView);
  823. // Drag up
  824. Application.OnMouseEvent (
  825. new MouseEventEventArgs (
  826. new MouseEvent
  827. {
  828. X = 2,
  829. Y = 1,
  830. Flags = MouseFlags.Button1Pressed
  831. | MouseFlags.ReportMousePosition
  832. }
  833. )
  834. );
  835. Application.Refresh ();
  836. Assert.Equal (Application.Current, Application.MouseGrabView);
  837. Assert.Equal (new Rectangle (1, 1, 10, 3), Application.MouseGrabView.Frame);
  838. }
  839. else if (iterations == 6)
  840. {
  841. Assert.Equal (Application.Current, Application.MouseGrabView);
  842. TestHelpers.AssertDriverContentsWithFrameAre (
  843. @"
  844. ┌─────────────┐
  845. │┌────────┐ │
  846. ││Hello │ │
  847. │└────────┘ │
  848. │ │
  849. │ │
  850. └─────────────┘",
  851. _output
  852. );
  853. Assert.Equal (Application.Current, Application.MouseGrabView);
  854. Assert.Equal (new Rectangle (1, 1, 10, 3), Application.MouseGrabView.Frame);
  855. }
  856. else if (iterations == 7)
  857. {
  858. Assert.Equal (Application.Current, Application.MouseGrabView);
  859. // Ungrab the mouse
  860. Application.OnMouseEvent (
  861. new MouseEventEventArgs (
  862. new MouseEvent { X = 2, Y = 1, Flags = MouseFlags.Button1Released }
  863. )
  864. );
  865. Application.Refresh ();
  866. Assert.Null (Application.MouseGrabView);
  867. }
  868. else if (iterations == 8)
  869. {
  870. Application.RequestStop ();
  871. }
  872. else if (iterations == 9)
  873. {
  874. Application.RequestStop ();
  875. }
  876. };
  877. Application.Run ();
  878. }
  879. [Fact]
  880. [AutoInitShutdown]
  881. public void Mouse_Drag_On_Top_With_Superview_Not_Null ()
  882. {
  883. var win = new Window { X = 3, Y = 2, Width = 10, Height = 5 };
  884. Toplevel top = Application.Top;
  885. top.Add (win);
  886. int iterations = -1;
  887. var movex = 0;
  888. var movey = 0;
  889. var location = new Rectangle (win.Frame.X, win.Frame.Y, 7, 3);
  890. Application.Iteration += (s, a) =>
  891. {
  892. iterations++;
  893. if (iterations == 0)
  894. {
  895. ((FakeDriver)Application.Driver).SetBufferSize (30, 10);
  896. }
  897. else if (iterations == 1)
  898. {
  899. location = win.Frame;
  900. Assert.Null (Application.MouseGrabView);
  901. // Grab the mouse
  902. Application.OnMouseEvent (
  903. new MouseEventEventArgs (
  904. new MouseEvent
  905. {
  906. X = win.Frame.X, Y = win.Frame.Y,
  907. Flags = MouseFlags.Button1Pressed
  908. }
  909. )
  910. );
  911. Assert.Equal (win, Application.MouseGrabView);
  912. Assert.Equal (location, Application.MouseGrabView.Frame);
  913. }
  914. else if (iterations == 2)
  915. {
  916. Assert.Equal (win, Application.MouseGrabView);
  917. // Drag to left
  918. movex = 1;
  919. movey = 0;
  920. Application.OnMouseEvent (
  921. new MouseEventEventArgs (
  922. new MouseEvent
  923. {
  924. X = win.Frame.X + movex,
  925. Y = win.Frame.Y + movey,
  926. Flags = MouseFlags.Button1Pressed
  927. | MouseFlags.ReportMousePosition
  928. }
  929. )
  930. );
  931. Assert.Equal (win, Application.MouseGrabView);
  932. }
  933. else if (iterations == 3)
  934. {
  935. // we should have moved +1, +0
  936. Assert.Equal (win, Application.MouseGrabView);
  937. Assert.Equal (win, Application.MouseGrabView);
  938. location.Offset (movex, movey);
  939. Assert.Equal (location, Application.MouseGrabView.Frame);
  940. }
  941. else if (iterations == 4)
  942. {
  943. Assert.Equal (win, Application.MouseGrabView);
  944. // Drag up
  945. movex = 0;
  946. movey = -1;
  947. Application.OnMouseEvent (
  948. new MouseEventEventArgs (
  949. new MouseEvent
  950. {
  951. X = win.Frame.X + movex,
  952. Y = win.Frame.Y + movey,
  953. Flags = MouseFlags.Button1Pressed
  954. | MouseFlags.ReportMousePosition
  955. }
  956. )
  957. );
  958. Assert.Equal (win, Application.MouseGrabView);
  959. }
  960. else if (iterations == 5)
  961. {
  962. // we should have moved +0, -1
  963. Assert.Equal (win, Application.MouseGrabView);
  964. location.Offset (movex, movey);
  965. Assert.Equal (location, Application.MouseGrabView.Frame);
  966. }
  967. else if (iterations == 6)
  968. {
  969. Assert.Equal (win, Application.MouseGrabView);
  970. // Ungrab the mouse
  971. movex = 0;
  972. movey = 0;
  973. Application.OnMouseEvent (
  974. new MouseEventEventArgs (
  975. new MouseEvent
  976. {
  977. X = win.Frame.X + movex, Y = win.Frame.Y + movey,
  978. Flags = MouseFlags.Button1Released
  979. }
  980. )
  981. );
  982. Assert.Null (Application.MouseGrabView);
  983. }
  984. else if (iterations == 7)
  985. {
  986. Application.RequestStop ();
  987. }
  988. };
  989. Application.Run ();
  990. }
  991. [Fact]
  992. [AutoInitShutdown]
  993. public void GetLocationThatFits_With_Border_Null_Not_Throws ()
  994. {
  995. var top = new Toplevel ();
  996. Application.Begin (top);
  997. Exception exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (0, 10));
  998. Assert.Null (exception);
  999. exception = Record.Exception (() => ((FakeDriver)Application.Driver).SetBufferSize (10, 0));
  1000. Assert.Null (exception);
  1001. }
  1002. [Fact]
  1003. [AutoInitShutdown]
  1004. public void OnEnter_OnLeave_Triggered_On_Application_Begin_End ()
  1005. {
  1006. var isEnter = false;
  1007. var isLeave = false;
  1008. var v = new View ();
  1009. v.Enter += (s, _) => isEnter = true;
  1010. v.Leave += (s, _) => isLeave = true;
  1011. Toplevel top = Application.Top;
  1012. top.Add (v);
  1013. Assert.False (v.CanFocus);
  1014. Exception exception = Record.Exception (() => top.OnEnter (top));
  1015. Assert.Null (exception);
  1016. exception = Record.Exception (() => top.OnLeave (top));
  1017. Assert.Null (exception);
  1018. v.CanFocus = true;
  1019. Application.Begin (top);
  1020. Assert.True (isEnter);
  1021. Assert.False (isLeave);
  1022. isEnter = false;
  1023. var d = new Dialog ();
  1024. RunState rs = Application.Begin (d);
  1025. Assert.False (isEnter);
  1026. Assert.True (isLeave);
  1027. isLeave = false;
  1028. Application.End (rs);
  1029. Assert.True (isEnter);
  1030. Assert.False (
  1031. isLeave
  1032. ); // Leave event cannot be trigger because it v.Enter was performed and v is focused
  1033. Assert.True (v.HasFocus);
  1034. }
  1035. [Fact]
  1036. [AutoInitShutdown]
  1037. public void OnEnter_OnLeave_Triggered_On_Application_Begin_End_With_More_Toplevels ()
  1038. {
  1039. var iterations = 0;
  1040. var steps = new int [5];
  1041. var isEnterTop = false;
  1042. var isLeaveTop = false;
  1043. var vt = new View ();
  1044. Toplevel top = Application.Top;
  1045. var diag = new Dialog ();
  1046. vt.Enter += (s, e) =>
  1047. {
  1048. iterations++;
  1049. isEnterTop = true;
  1050. if (iterations == 1)
  1051. {
  1052. steps [0] = iterations;
  1053. Assert.Null (e.View);
  1054. }
  1055. else
  1056. {
  1057. steps [4] = iterations;
  1058. Assert.Equal (diag, e.View);
  1059. }
  1060. };
  1061. vt.Leave += (s, e) =>
  1062. {
  1063. iterations++;
  1064. steps [1] = iterations;
  1065. isLeaveTop = true;
  1066. Assert.Equal (diag, e.View);
  1067. };
  1068. top.Add (vt);
  1069. Assert.False (vt.CanFocus);
  1070. Exception exception = Record.Exception (() => top.OnEnter (top));
  1071. Assert.Null (exception);
  1072. exception = Record.Exception (() => top.OnLeave (top));
  1073. Assert.Null (exception);
  1074. vt.CanFocus = true;
  1075. Application.Begin (top);
  1076. Assert.True (isEnterTop);
  1077. Assert.False (isLeaveTop);
  1078. isEnterTop = false;
  1079. var isEnterDiag = false;
  1080. var isLeaveDiag = false;
  1081. var vd = new View ();
  1082. vd.Enter += (s, e) =>
  1083. {
  1084. iterations++;
  1085. steps [2] = iterations;
  1086. isEnterDiag = true;
  1087. Assert.Null (e.View);
  1088. };
  1089. vd.Leave += (s, e) =>
  1090. {
  1091. iterations++;
  1092. steps [3] = iterations;
  1093. isLeaveDiag = true;
  1094. Assert.Equal (top, e.View);
  1095. };
  1096. diag.Add (vd);
  1097. Assert.False (vd.CanFocus);
  1098. exception = Record.Exception (() => diag.OnEnter (diag));
  1099. Assert.Null (exception);
  1100. exception = Record.Exception (() => diag.OnLeave (diag));
  1101. Assert.Null (exception);
  1102. vd.CanFocus = true;
  1103. RunState rs = Application.Begin (diag);
  1104. Assert.True (isEnterDiag);
  1105. Assert.False (isLeaveDiag);
  1106. Assert.False (isEnterTop);
  1107. Assert.True (isLeaveTop);
  1108. isEnterDiag = false;
  1109. isLeaveTop = false;
  1110. Application.End (rs);
  1111. Assert.False (isEnterDiag);
  1112. Assert.True (isLeaveDiag);
  1113. Assert.True (isEnterTop);
  1114. Assert.False (
  1115. isLeaveTop
  1116. ); // Leave event cannot be trigger because it v.Enter was performed and v is focused
  1117. Assert.True (vt.HasFocus);
  1118. Assert.Equal (1, steps [0]);
  1119. Assert.Equal (2, steps [1]);
  1120. Assert.Equal (3, steps [2]);
  1121. Assert.Equal (4, steps [3]);
  1122. Assert.Equal (5, steps [^1]);
  1123. }
  1124. [Fact]
  1125. [AutoInitShutdown]
  1126. public void PositionCursor_SetCursorVisibility_To_Invisible_If_Focused_Is_Null ()
  1127. {
  1128. var tf = new TextField { Width = 5, Text = "test" };
  1129. var view = new View { Width = 10, Height = 10 };
  1130. view.Add (tf);
  1131. Application.Top.Add (view);
  1132. Application.Begin (Application.Top);
  1133. Assert.True (tf.HasFocus);
  1134. Application.Driver.GetCursorVisibility (out CursorVisibility cursor);
  1135. Assert.Equal (CursorVisibility.Default, cursor);
  1136. view.Enabled = false;
  1137. Assert.False (tf.HasFocus);
  1138. Application.Refresh ();
  1139. Application.Driver.GetCursorVisibility (out cursor);
  1140. Assert.Equal (CursorVisibility.Invisible, cursor);
  1141. }
  1142. [Fact]
  1143. [AutoInitShutdown]
  1144. public void IsLoaded_Application_Begin ()
  1145. {
  1146. Toplevel top = Application.Top;
  1147. Assert.False (top.IsLoaded);
  1148. Application.Begin (top);
  1149. Assert.True (top.IsLoaded);
  1150. }
  1151. [Fact]
  1152. [AutoInitShutdown]
  1153. public void IsLoaded_With_Sub_Toplevel_Application_Begin_NeedDisplay ()
  1154. {
  1155. Toplevel top = Application.Top;
  1156. var subTop = new Toplevel ();
  1157. var view = new View { Frame = new Rectangle (0, 0, 20, 10) };
  1158. subTop.Add (view);
  1159. top.Add (subTop);
  1160. Assert.False (top.IsLoaded);
  1161. Assert.False (subTop.IsLoaded);
  1162. Assert.Equal (new Rectangle (0, 0, 20, 10), view.Frame);
  1163. view.LayoutStarted += view_LayoutStarted;
  1164. void view_LayoutStarted (object sender, LayoutEventArgs e)
  1165. {
  1166. Assert.Equal (new Rectangle (0, 0, 20, 10), view._needsDisplayRect);
  1167. view.LayoutStarted -= view_LayoutStarted;
  1168. }
  1169. Application.Begin (top);
  1170. Assert.True (top.IsLoaded);
  1171. Assert.True (subTop.IsLoaded);
  1172. Assert.Equal (new Rectangle (0, 0, 20, 10), view.Frame);
  1173. view.Frame = new (1, 3, 10, 5);
  1174. Assert.Equal (new (1, 3, 10, 5), view.Frame);
  1175. Assert.Equal (new (0, 0, 10, 5), view._needsDisplayRect);
  1176. view.OnDrawContent (view.Bounds);
  1177. view.Frame = new (1, 3, 10, 5);
  1178. Assert.Equal (new (1, 3, 10, 5), view.Frame);
  1179. Assert.Equal (new (0, 0, 10, 5), view._needsDisplayRect);
  1180. }
  1181. // BUGBUG: Broke this test with #2483 - @bdisp I need your help figuring out why
  1182. [Fact]
  1183. [AutoInitShutdown]
  1184. public void Toplevel_Inside_ScrollView_MouseGrabView ()
  1185. {
  1186. var scrollView = new ScrollView
  1187. {
  1188. X = 3,
  1189. Y = 3,
  1190. Width = 40,
  1191. Height = 16,
  1192. ContentSize = new (200, 100)
  1193. };
  1194. var win = new Window { X = 3, Y = 3, Width = Dim.Fill (3), Height = Dim.Fill (3) };
  1195. scrollView.Add (win);
  1196. Toplevel top = Application.Top;
  1197. top.Add (scrollView);
  1198. Application.Begin (top);
  1199. Assert.Equal (new (0, 0, 80, 25), top.Frame);
  1200. Assert.Equal (new (3, 3, 40, 16), scrollView.Frame);
  1201. Assert.Equal (new (0, 0, 200, 100), scrollView.Subviews [0].Frame);
  1202. Assert.Equal (new (3, 3, 194, 94), win.Frame);
  1203. TestHelpers.AssertDriverContentsWithFrameAre (
  1204. @"
  1205. ┌───────────────────────────────────┴
  1206. │ ░
  1207. │ ░
  1208. │ ░
  1209. │ ░
  1210. │ ░
  1211. │ ░
  1212. │ ░
  1213. │ ░
  1214. │ ░
  1215. │ ░
  1216. │ ▼
  1217. ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
  1218. _output
  1219. );
  1220. Application.OnMouseEvent (
  1221. new MouseEventEventArgs (
  1222. new MouseEvent { X = 6, Y = 6, Flags = MouseFlags.Button1Pressed }
  1223. )
  1224. );
  1225. Assert.Equal (win, Application.MouseGrabView);
  1226. Assert.Equal (new (3, 3, 194, 94), win.Frame);
  1227. Application.OnMouseEvent (
  1228. new MouseEventEventArgs (
  1229. new MouseEvent
  1230. {
  1231. X = 9,
  1232. Y = 9,
  1233. Flags = MouseFlags.Button1Pressed
  1234. | MouseFlags.ReportMousePosition
  1235. }
  1236. )
  1237. );
  1238. Assert.Equal (win, Application.MouseGrabView);
  1239. top.SetNeedsLayout ();
  1240. top.LayoutSubviews ();
  1241. Assert.Equal (new Rectangle (6, 6, 191, 91), win.Frame);
  1242. Application.Refresh ();
  1243. TestHelpers.AssertDriverContentsWithFrameAre (
  1244. @"
  1245. ┌────────────────────────────────░
  1246. │ ░
  1247. │ ░
  1248. │ ░
  1249. │ ░
  1250. │ ░
  1251. │ ░
  1252. │ ░
  1253. │ ▼
  1254. ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
  1255. _output
  1256. );
  1257. Application.OnMouseEvent (
  1258. new MouseEventEventArgs (
  1259. new MouseEvent
  1260. {
  1261. X = 5,
  1262. Y = 5,
  1263. Flags = MouseFlags.Button1Pressed
  1264. | MouseFlags.ReportMousePosition
  1265. }
  1266. )
  1267. );
  1268. Assert.Equal (win, Application.MouseGrabView);
  1269. top.SetNeedsLayout ();
  1270. top.LayoutSubviews ();
  1271. Assert.Equal (new Rectangle (2, 2, 195, 95), win.Frame);
  1272. Application.Refresh ();
  1273. TestHelpers.AssertDriverContentsWithFrameAre (
  1274. @"
  1275. ┌────────────────────────────────────│
  1276. │ ┴
  1277. │ ░
  1278. │ ░
  1279. │ ░
  1280. │ ░
  1281. │ ░
  1282. │ ░
  1283. │ ░
  1284. │ ░
  1285. │ ░
  1286. │ ░
  1287. │ ▼
  1288. ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
  1289. _output
  1290. );
  1291. Application.OnMouseEvent (
  1292. new MouseEventEventArgs (
  1293. new MouseEvent { X = 5, Y = 5, Flags = MouseFlags.Button1Released }
  1294. )
  1295. );
  1296. Assert.Null (Application.MouseGrabView);
  1297. Application.OnMouseEvent (
  1298. new MouseEventEventArgs (
  1299. new MouseEvent { X = 4, Y = 4, Flags = MouseFlags.ReportMousePosition }
  1300. )
  1301. );
  1302. Assert.Equal (scrollView, Application.MouseGrabView);
  1303. }
  1304. [Fact]
  1305. [AutoInitShutdown]
  1306. public void Window_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Left_Right_And_Bottom ()
  1307. {
  1308. Toplevel top = Application.Top;
  1309. var window = new Window { Width = 20, Height = 3 };
  1310. Application.Begin (top);
  1311. ((FakeDriver)Application.Driver).SetBufferSize (40, 10);
  1312. Application.Begin (window);
  1313. Application.Refresh ();
  1314. Assert.Equal (new Rectangle (0, 0, 40, 10), top.Frame);
  1315. Assert.Equal (new Rectangle (0, 0, 20, 3), window.Frame);
  1316. TestHelpers.AssertDriverContentsWithFrameAre (
  1317. @"
  1318. ┌──────────────────┐
  1319. │ │
  1320. └──────────────────┘
  1321. ",
  1322. _output
  1323. );
  1324. Assert.Null (Application.MouseGrabView);
  1325. Application.OnMouseEvent (
  1326. new MouseEventEventArgs (
  1327. new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed }
  1328. )
  1329. );
  1330. Assert.Equal (window, Application.MouseGrabView);
  1331. Application.OnMouseEvent (
  1332. new MouseEventEventArgs (
  1333. new MouseEvent
  1334. {
  1335. X = -11,
  1336. Y = -4,
  1337. Flags = MouseFlags.Button1Pressed
  1338. | MouseFlags.ReportMousePosition
  1339. }
  1340. )
  1341. );
  1342. Application.Refresh ();
  1343. Assert.Equal (new Rectangle (0, 0, 40, 10), top.Frame);
  1344. Assert.Equal (new Rectangle (0, 0, 20, 3), window.Frame);
  1345. TestHelpers.AssertDriverContentsWithFrameAre (
  1346. @"
  1347. ┌──────────────────┐
  1348. │ │
  1349. └──────────────────┘
  1350. ",
  1351. _output
  1352. );
  1353. // Changes Top size to same size as Dialog more menu and scroll bar
  1354. ((FakeDriver)Application.Driver).SetBufferSize (20, 3);
  1355. Application.OnMouseEvent (
  1356. new MouseEventEventArgs (
  1357. new MouseEvent
  1358. {
  1359. X = -1,
  1360. Y = -1,
  1361. Flags = MouseFlags.Button1Pressed
  1362. | MouseFlags.ReportMousePosition
  1363. }
  1364. )
  1365. );
  1366. Application.Refresh ();
  1367. Assert.Equal (new Rectangle (0, 0, 20, 3), top.Frame);
  1368. Assert.Equal (new Rectangle (0, 0, 20, 3), window.Frame);
  1369. TestHelpers.AssertDriverContentsWithFrameAre (
  1370. @"
  1371. ┌──────────────────┐
  1372. │ │
  1373. └──────────────────┘
  1374. ",
  1375. _output
  1376. );
  1377. // Changes Top size smaller than Dialog size
  1378. ((FakeDriver)Application.Driver).SetBufferSize (19, 2);
  1379. Application.OnMouseEvent (
  1380. new MouseEventEventArgs (
  1381. new MouseEvent
  1382. {
  1383. X = -1,
  1384. Y = -1,
  1385. Flags = MouseFlags.Button1Pressed
  1386. | MouseFlags.ReportMousePosition
  1387. }
  1388. )
  1389. );
  1390. Application.Refresh ();
  1391. Assert.Equal (new Rectangle (0, 0, 19, 2), top.Frame);
  1392. Assert.Equal (new Rectangle (-1, 0, 20, 3), window.Frame);
  1393. TestHelpers.AssertDriverContentsWithFrameAre (
  1394. @"
  1395. ──────────────────┐
  1396. ",
  1397. _output
  1398. );
  1399. Application.OnMouseEvent (
  1400. new MouseEventEventArgs (
  1401. new MouseEvent
  1402. {
  1403. X = 18,
  1404. Y = 1,
  1405. Flags = MouseFlags.Button1Pressed
  1406. | MouseFlags.ReportMousePosition
  1407. }
  1408. )
  1409. );
  1410. Application.Refresh ();
  1411. Assert.Equal (new Rectangle (0, 0, 19, 2), top.Frame);
  1412. Assert.Equal (new Rectangle (18, 1, 20, 3), window.Frame);
  1413. TestHelpers.AssertDriverContentsWithFrameAre (
  1414. @"
  1415. ┌",
  1416. _output
  1417. );
  1418. // On a real app we can't go beyond the SuperView bounds
  1419. Application.OnMouseEvent (
  1420. new MouseEventEventArgs (
  1421. new MouseEvent
  1422. {
  1423. X = 19,
  1424. Y = 2,
  1425. Flags = MouseFlags.Button1Pressed
  1426. | MouseFlags.ReportMousePosition
  1427. }
  1428. )
  1429. );
  1430. Application.Refresh ();
  1431. Assert.Equal (new Rectangle (0, 0, 19, 2), top.Frame);
  1432. Assert.Equal (new Rectangle (19, 2, 20, 3), window.Frame);
  1433. TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
  1434. }
  1435. [Fact]
  1436. [AutoInitShutdown]
  1437. public void Modal_As_Top_Will_Drag_Cleanly ()
  1438. {
  1439. // Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
  1440. var window = new Window { Width = 10, Height = 3 };
  1441. window.Add (
  1442. new Label
  1443. {
  1444. X = Pos.Center (),
  1445. Y = Pos.Center (),
  1446. AutoSize = false,
  1447. Width = Dim.Fill (),
  1448. Height = Dim.Fill (),
  1449. TextAlignment = TextAlignment.Centered,
  1450. VerticalTextAlignment = VerticalTextAlignment.Middle,
  1451. Text = "Test"
  1452. }
  1453. );
  1454. RunState rs = Application.Begin (window);
  1455. Assert.Null (Application.MouseGrabView);
  1456. Assert.Equal (new Rectangle (0, 0, 10, 3), window.Frame);
  1457. TestHelpers.AssertDriverContentsWithFrameAre (
  1458. @"
  1459. ┌────────┐
  1460. │ Test │
  1461. └────────┘",
  1462. _output
  1463. );
  1464. Application.OnMouseEvent (
  1465. new MouseEventEventArgs (
  1466. new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed }
  1467. )
  1468. );
  1469. var firstIteration = false;
  1470. Application.RunIteration (ref rs, ref firstIteration);
  1471. Assert.Equal (window, Application.MouseGrabView);
  1472. Assert.Equal (new Rectangle (0, 0, 10, 3), window.Frame);
  1473. TestHelpers.AssertDriverContentsWithFrameAre (
  1474. @"
  1475. ┌────────┐
  1476. │ Test │
  1477. └────────┘",
  1478. _output
  1479. );
  1480. Application.OnMouseEvent (
  1481. new MouseEventEventArgs (
  1482. new MouseEvent
  1483. {
  1484. X = 1,
  1485. Y = 1,
  1486. Flags = MouseFlags.Button1Pressed
  1487. | MouseFlags.ReportMousePosition
  1488. }
  1489. )
  1490. );
  1491. firstIteration = false;
  1492. Application.RunIteration (ref rs, ref firstIteration);
  1493. Assert.Equal (window, Application.MouseGrabView);
  1494. Assert.Equal (new Rectangle (1, 1, 10, 3), window.Frame);
  1495. TestHelpers.AssertDriverContentsWithFrameAre (
  1496. @"
  1497. ┌────────┐
  1498. │ Test │
  1499. └────────┘",
  1500. _output
  1501. );
  1502. Application.End (rs);
  1503. }
  1504. [Fact]
  1505. [AutoInitShutdown]
  1506. public void Begin_With_Window_Sets_Size_Correctly ()
  1507. {
  1508. Toplevel top = Application.Top;
  1509. Application.Begin (top);
  1510. ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
  1511. var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
  1512. Assert.Equal (new Rectangle (2, 1, 15, 10), testWindow.Frame);
  1513. RunState rs = Application.Begin (testWindow);
  1514. Assert.Equal (new Rectangle (2, 1, 15, 10), testWindow.Frame);
  1515. }
  1516. // Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
  1517. [Fact]
  1518. [AutoInitShutdown]
  1519. public void Draw_A_Top_Subview_On_A_Window ()
  1520. {
  1521. Toplevel top = Application.Top;
  1522. var win = new Window ();
  1523. top.Add (win);
  1524. Application.Begin (top);
  1525. ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
  1526. Assert.Equal (new Rectangle (0, 0, 20, 20), win.Frame);
  1527. TestHelpers.AssertDriverContentsWithFrameAre (
  1528. @"
  1529. ┌──────────────────┐
  1530. │ │
  1531. │ │
  1532. │ │
  1533. │ │
  1534. │ │
  1535. │ │
  1536. │ │
  1537. │ │
  1538. │ │
  1539. │ │
  1540. │ │
  1541. │ │
  1542. │ │
  1543. │ │
  1544. │ │
  1545. │ │
  1546. │ │
  1547. │ │
  1548. └──────────────────┘",
  1549. _output
  1550. );
  1551. var btnPopup = new Button { Text = "Popup" };
  1552. var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
  1553. testWindow.Add (btnPopup);
  1554. btnPopup.Accept += (s, e) =>
  1555. {
  1556. Rectangle viewToScreen = btnPopup.BoundsToScreen (top.Frame);
  1557. var viewAddedToTop = new View
  1558. {
  1559. Text = "viewAddedToTop",
  1560. X = 1,
  1561. Y = viewToScreen.Y + 1,
  1562. Width = 18,
  1563. Height = 16,
  1564. BorderStyle = LineStyle.Single
  1565. };
  1566. Assert.Equal (testWindow, Application.Current);
  1567. Application.Current.DrawContentComplete += testWindow_DrawContentComplete;
  1568. top.Add (viewAddedToTop);
  1569. void testWindow_DrawContentComplete (object sender, DrawEventArgs e)
  1570. {
  1571. Assert.Equal (new Rectangle (1, 3, 18, 16), viewAddedToTop.Frame);
  1572. Rectangle savedClip = Application.Driver.Clip;
  1573. Application.Driver.Clip = top.Frame;
  1574. viewAddedToTop.Draw ();
  1575. top.Move (2, 15);
  1576. View.Driver.AddStr ("One");
  1577. top.Move (2, 16);
  1578. View.Driver.AddStr ("Two");
  1579. top.Move (2, 17);
  1580. View.Driver.AddStr ("Three");
  1581. Application.Driver.Clip = savedClip;
  1582. Application.Current.DrawContentComplete -= testWindow_DrawContentComplete;
  1583. }
  1584. };
  1585. RunState rs = Application.Begin (testWindow);
  1586. Assert.Equal (new Rectangle (2, 1, 15, 10), testWindow.Frame);
  1587. TestHelpers.AssertDriverContentsWithFrameAre (
  1588. @$"
  1589. ┌──────────────────┐
  1590. │ ┌─────────────┐ │
  1591. │ │{
  1592. CM.Glyphs.LeftBracket
  1593. } Popup {
  1594. CM.Glyphs.RightBracket
  1595. } │ │
  1596. │ │ │ │
  1597. │ │ │ │
  1598. │ │ │ │
  1599. │ │ │ │
  1600. │ │ │ │
  1601. │ │ │ │
  1602. │ │ │ │
  1603. │ └─────────────┘ │
  1604. │ │
  1605. │ │
  1606. │ │
  1607. │ │
  1608. │ │
  1609. │ │
  1610. │ │
  1611. │ │
  1612. └──────────────────┘",
  1613. _output
  1614. );
  1615. Application.OnMouseEvent (
  1616. new MouseEventEventArgs (
  1617. new MouseEvent { X = 5, Y = 2, Flags = MouseFlags.Button1Clicked }
  1618. )
  1619. );
  1620. Application.Top.Draw ();
  1621. var firstIteration = false;
  1622. Application.RunIteration (ref rs, ref firstIteration);
  1623. TestHelpers.AssertDriverContentsWithFrameAre (
  1624. @$"
  1625. ┌──────────────────┐
  1626. │ ┌─────────────┐ │
  1627. │ │{
  1628. CM.Glyphs.LeftBracket
  1629. } Popup {
  1630. CM.Glyphs.RightBracket
  1631. } │ │
  1632. │┌────────────────┐│
  1633. ││viewAddedToTop ││
  1634. ││ ││
  1635. ││ ││
  1636. ││ ││
  1637. ││ ││
  1638. ││ ││
  1639. ││ ││
  1640. ││ ││
  1641. ││ ││
  1642. ││ ││
  1643. ││ ││
  1644. ││One ││
  1645. ││Two ││
  1646. ││Three ││
  1647. │└────────────────┘│
  1648. └──────────────────┘",
  1649. _output
  1650. );
  1651. Application.End (rs);
  1652. }
  1653. [Fact]
  1654. [AutoInitShutdown]
  1655. public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
  1656. {
  1657. var menu = new MenuBar
  1658. {
  1659. Menus =
  1660. [
  1661. new MenuBarItem ("Child", new MenuItem [] { new ("_Create Child", "", null) })
  1662. ]
  1663. };
  1664. var topChild = new Toplevel ();
  1665. topChild.Add (menu);
  1666. Application.Top.Add (topChild);
  1667. Application.Begin (Application.Top);
  1668. Exception exception = Record.Exception (() => topChild.NewKeyDownEvent (KeyCode.AltMask));
  1669. Assert.Null (exception);
  1670. }
  1671. [Fact]
  1672. [TestRespondersDisposed]
  1673. public void Multi_Thread_Toplevels ()
  1674. {
  1675. Application.Init (new FakeDriver ());
  1676. Toplevel t = Application.Top;
  1677. var w = new Window ();
  1678. t.Add (w);
  1679. int count = 0, count1 = 0, count2 = 0;
  1680. bool log = false, log1 = false, log2 = false;
  1681. var fromTopStillKnowFirstIsRunning = false;
  1682. var fromTopStillKnowSecondIsRunning = false;
  1683. var fromFirstStillKnowSecondIsRunning = false;
  1684. Application.AddTimeout (
  1685. TimeSpan.FromMilliseconds (100),
  1686. () =>
  1687. {
  1688. count++;
  1689. if (count1 == 5)
  1690. {
  1691. log1 = true;
  1692. }
  1693. if (count1 == 14 && count2 == 10 && count == 15)
  1694. {
  1695. // count2 is already stopped
  1696. fromTopStillKnowFirstIsRunning = true;
  1697. }
  1698. if (count1 == 7 && count2 == 7 && count == 8)
  1699. {
  1700. fromTopStillKnowSecondIsRunning = true;
  1701. }
  1702. if (count == 30)
  1703. {
  1704. Assert.Equal (30, count);
  1705. Assert.Equal (20, count1);
  1706. Assert.Equal (10, count2);
  1707. Assert.True (log);
  1708. Assert.True (log1);
  1709. Assert.True (log2);
  1710. Assert.True (fromTopStillKnowFirstIsRunning);
  1711. Assert.True (fromTopStillKnowSecondIsRunning);
  1712. Assert.True (fromFirstStillKnowSecondIsRunning);
  1713. Application.RequestStop ();
  1714. return false;
  1715. }
  1716. return true;
  1717. }
  1718. );
  1719. t.Ready += FirstWindow;
  1720. void FirstWindow (object sender, EventArgs args)
  1721. {
  1722. var firstWindow = new Window ();
  1723. firstWindow.Ready += SecondWindow;
  1724. Application.AddTimeout (
  1725. TimeSpan.FromMilliseconds (100),
  1726. () =>
  1727. {
  1728. count1++;
  1729. if (count2 == 5)
  1730. {
  1731. log2 = true;
  1732. }
  1733. if (count2 == 4 && count1 == 5 && count == 5)
  1734. {
  1735. fromFirstStillKnowSecondIsRunning = true;
  1736. }
  1737. if (count1 == 20)
  1738. {
  1739. Assert.Equal (20, count1);
  1740. Application.RequestStop ();
  1741. return false;
  1742. }
  1743. return true;
  1744. }
  1745. );
  1746. Application.Run (firstWindow);
  1747. }
  1748. void SecondWindow (object sender, EventArgs args)
  1749. {
  1750. var testWindow = new Window ();
  1751. Application.AddTimeout (
  1752. TimeSpan.FromMilliseconds (100),
  1753. () =>
  1754. {
  1755. count2++;
  1756. if (count < 30)
  1757. {
  1758. log = true;
  1759. }
  1760. if (count2 == 10)
  1761. {
  1762. Assert.Equal (10, count2);
  1763. Application.RequestStop ();
  1764. return false;
  1765. }
  1766. return true;
  1767. }
  1768. );
  1769. Application.Run (testWindow);
  1770. }
  1771. Application.Run ();
  1772. Application.Shutdown ();
  1773. }
  1774. }