ToplevelTests.cs 92 KB

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