ToplevelTests.cs 57 KB

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