ToplevelTests.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. using UnitTests;
  2. namespace Terminal.Gui.ViewsTests;
  3. public class ToplevelTests
  4. {
  5. public ToplevelTests ()
  6. {
  7. #if DEBUG_IDISPOSABLE
  8. View.DebugIDisposable = true;
  9. #endif
  10. }
  11. [Fact]
  12. public void Constructor_Default ()
  13. {
  14. var top = new Toplevel ();
  15. Assert.Equal (Colors.ColorSchemes ["TopLevel"], top.ColorScheme);
  16. Assert.Equal ("Fill(Absolute(0))", top.Width.ToString ());
  17. Assert.Equal ("Fill(Absolute(0))", top.Height.ToString ());
  18. Assert.False (top.Running);
  19. Assert.False (top.Modal);
  20. Assert.Null (top.MenuBar);
  21. //Assert.Null (top.StatusBar);
  22. }
  23. [Fact]
  24. public void Arrangement_Default_Is_Overlapped ()
  25. {
  26. var top = new Toplevel ();
  27. Assert.Equal (ViewArrangement.Overlapped, top.Arrangement);
  28. }
  29. [Fact]
  30. [AutoInitShutdown]
  31. public void Internal_Tests ()
  32. {
  33. var top = new Toplevel ();
  34. var eventInvoked = "";
  35. top.Loaded += (s, e) => eventInvoked = "Loaded";
  36. top.OnLoaded ();
  37. Assert.Equal ("Loaded", eventInvoked);
  38. top.Ready += (s, e) => eventInvoked = "Ready";
  39. top.OnReady ();
  40. Assert.Equal ("Ready", eventInvoked);
  41. top.Unloaded += (s, e) => eventInvoked = "Unloaded";
  42. top.OnUnloaded ();
  43. Assert.Equal ("Unloaded", eventInvoked);
  44. top.Add (new MenuBar ());
  45. Assert.NotNull (top.MenuBar);
  46. //top.Add (new StatusBar ());
  47. //Assert.NotNull (top.StatusBar);
  48. MenuBar menuBar = top.MenuBar;
  49. top.Remove (top.MenuBar);
  50. Assert.Null (top.MenuBar);
  51. Assert.NotNull (menuBar);
  52. //var statusBar = top.StatusBar;
  53. //top.Remove (top.StatusBar);
  54. //Assert.Null (top.StatusBar);
  55. //Assert.NotNull (statusBar);
  56. #if DEBUG_IDISPOSABLE
  57. Assert.False (menuBar.WasDisposed);
  58. //Assert.False (statusBar.WasDisposed);
  59. menuBar.Dispose ();
  60. //statusBar.Dispose ();
  61. Assert.True (menuBar.WasDisposed);
  62. //Assert.True (statusBar.WasDisposed);
  63. #endif
  64. Application.Begin (top);
  65. Assert.Equal (top, Application.Top);
  66. // Application.Top without menu and status bar.
  67. View supView = View.GetLocationEnsuringFullVisibility (top, 2, 2, out int nx, out int ny /*, out StatusBar sb*/);
  68. Assert.Equal (Application.Top, supView);
  69. Assert.Equal (0, nx);
  70. Assert.Equal (0, ny);
  71. //Assert.Null (sb);
  72. top.Add (new MenuBar ());
  73. Assert.NotNull (top.MenuBar);
  74. // Application.Top with a menu and without status bar.
  75. View.GetLocationEnsuringFullVisibility (top, 2, 2, out nx, out ny /*, out sb*/);
  76. Assert.Equal (0, nx);
  77. Assert.Equal (1, ny);
  78. //Assert.Null (sb);
  79. //top.Add (new StatusBar ());
  80. //Assert.NotNull (top.StatusBar);
  81. // Application.Top with a menu and status bar.
  82. View.GetLocationEnsuringFullVisibility (top, 2, 2, out nx, out ny /*, out sb*/);
  83. Assert.Equal (0, nx);
  84. // The available height is lower than the Application.Top height minus
  85. // the menu bar and status bar, then the top can go beyond the bottom
  86. // Assert.Equal (2, ny);
  87. //Assert.NotNull (sb);
  88. menuBar = top.MenuBar;
  89. top.Remove (top.MenuBar);
  90. Assert.Null (top.MenuBar);
  91. Assert.NotNull (menuBar);
  92. // Application.Top without a menu and with a status bar.
  93. View.GetLocationEnsuringFullVisibility (top, 2, 2, out nx, out ny /*, out sb*/);
  94. Assert.Equal (0, nx);
  95. // The available height is lower than the Application.Top height minus
  96. // the status bar, then the top can go beyond the bottom
  97. // Assert.Equal (2, ny);
  98. //Assert.NotNull (sb);
  99. //statusBar = top.StatusBar;
  100. //top.Remove (top.StatusBar);
  101. //Assert.Null (top.StatusBar);
  102. //Assert.NotNull (statusBar);
  103. Assert.Null (top.MenuBar);
  104. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  105. top.Add (win);
  106. top.LayoutSubViews ();
  107. // The SuperView is always the same regardless of the caller.
  108. supView = View.GetLocationEnsuringFullVisibility (win, 0, 0, out nx, out ny /*, out sb*/);
  109. Assert.Equal (Application.Top, supView);
  110. supView = View.GetLocationEnsuringFullVisibility (win, 0, 0, out nx, out ny /*, out sb*/);
  111. Assert.Equal (Application.Top, supView);
  112. // Application.Top without menu and status bar.
  113. View.GetLocationEnsuringFullVisibility (win, 0, 0, out nx, out ny /*, out sb*/);
  114. Assert.Equal (0, nx);
  115. Assert.Equal (0, ny);
  116. //Assert.Null (sb);
  117. top.Add (new MenuBar ());
  118. Assert.NotNull (top.MenuBar);
  119. // Application.Top with a menu and without status bar.
  120. View.GetLocationEnsuringFullVisibility (win, 2, 2, out nx, out ny /*, out sb*/);
  121. Assert.Equal (0, nx);
  122. Assert.Equal (1, ny);
  123. //Assert.Null (sb);
  124. top.Add (new StatusBar ());
  125. //Assert.NotNull (top.StatusBar);
  126. // Application.Top with a menu and status bar.
  127. View.GetLocationEnsuringFullVisibility (win, 30, 20, out nx, out ny /*, out sb*/);
  128. Assert.Equal (0, nx);
  129. // The available height is lower than the Application.Top height minus
  130. // the menu bar and status bar, then the top can go beyond the bottom
  131. //Assert.Equal (20, ny);
  132. //Assert.NotNull (sb);
  133. menuBar = top.MenuBar;
  134. //statusBar = top.StatusBar;
  135. top.Remove (top.MenuBar);
  136. Assert.Null (top.MenuBar);
  137. Assert.NotNull (menuBar);
  138. //top.Remove (top.StatusBar);
  139. //Assert.Null (top.StatusBar);
  140. //Assert.NotNull (statusBar);
  141. top.Remove (win);
  142. win = new () { Width = 60, Height = 15 };
  143. top.Add (win);
  144. // Application.Top without menu and status bar.
  145. View.GetLocationEnsuringFullVisibility (win, 0, 0, out nx, out ny /*, out sb*/);
  146. Assert.Equal (0, nx);
  147. Assert.Equal (0, ny);
  148. //Assert.Null (sb);
  149. top.Add (new MenuBar ());
  150. Assert.NotNull (top.MenuBar);
  151. // Application.Top with a menu and without status bar.
  152. View.GetLocationEnsuringFullVisibility (win, 2, 2, out nx, out ny /*, out sb*/);
  153. Assert.Equal (2, nx);
  154. Assert.Equal (2, ny);
  155. //Assert.Null (sb);
  156. top.Add (new StatusBar ());
  157. //Assert.NotNull (top.StatusBar);
  158. // Application.Top with a menu and status bar.
  159. View.GetLocationEnsuringFullVisibility (win, 30, 20, out nx, out ny /*, out sb*/);
  160. Assert.Equal (20, nx); // 20+60=80
  161. //Assert.Equal (9, ny); // 9+15+1(mb)=25
  162. //Assert.NotNull (sb);
  163. //Assert.Null (Toplevel._dragPosition);
  164. win.NewMouseEvent (new () { Position = new (6, 0), Flags = MouseFlags.Button1Pressed });
  165. // Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
  166. win.NewMouseEvent (new () { Position = new (6, 0), Flags = MouseFlags.Button1Released });
  167. //Assert.Null (Toplevel._dragPosition);
  168. win.CanFocus = false;
  169. win.NewMouseEvent (new () { Position = new (6, 0), Flags = MouseFlags.Button1Pressed });
  170. //Assert.Null (Toplevel._dragPosition);
  171. #if DEBUG_IDISPOSABLE
  172. Assert.False (top.MenuBar.WasDisposed);
  173. //Assert.False (top.StatusBar.WasDisposed);
  174. #endif
  175. menuBar = top.MenuBar;
  176. //statusBar = top.StatusBar;
  177. top.Dispose ();
  178. Assert.Null (top.MenuBar);
  179. //Assert.Null (top.StatusBar);
  180. Assert.NotNull (menuBar);
  181. //Assert.NotNull (statusBar);
  182. #if DEBUG_IDISPOSABLE
  183. Assert.True (menuBar.WasDisposed);
  184. //Assert.True (statusBar.WasDisposed);
  185. #endif
  186. }
  187. [Fact]
  188. public void SuperViewChanged_Should_Not_Be_Used_To_Initialize_Toplevel_Events ()
  189. {
  190. var wasAdded = false;
  191. var view = new View ();
  192. view.SuperViewChanged += SuperViewChanged;
  193. var win = new Window ();
  194. win.Add (view);
  195. Application.Init (new FakeDriver ());
  196. Toplevel top = new ();
  197. top.Add (win);
  198. Assert.True (wasAdded);
  199. Application.Shutdown ();
  200. return;
  201. void SuperViewChanged (object sender, SuperViewChangedEventArgs _)
  202. {
  203. Assert.False (wasAdded);
  204. wasAdded = true;
  205. view.SuperViewChanged -= SuperViewChanged;
  206. }
  207. }
  208. [Fact]
  209. [AutoInitShutdown]
  210. public void Mouse_Drag_On_Top_With_Superview_Null ()
  211. {
  212. var win = new Window ();
  213. Toplevel top = new ();
  214. top.Add (win);
  215. int iterations = -1;
  216. Window testWindow;
  217. Application.Iteration += (s, a) =>
  218. {
  219. iterations++;
  220. if (iterations == 0)
  221. {
  222. ((FakeDriver)Application.Driver!).SetBufferSize (15, 7);
  223. // Don't use MessageBox here; it's too complicated for this unit test; just use Window
  224. testWindow = new ()
  225. {
  226. Text = "Hello",
  227. X = 2,
  228. Y = 2,
  229. Width = 10,
  230. Height = 3,
  231. Arrangement = ViewArrangement.Movable
  232. };
  233. Application.Run (testWindow);
  234. }
  235. else if (iterations == 1)
  236. {
  237. Assert.Equal (new (2, 2), Application.Top!.Frame.Location);
  238. }
  239. else if (iterations == 2)
  240. {
  241. Assert.Null (Application.MouseGrabView);
  242. // Grab the mouse
  243. Application.RaiseMouseEvent (new () { ScreenPosition = new (3, 2), Flags = MouseFlags.Button1Pressed });
  244. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  245. Assert.Equal (new (2, 2, 10, 3), Application.Top.Frame);
  246. }
  247. else if (iterations == 3)
  248. {
  249. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  250. // Drag to left
  251. Application.RaiseMouseEvent (
  252. new ()
  253. {
  254. ScreenPosition = new (2, 2), Flags = MouseFlags.Button1Pressed
  255. | MouseFlags.ReportMousePosition
  256. });
  257. Application.LayoutAndDraw ();
  258. Assert.Equal (Application.Top.Border, Application.MouseGrabView);
  259. Assert.Equal (new (1, 2, 10, 3), Application.Top.Frame);
  260. }
  261. else if (iterations == 4)
  262. {
  263. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  264. Assert.Equal (new (1, 2), Application.Top.Frame.Location);
  265. Assert.Equal (Application.Top.Border, Application.MouseGrabView);
  266. }
  267. else if (iterations == 5)
  268. {
  269. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  270. // Drag up
  271. Application.RaiseMouseEvent (
  272. new ()
  273. {
  274. ScreenPosition = new (2, 1),
  275. Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  276. });
  277. Application.LayoutAndDraw ();
  278. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  279. Assert.Equal (new (1, 1, 10, 3), Application.Top.Frame);
  280. }
  281. else if (iterations == 6)
  282. {
  283. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  284. Assert.Equal (new (1, 1), Application.Top.Frame.Location);
  285. Assert.Equal (Application.Top.Border, Application.MouseGrabView);
  286. Assert.Equal (new (1, 1, 10, 3), Application.Top.Frame);
  287. }
  288. else if (iterations == 7)
  289. {
  290. Assert.Equal (Application.Top!.Border, Application.MouseGrabView);
  291. // Ungrab the mouse
  292. Application.RaiseMouseEvent (new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Released });
  293. Application.LayoutAndDraw ();
  294. Assert.Null (Application.MouseGrabView);
  295. }
  296. else if (iterations == 8)
  297. {
  298. Application.RequestStop ();
  299. }
  300. else if (iterations == 9)
  301. {
  302. Application.RequestStop ();
  303. }
  304. };
  305. Application.Run (top);
  306. top.Dispose ();
  307. }
  308. [Fact]
  309. [AutoInitShutdown]
  310. public void Mouse_Drag_On_Top_With_Superview_Not_Null ()
  311. {
  312. var win = new Window { X = 3, Y = 2, Width = 10, Height = 5, Arrangement = ViewArrangement.Movable };
  313. Toplevel top = new ();
  314. top.Add (win);
  315. int iterations = -1;
  316. var movex = 0;
  317. var movey = 0;
  318. var location = new Rectangle (win.Frame.X, win.Frame.Y, 7, 3);
  319. Application.Iteration += (s, a) =>
  320. {
  321. iterations++;
  322. if (iterations == 0)
  323. {
  324. ((FakeDriver)Application.Driver!).SetBufferSize (30, 10);
  325. }
  326. else if (iterations == 1)
  327. {
  328. location = win.Frame;
  329. Assert.Null (Application.MouseGrabView);
  330. // Grab the mouse
  331. Application.RaiseMouseEvent (
  332. new ()
  333. {
  334. ScreenPosition = new (win.Frame.X, win.Frame.Y), Flags = MouseFlags.Button1Pressed
  335. });
  336. Assert.Equal (win.Border, Application.MouseGrabView);
  337. }
  338. else if (iterations == 2)
  339. {
  340. Assert.Equal (win.Border, Application.MouseGrabView);
  341. // Drag to left
  342. movex = 1;
  343. movey = 0;
  344. Application.RaiseMouseEvent (
  345. new ()
  346. {
  347. ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), Flags =
  348. MouseFlags.Button1Pressed
  349. | MouseFlags.ReportMousePosition
  350. });
  351. Assert.Equal (win.Border, Application.MouseGrabView);
  352. }
  353. else if (iterations == 3)
  354. {
  355. // we should have moved +1, +0
  356. Assert.Equal (win.Border, Application.MouseGrabView);
  357. Assert.Equal (win.Border, Application.MouseGrabView);
  358. location.Offset (movex, movey);
  359. }
  360. else if (iterations == 4)
  361. {
  362. Assert.Equal (win.Border, Application.MouseGrabView);
  363. // Drag up
  364. movex = 0;
  365. movey = -1;
  366. Application.RaiseMouseEvent (
  367. new ()
  368. {
  369. ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), Flags =
  370. MouseFlags.Button1Pressed
  371. | MouseFlags.ReportMousePosition
  372. });
  373. Assert.Equal (win.Border, Application.MouseGrabView);
  374. }
  375. else if (iterations == 5)
  376. {
  377. // we should have moved +0, -1
  378. Assert.Equal (win.Border, Application.MouseGrabView);
  379. location.Offset (movex, movey);
  380. Assert.Equal (location, win.Frame);
  381. }
  382. else if (iterations == 6)
  383. {
  384. Assert.Equal (win.Border, Application.MouseGrabView);
  385. // Ungrab the mouse
  386. movex = 0;
  387. movey = 0;
  388. Application.RaiseMouseEvent (
  389. new ()
  390. {
  391. ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey),
  392. Flags = MouseFlags.Button1Released
  393. });
  394. Assert.Null (Application.MouseGrabView);
  395. }
  396. else if (iterations == 7)
  397. {
  398. Application.RequestStop ();
  399. }
  400. };
  401. Application.Run (top);
  402. top.Dispose ();
  403. }
  404. [Fact]
  405. [SetupFakeDriver]
  406. public void GetLocationThatFits_With_Border_Null_Not_Throws ()
  407. {
  408. var top = new Toplevel ();
  409. top.BeginInit ();
  410. top.EndInit ();
  411. Exception exception = Record.Exception (() => ((FakeDriver)Application.Driver!).SetBufferSize (0, 10));
  412. Assert.Null (exception);
  413. exception = Record.Exception (() => ((FakeDriver)Application.Driver!).SetBufferSize (10, 0));
  414. Assert.Null (exception);
  415. }
  416. [Fact]
  417. [AutoInitShutdown]
  418. public void PositionCursor_SetCursorVisibility_To_Invisible_If_Focused_Is_Null ()
  419. {
  420. var tf = new TextField { Width = 5, Text = "test" };
  421. var view = new View { Width = 10, Height = 10, CanFocus = true };
  422. view.Add (tf);
  423. var top = new Toplevel ();
  424. top.Add (view);
  425. Application.Begin (top);
  426. Assert.True (tf.HasFocus);
  427. Application.PositionCursor ();
  428. Application.Driver!.GetCursorVisibility (out CursorVisibility cursor);
  429. Assert.Equal (CursorVisibility.Default, cursor);
  430. view.Enabled = false;
  431. Assert.False (tf.HasFocus);
  432. Application.PositionCursor ();
  433. Application.Driver!.GetCursorVisibility (out cursor);
  434. Assert.Equal (CursorVisibility.Invisible, cursor);
  435. top.Dispose ();
  436. }
  437. [Fact]
  438. [AutoInitShutdown]
  439. public void IsLoaded_Application_Begin ()
  440. {
  441. Toplevel top = new ();
  442. Assert.False (top.IsLoaded);
  443. Application.Begin (top);
  444. Assert.True (top.IsLoaded);
  445. top.Dispose ();
  446. }
  447. [Fact]
  448. [AutoInitShutdown]
  449. public void IsLoaded_With_Sub_Toplevel_Application_Begin_NeedDisplay ()
  450. {
  451. Toplevel top = new ();
  452. var subTop = new Toplevel ();
  453. var view = new View { Frame = new (0, 0, 20, 10) };
  454. subTop.Add (view);
  455. top.Add (subTop);
  456. Assert.False (top.IsLoaded);
  457. Assert.False (subTop.IsLoaded);
  458. Assert.Equal (new (0, 0, 20, 10), view.Frame);
  459. view.SubViewLayout += ViewLayoutStarted;
  460. void ViewLayoutStarted (object sender, LayoutEventArgs e)
  461. {
  462. Assert.Equal (new (0, 0, 20, 10), view._needsDrawRect);
  463. view.SubViewLayout -= ViewLayoutStarted;
  464. }
  465. Application.Begin (top);
  466. Assert.True (top.IsLoaded);
  467. Assert.True (subTop.IsLoaded);
  468. Assert.Equal (new (0, 0, 20, 10), view.Frame);
  469. view.Frame = new (1, 3, 10, 5);
  470. Assert.Equal (new (1, 3, 10, 5), view.Frame);
  471. Assert.Equal (new (0, 0, 10, 5), view._needsDrawRect);
  472. view.Frame = new (1, 3, 10, 5);
  473. top.Layout ();
  474. Assert.Equal (new (1, 3, 10, 5), view.Frame);
  475. Assert.Equal (new (0, 0, 10, 5), view._needsDrawRect);
  476. top.Dispose ();
  477. }
  478. [Fact]
  479. [AutoInitShutdown]
  480. public void Window_Viewport_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Left_Right_And_Bottom ()
  481. {
  482. Toplevel top = new ();
  483. var window = new Window { Width = 20, Height = 3, Arrangement = ViewArrangement.Movable };
  484. RunState rsTop = Application.Begin (top);
  485. ((FakeDriver)Application.Driver!).SetBufferSize (40, 10);
  486. RunState rsWindow = Application.Begin (window);
  487. Application.LayoutAndDraw ();
  488. Assert.Equal (new (0, 0, 40, 10), top.Frame);
  489. Assert.Equal (new (0, 0, 20, 3), window.Frame);
  490. Assert.Null (Application.MouseGrabView);
  491. Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed });
  492. Assert.Equal (window.Border, Application.MouseGrabView);
  493. Application.RaiseMouseEvent (
  494. new ()
  495. {
  496. ScreenPosition = new (-11, -4), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  497. });
  498. Application.LayoutAndDraw ();
  499. Assert.Equal (new (0, 0, 40, 10), top.Frame);
  500. Assert.Equal (new (-11, -4, 20, 3), window.Frame);
  501. // Changes Top size to same size as Dialog more menu and scroll bar
  502. ((FakeDriver)Application.Driver!).SetBufferSize (20, 3);
  503. Application.RaiseMouseEvent (
  504. new ()
  505. {
  506. ScreenPosition = new (-1, -1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  507. });
  508. Application.LayoutAndDraw ();
  509. Assert.Equal (new (0, 0, 20, 3), top.Frame);
  510. Assert.Equal (new (-1, -1, 20, 3), window.Frame);
  511. // Changes Top size smaller than Dialog size
  512. ((FakeDriver)Application.Driver!).SetBufferSize (19, 2);
  513. Application.RaiseMouseEvent (
  514. new ()
  515. {
  516. ScreenPosition = new (-1, -1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  517. });
  518. Application.LayoutAndDraw ();
  519. Assert.Equal (new (0, 0, 19, 2), top.Frame);
  520. Assert.Equal (new (-1, -1, 20, 3), window.Frame);
  521. Application.RaiseMouseEvent (
  522. new ()
  523. {
  524. ScreenPosition = new (18, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  525. });
  526. Application.LayoutAndDraw ();
  527. Assert.Equal (new (0, 0, 19, 2), top.Frame);
  528. Assert.Equal (new (18, 1, 20, 3), window.Frame);
  529. // On a real app we can't go beyond the SuperView bounds
  530. Application.RaiseMouseEvent (
  531. new ()
  532. {
  533. ScreenPosition = new (19, 2), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  534. });
  535. Application.LayoutAndDraw ();
  536. Assert.Equal (new (0, 0, 19, 2), top.Frame);
  537. Assert.Equal (new (19, 2, 20, 3), window.Frame);
  538. //DriverAsserts.AssertDriverContentsWithFrameAre (@"", output);
  539. Application.End (rsWindow);
  540. Application.End (rsTop);
  541. top.Dispose ();
  542. }
  543. [Fact]
  544. [AutoInitShutdown]
  545. public void Modal_As_Top_Will_Drag_Cleanly ()
  546. {
  547. // Don't use Dialog as a Top, use a Window instead - dialog has complex layout behavior that is not needed here.
  548. var window = new Window { Width = 10, Height = 3, Arrangement = ViewArrangement.Movable };
  549. window.Add (
  550. new Label
  551. {
  552. X = Pos.Center (),
  553. Y = Pos.Center (),
  554. Width = Dim.Fill (),
  555. Height = Dim.Fill (),
  556. TextAlignment = Alignment.Center,
  557. VerticalTextAlignment = Alignment.Center,
  558. Text = "Test"
  559. }
  560. );
  561. RunState rs = Application.Begin (window);
  562. Assert.Null (Application.MouseGrabView);
  563. Assert.Equal (new (0, 0, 10, 3), window.Frame);
  564. Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed });
  565. var firstIteration = false;
  566. Application.RunIteration (ref rs, firstIteration);
  567. Assert.Equal (window.Border, Application.MouseGrabView);
  568. Assert.Equal (new (0, 0, 10, 3), window.Frame);
  569. Application.RaiseMouseEvent (
  570. new ()
  571. {
  572. ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition
  573. });
  574. firstIteration = false;
  575. Application.RunIteration (ref rs, firstIteration);
  576. Assert.Equal (window.Border, Application.MouseGrabView);
  577. Assert.Equal (new (1, 1, 10, 3), window.Frame);
  578. Application.End (rs);
  579. window.Dispose ();
  580. }
  581. [Fact]
  582. [AutoInitShutdown]
  583. public void Begin_With_Window_Sets_Size_Correctly ()
  584. {
  585. Toplevel top = new ();
  586. RunState rsTop = Application.Begin (top);
  587. ((FakeDriver)Application.Driver!).SetBufferSize (20, 20);
  588. var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
  589. Assert.Equal (new (2, 1, 15, 10), testWindow.Frame);
  590. RunState rsTestWindow = Application.Begin (testWindow);
  591. Assert.Equal (new (2, 1, 15, 10), testWindow.Frame);
  592. Application.End (rsTestWindow);
  593. Application.End (rsTop);
  594. top.Dispose ();
  595. }
  596. [Fact]
  597. [AutoInitShutdown]
  598. public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
  599. {
  600. var menu = new MenuBar
  601. {
  602. Menus =
  603. [
  604. new ("Child", new MenuItem [] { new ("_Create Child", "", null) })
  605. ]
  606. };
  607. var topChild = new Toplevel ();
  608. topChild.Add (menu);
  609. var top = new Toplevel ();
  610. top.Add (topChild);
  611. Application.Begin (top);
  612. Exception exception = Record.Exception (() => topChild.NewKeyDownEvent (KeyCode.AltMask));
  613. Assert.Null (exception);
  614. top.Dispose ();
  615. }
  616. [Fact]
  617. [TestRespondersDisposed]
  618. public void Multi_Thread_Toplevels ()
  619. {
  620. Application.Init (new FakeDriver ());
  621. Toplevel t = new ();
  622. var w = new Window ();
  623. t.Add (w);
  624. int count = 0, count1 = 0, count2 = 0;
  625. bool log = false, log1 = false, log2 = false;
  626. var fromTopStillKnowFirstIsRunning = false;
  627. var fromTopStillKnowSecondIsRunning = false;
  628. var fromFirstStillKnowSecondIsRunning = false;
  629. Application.AddTimeout (
  630. TimeSpan.FromMilliseconds (100),
  631. () =>
  632. {
  633. count++;
  634. if (count1 == 5)
  635. {
  636. log1 = true;
  637. }
  638. if (count1 == 14 && count2 == 10 && count == 15)
  639. {
  640. // count2 is already stopped
  641. fromTopStillKnowFirstIsRunning = true;
  642. }
  643. if (count1 == 7 && count2 == 7 && count == 8)
  644. {
  645. fromTopStillKnowSecondIsRunning = true;
  646. }
  647. if (count == 30)
  648. {
  649. Assert.Equal (30, count);
  650. Assert.Equal (20, count1);
  651. Assert.Equal (10, count2);
  652. Assert.True (log);
  653. Assert.True (log1);
  654. Assert.True (log2);
  655. Assert.True (fromTopStillKnowFirstIsRunning);
  656. Assert.True (fromTopStillKnowSecondIsRunning);
  657. Assert.True (fromFirstStillKnowSecondIsRunning);
  658. Application.RequestStop ();
  659. return false;
  660. }
  661. return true;
  662. }
  663. );
  664. t.Ready += FirstWindow;
  665. void FirstWindow (object sender, EventArgs args)
  666. {
  667. var firstWindow = new Window ();
  668. firstWindow.Ready += SecondWindow;
  669. Application.AddTimeout (
  670. TimeSpan.FromMilliseconds (100),
  671. () =>
  672. {
  673. count1++;
  674. if (count2 == 5)
  675. {
  676. log2 = true;
  677. }
  678. if (count2 == 4 && count1 == 5 && count == 5)
  679. {
  680. fromFirstStillKnowSecondIsRunning = true;
  681. }
  682. if (count1 == 20)
  683. {
  684. Assert.Equal (20, count1);
  685. Application.RequestStop ();
  686. return false;
  687. }
  688. return true;
  689. }
  690. );
  691. Application.Run (firstWindow);
  692. firstWindow.Dispose ();
  693. }
  694. void SecondWindow (object sender, EventArgs args)
  695. {
  696. var testWindow = new Window ();
  697. Application.AddTimeout (
  698. TimeSpan.FromMilliseconds (100),
  699. () =>
  700. {
  701. count2++;
  702. if (count < 30)
  703. {
  704. log = true;
  705. }
  706. if (count2 == 10)
  707. {
  708. Assert.Equal (10, count2);
  709. Application.RequestStop ();
  710. return false;
  711. }
  712. return true;
  713. }
  714. );
  715. Application.Run (testWindow);
  716. testWindow.Dispose ();
  717. }
  718. Application.Run (t);
  719. t.Dispose ();
  720. Application.Shutdown ();
  721. }
  722. [Fact]
  723. public void Remove_Do_Not_Dispose_MenuBar_Or_StatusBar ()
  724. {
  725. var mb = new MenuBar ();
  726. var sb = new StatusBar ();
  727. var tl = new Toplevel ();
  728. #if DEBUG
  729. Assert.False (mb.WasDisposed);
  730. Assert.False (sb.WasDisposed);
  731. #endif
  732. tl.Add (mb, sb);
  733. Assert.NotNull (tl.MenuBar);
  734. //Assert.NotNull (tl.StatusBar);
  735. #if DEBUG
  736. Assert.False (mb.WasDisposed);
  737. Assert.False (sb.WasDisposed);
  738. #endif
  739. tl.RemoveAll ();
  740. Assert.Null (tl.MenuBar);
  741. //Assert.Null (tl.StatusBar);
  742. #if DEBUG
  743. Assert.False (mb.WasDisposed);
  744. Assert.False (sb.WasDisposed);
  745. #endif
  746. }
  747. }