ViewTests.cs 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375
  1. using System;
  2. using System.Text;
  3. using Xunit;
  4. using Xunit.Abstractions;
  5. // Alias Console to MockConsole so we don't accidentally use Console
  6. using Console = Terminal.Gui.FakeConsole;
  7. namespace Terminal.Gui.ViewTests;
  8. public class ViewTests {
  9. readonly ITestOutputHelper output;
  10. public ViewTests (ITestOutputHelper output) => this.output = output;
  11. [Fact] [TestRespondersDisposed]
  12. public void New_Initializes ()
  13. {
  14. // Parameterless
  15. var r = new View ();
  16. Assert.NotNull (r);
  17. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  18. Assert.Equal ("View()(0,0,0,0)", r.ToString ());
  19. Assert.False (r.CanFocus);
  20. Assert.False (r.HasFocus);
  21. Assert.Equal (new Rect (0, 0, 0, 0), r.Bounds);
  22. Assert.Equal (new Rect (0, 0, 0, 0), r.Frame);
  23. Assert.Null (r.Focused);
  24. Assert.Null (r.ColorScheme);
  25. Assert.Equal (0, r.Width);
  26. Assert.Equal (0, r.Height);
  27. Assert.Equal (0, r.X);
  28. Assert.Equal (0, r.Y);
  29. Assert.False (r.IsCurrentTop);
  30. Assert.Empty (r.Id);
  31. Assert.Empty (r.Subviews);
  32. Assert.False (r.WantContinuousButtonPressed);
  33. Assert.False (r.WantMousePositionReports);
  34. Assert.Null (r.SuperView);
  35. Assert.Null (r.MostFocused);
  36. Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
  37. r.Dispose ();
  38. // Empty Rect
  39. r = new View (Rect.Empty);
  40. Assert.NotNull (r);
  41. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  42. Assert.Equal ("View()(0,0,0,0)", r.ToString ());
  43. Assert.False (r.CanFocus);
  44. Assert.False (r.HasFocus);
  45. Assert.Equal (new Rect (0, 0, 0, 0), r.Bounds);
  46. Assert.Equal (new Rect (0, 0, 0, 0), r.Frame);
  47. Assert.Null (r.Focused);
  48. Assert.Null (r.ColorScheme);
  49. Assert.Equal (0, r.Width);
  50. Assert.Equal (0, r.Height);
  51. Assert.Equal (0, r.X);
  52. Assert.Equal (0, r.Y);
  53. Assert.False (r.IsCurrentTop);
  54. Assert.Empty (r.Id);
  55. Assert.Empty (r.Subviews);
  56. Assert.False (r.WantContinuousButtonPressed);
  57. Assert.False (r.WantMousePositionReports);
  58. Assert.Null (r.SuperView);
  59. Assert.Null (r.MostFocused);
  60. Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
  61. r.Dispose ();
  62. // Rect with values
  63. r = new View (new Rect (1, 2, 3, 4));
  64. Assert.NotNull (r);
  65. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  66. Assert.Equal ("View()(1,2,3,4)", r.ToString ());
  67. Assert.False (r.CanFocus);
  68. Assert.False (r.HasFocus);
  69. Assert.Equal (new Rect (0, 0, 3, 4), r.Bounds);
  70. Assert.Equal (new Rect (1, 2, 3, 4), r.Frame);
  71. Assert.Null (r.Focused);
  72. Assert.Null (r.ColorScheme);
  73. Assert.Equal (3, r.Width);
  74. Assert.Equal (4, r.Height);
  75. Assert.Equal (1, r.X);
  76. Assert.Equal (2, r.Y);
  77. Assert.False (r.IsCurrentTop);
  78. Assert.Empty (r.Id);
  79. Assert.Empty (r.Subviews);
  80. Assert.False (r.WantContinuousButtonPressed);
  81. Assert.False (r.WantMousePositionReports);
  82. Assert.Null (r.SuperView);
  83. Assert.Null (r.MostFocused);
  84. Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
  85. r.Dispose ();
  86. // Initializes a view with a vertical direction
  87. r = new View ("Vertical View", TextDirection.TopBottom_LeftRight);
  88. Assert.NotNull (r);
  89. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  90. Assert.Equal ("View(Vertical View)(0,0,1,13)", r.ToString ());
  91. Assert.False (r.CanFocus);
  92. Assert.False (r.HasFocus);
  93. Assert.Equal (new Rect (0, 0, 1, 13), r.Bounds);
  94. Assert.Equal (new Rect (0, 0, 1, 13), r.Frame);
  95. Assert.Null (r.Focused);
  96. Assert.Null (r.ColorScheme);
  97. Assert.False (r.IsCurrentTop);
  98. Assert.Equal ("Vertical View", r.Id);
  99. Assert.Empty (r.Subviews);
  100. Assert.False (r.WantContinuousButtonPressed);
  101. Assert.False (r.WantMousePositionReports);
  102. Assert.Null (r.SuperView);
  103. Assert.Null (r.MostFocused);
  104. Assert.Equal (TextDirection.TopBottom_LeftRight, r.TextDirection);
  105. r.Dispose ();
  106. }
  107. [Fact] [TestRespondersDisposed]
  108. public void New_Methods_Return_False ()
  109. {
  110. var r = new View ();
  111. Assert.False (r.OnKeyDown (new Key { KeyCode = KeyCode.Null }));
  112. //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown }));
  113. Assert.False (r.OnKeyUp (new Key { KeyCode = KeyCode.Null }));
  114. Assert.False (r.MouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
  115. Assert.False (r.OnMouseEnter (new MouseEvent { Flags = MouseFlags.AllEvents }));
  116. Assert.False (r.OnMouseLeave (new MouseEvent { Flags = MouseFlags.AllEvents }));
  117. var v1 = new View ();
  118. Assert.False (r.OnEnter (v1));
  119. v1.Dispose ();
  120. var v2 = new View ();
  121. Assert.False (r.OnLeave (v2));
  122. v2.Dispose ();
  123. r.Dispose ();
  124. // TODO: Add more
  125. }
  126. [Fact] [TestRespondersDisposed]
  127. public void View_With_No_Difference_Between_An_Object_Initializer_And_A_Constructor ()
  128. {
  129. // Object Initializer
  130. var view = new View {
  131. X = 1,
  132. Y = 2,
  133. Width = 3,
  134. Height = 4
  135. };
  136. var super = new View (new Rect (0, 0, 10, 10));
  137. super.Add (view);
  138. super.BeginInit ();
  139. super.EndInit ();
  140. super.LayoutSubviews ();
  141. Assert.Equal (1, view.X);
  142. Assert.Equal (2, view.Y);
  143. Assert.Equal (3, view.Width);
  144. Assert.Equal (4, view.Height);
  145. Assert.False (view.Frame.IsEmpty);
  146. Assert.Equal (new Rect (1, 2, 3, 4), view.Frame);
  147. Assert.False (view.Bounds.IsEmpty);
  148. Assert.Equal (new Rect (0, 0, 3, 4), view.Bounds);
  149. view.LayoutSubviews ();
  150. Assert.Equal (1, view.X);
  151. Assert.Equal (2, view.Y);
  152. Assert.Equal (3, view.Width);
  153. Assert.Equal (4, view.Height);
  154. Assert.False (view.Frame.IsEmpty);
  155. Assert.False (view.Bounds.IsEmpty);
  156. super.Dispose ();
  157. #if DEBUG_IDISPOSABLE
  158. Assert.Empty (Responder.Instances);
  159. #endif
  160. // Default Constructor
  161. view = new View ();
  162. Assert.Equal (0, view.X);
  163. Assert.Equal (0, view.Y);
  164. Assert.Equal (0, view.Width);
  165. Assert.Equal (0, view.Height);
  166. Assert.True (view.Frame.IsEmpty);
  167. Assert.True (view.Bounds.IsEmpty);
  168. view.Dispose ();
  169. // Constructor
  170. view = new View (1, 2, "");
  171. Assert.Equal (1, view.X);
  172. Assert.Equal (2, view.Y);
  173. Assert.Equal (0, view.Width);
  174. Assert.Equal (0, view.Height);
  175. Assert.False (view.Frame.IsEmpty);
  176. Assert.True (view.Bounds.IsEmpty);
  177. view.Dispose ();
  178. // Default Constructor and post assignment equivalent to Object Initializer
  179. view = new View ();
  180. view.X = 1;
  181. view.Y = 2;
  182. view.Width = 3;
  183. view.Height = 4;
  184. super = new View (new Rect (0, 0, 10, 10));
  185. super.Add (view);
  186. super.BeginInit ();
  187. super.EndInit ();
  188. super.LayoutSubviews ();
  189. Assert.Equal (1, view.X);
  190. Assert.Equal (2, view.Y);
  191. Assert.Equal (3, view.Width);
  192. Assert.Equal (4, view.Height);
  193. Assert.False (view.Frame.IsEmpty);
  194. Assert.Equal (new Rect (1, 2, 3, 4), view.Frame);
  195. Assert.False (view.Bounds.IsEmpty);
  196. Assert.Equal (new Rect (0, 0, 3, 4), view.Bounds);
  197. super.Dispose ();
  198. }
  199. [Fact] [TestRespondersDisposed]
  200. public void Added_Removed ()
  201. {
  202. var v = new View (new Rect (0, 0, 10, 24));
  203. var t = new View ();
  204. v.Added += (s, e) => {
  205. Assert.Same (v.SuperView, e.Parent);
  206. Assert.Same (t, e.Parent);
  207. Assert.Same (v, e.Child);
  208. };
  209. v.Removed += (s, e) => {
  210. Assert.Same (t, e.Parent);
  211. Assert.Same (v, e.Child);
  212. Assert.True (v.SuperView == null);
  213. };
  214. t.Add (v);
  215. Assert.True (t.Subviews.Count == 1);
  216. t.Remove (v);
  217. Assert.True (t.Subviews.Count == 0);
  218. t.Dispose ();
  219. v.Dispose ();
  220. }
  221. [Fact] [TestRespondersDisposed]
  222. public void Initialized_Event_Comparing_With_Added_Event ()
  223. {
  224. Application.Init (new FakeDriver ());
  225. var top = new Toplevel { Id = "0" }; // Frame: 0, 0, 80, 25; Bounds: 0, 0, 80, 25
  226. var winAddedToTop = new Window { Id = "t", Width = Dim.Fill (), Height = Dim.Fill () }; // Frame: 0, 0, 80, 25; Bounds: 0, 0, 78, 23
  227. var v1AddedToWin = new View { Id = "v1", Width = Dim.Fill (), Height = Dim.Fill () }; // Frame: 1, 1, 78, 23 (because Windows has a border)
  228. var v2AddedToWin = new View { Id = "v2", Width = Dim.Fill (), Height = Dim.Fill () }; // Frame: 1, 1, 78, 23 (because Windows has a border)
  229. var svAddedTov1 = new View { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () }; // Frame: 1, 1, 78, 23 (same as it's superview v1AddedToWin)
  230. int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0;
  231. winAddedToTop.Added += (s, e) => {
  232. Assert.Equal (e.Parent.Frame.Width, winAddedToTop.Frame.Width);
  233. Assert.Equal (e.Parent.Frame.Height, winAddedToTop.Frame.Height);
  234. };
  235. v1AddedToWin.Added += (s, e) => {
  236. Assert.Equal (e.Parent.Frame.Width, v1AddedToWin.Frame.Width);
  237. Assert.Equal (e.Parent.Frame.Height, v1AddedToWin.Frame.Height);
  238. };
  239. v2AddedToWin.Added += (s, e) => {
  240. Assert.Equal (e.Parent.Frame.Width, v2AddedToWin.Frame.Width);
  241. Assert.Equal (e.Parent.Frame.Height, v2AddedToWin.Frame.Height);
  242. };
  243. svAddedTov1.Added += (s, e) => {
  244. Assert.Equal (e.Parent.Frame.Width, svAddedTov1.Frame.Width);
  245. Assert.Equal (e.Parent.Frame.Height, svAddedTov1.Frame.Height);
  246. };
  247. top.Initialized += (s, e) => {
  248. tc++;
  249. Assert.Equal (1, tc);
  250. Assert.Equal (1, wc);
  251. Assert.Equal (1, v1c);
  252. Assert.Equal (1, v2c);
  253. Assert.Equal (1, sv1c);
  254. Assert.True (top.CanFocus);
  255. Assert.True (winAddedToTop.CanFocus);
  256. Assert.False (v1AddedToWin.CanFocus);
  257. Assert.False (v2AddedToWin.CanFocus);
  258. Assert.False (svAddedTov1.CanFocus);
  259. Application.Refresh ();
  260. };
  261. winAddedToTop.Initialized += (s, e) => {
  262. wc++;
  263. Assert.Equal (top.Bounds.Width, winAddedToTop.Frame.Width);
  264. Assert.Equal (top.Bounds.Height, winAddedToTop.Frame.Height);
  265. };
  266. v1AddedToWin.Initialized += (s, e) => {
  267. v1c++;
  268. // Top.Frame: 0, 0, 80, 25; Top.Bounds: 0, 0, 80, 25
  269. // BUGBUG: This is wrong, it should be 78, 23. This test has always been broken.
  270. // in no way should the v1AddedToWin.Frame be the same as the Top.Frame/Bounds
  271. // as it is a subview of winAddedToTop, which has a border!
  272. //Assert.Equal (top.Bounds.Width, v1AddedToWin.Frame.Width);
  273. //Assert.Equal (top.Bounds.Height, v1AddedToWin.Frame.Height);
  274. };
  275. v2AddedToWin.Initialized += (s, e) => {
  276. v2c++;
  277. // Top.Frame: 0, 0, 80, 25; Top.Bounds: 0, 0, 80, 25
  278. // BUGBUG: This is wrong, it should be 78, 23. This test has always been broken.
  279. // in no way should the v2AddedToWin.Frame be the same as the Top.Frame/Bounds
  280. // as it is a subview of winAddedToTop, which has a border!
  281. //Assert.Equal (top.Bounds.Width, v2AddedToWin.Frame.Width);
  282. //Assert.Equal (top.Bounds.Height, v2AddedToWin.Frame.Height);
  283. };
  284. svAddedTov1.Initialized += (s, e) => {
  285. sv1c++;
  286. // Top.Frame: 0, 0, 80, 25; Top.Bounds: 0, 0, 80, 25
  287. // BUGBUG: This is wrong, it should be 78, 23. This test has always been broken.
  288. // in no way should the svAddedTov1.Frame be the same as the Top.Frame/Bounds
  289. // because sv1AddedTov1 is a subview of v1AddedToWin, which is a subview of
  290. // winAddedToTop, which has a border!
  291. //Assert.Equal (top.Bounds.Width, svAddedTov1.Frame.Width);
  292. //Assert.Equal (top.Bounds.Height, svAddedTov1.Frame.Height);
  293. Assert.False (svAddedTov1.CanFocus);
  294. Assert.Throws<InvalidOperationException> (() => svAddedTov1.CanFocus = true);
  295. Assert.False (svAddedTov1.CanFocus);
  296. };
  297. v1AddedToWin.Add (svAddedTov1);
  298. winAddedToTop.Add (v1AddedToWin, v2AddedToWin);
  299. top.Add (winAddedToTop);
  300. Application.Iteration += (s, a) => {
  301. Application.Refresh ();
  302. top.Running = false;
  303. };
  304. Application.Run (top);
  305. Application.Shutdown ();
  306. Assert.Equal (1, tc);
  307. Assert.Equal (1, wc);
  308. Assert.Equal (1, v1c);
  309. Assert.Equal (1, v2c);
  310. Assert.Equal (1, sv1c);
  311. Assert.True (top.CanFocus);
  312. Assert.True (winAddedToTop.CanFocus);
  313. Assert.False (v1AddedToWin.CanFocus);
  314. Assert.False (v2AddedToWin.CanFocus);
  315. Assert.False (svAddedTov1.CanFocus);
  316. v1AddedToWin.CanFocus = true;
  317. Assert.False (svAddedTov1.CanFocus); // False because sv1 was disposed and it isn't a subview of v1.
  318. }
  319. [Fact] [TestRespondersDisposed]
  320. public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically ()
  321. {
  322. Application.Init (new FakeDriver ());
  323. var t = new Toplevel { Id = "0" };
  324. var w = new Window { Id = "t", Width = Dim.Fill (), Height = Dim.Fill () };
  325. var v1 = new View { Id = "v1", Width = Dim.Fill (), Height = Dim.Fill () };
  326. var v2 = new View { Id = "v2", Width = Dim.Fill (), Height = Dim.Fill () };
  327. int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0;
  328. t.Initialized += (s, e) => {
  329. tc++;
  330. Assert.Equal (1, tc);
  331. Assert.Equal (1, wc);
  332. Assert.Equal (1, v1c);
  333. Assert.Equal (1, v2c);
  334. Assert.Equal (0, sv1c); // Added after t in the Application.Iteration.
  335. Assert.True (t.CanFocus);
  336. Assert.True (w.CanFocus);
  337. Assert.False (v1.CanFocus);
  338. Assert.False (v2.CanFocus);
  339. Application.Refresh ();
  340. };
  341. w.Initialized += (s, e) => {
  342. wc++;
  343. Assert.Equal (t.Bounds.Width, w.Frame.Width);
  344. Assert.Equal (t.Bounds.Height, w.Frame.Height);
  345. };
  346. v1.Initialized += (s, e) => {
  347. v1c++;
  348. //Assert.Equal (t.Bounds.Width, v1.Frame.Width);
  349. //Assert.Equal (t.Bounds.Height, v1.Frame.Height);
  350. };
  351. v2.Initialized += (s, e) => {
  352. v2c++;
  353. //Assert.Equal (t.Bounds.Width, v2.Frame.Width);
  354. //Assert.Equal (t.Bounds.Height, v2.Frame.Height);
  355. };
  356. w.Add (v1, v2);
  357. t.Add (w);
  358. Application.Iteration += (s, a) => {
  359. var sv1 = new View { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () };
  360. sv1.Initialized += (s, e) => {
  361. sv1c++;
  362. Assert.NotEqual (t.Frame.Width, sv1.Frame.Width);
  363. Assert.NotEqual (t.Frame.Height, sv1.Frame.Height);
  364. Assert.False (sv1.CanFocus);
  365. Assert.Throws<InvalidOperationException> (() => sv1.CanFocus = true);
  366. Assert.False (sv1.CanFocus);
  367. };
  368. v1.Add (sv1);
  369. Application.Refresh ();
  370. t.Running = false;
  371. };
  372. Application.Run (t);
  373. Application.Shutdown ();
  374. Assert.Equal (1, tc);
  375. Assert.Equal (1, wc);
  376. Assert.Equal (1, v1c);
  377. Assert.Equal (1, v2c);
  378. Assert.Equal (1, sv1c);
  379. Assert.True (t.CanFocus);
  380. Assert.True (w.CanFocus);
  381. Assert.False (v1.CanFocus);
  382. Assert.False (v2.CanFocus);
  383. }
  384. [Theory] [TestRespondersDisposed]
  385. [InlineData (1)]
  386. [InlineData (2)]
  387. [InlineData (3)]
  388. public void LabelChangeText_RendersCorrectly_Constructors (int choice)
  389. {
  390. var driver = new FakeDriver ();
  391. Application.Init (driver);
  392. try {
  393. // Create a label with a short text
  394. Label lbl;
  395. var text = "test";
  396. if (choice == 1) {
  397. // An object initializer should call the default constructor.
  398. lbl = new Label { Text = text };
  399. } else if (choice == 2) {
  400. // Calling the default constructor followed by the object initializer.
  401. lbl = new Label { Text = text };
  402. } else {
  403. // Calling the Text constructor.
  404. lbl = new Label (text);
  405. }
  406. Application.Top.Add (lbl);
  407. Application.Begin (Application.Top);
  408. // should have the initial text
  409. Assert.Equal ((Rune)'t', driver.Contents [0, 0].Rune);
  410. Assert.Equal ((Rune)'e', driver.Contents [0, 1].Rune);
  411. Assert.Equal ((Rune)'s', driver.Contents [0, 2].Rune);
  412. Assert.Equal ((Rune)'t', driver.Contents [0, 3].Rune);
  413. Assert.Equal ((Rune)' ', driver.Contents [0, 4].Rune);
  414. } finally {
  415. Application.Shutdown ();
  416. }
  417. }
  418. [Fact, AutoInitShutdown]
  419. public void Internal_Tests ()
  420. {
  421. Assert.Equal (new [] { View.Direction.Forward, View.Direction.Backward },
  422. Enum.GetValues (typeof (View.Direction)));
  423. var rect = new Rect (1, 1, 10, 1);
  424. var view = new View (rect);
  425. var top = Application.Top;
  426. top.Add (view);
  427. Assert.Equal (View.Direction.Forward, view.FocusDirection);
  428. view.FocusDirection = View.Direction.Backward;
  429. Assert.Equal (View.Direction.Backward, view.FocusDirection);
  430. Assert.Empty (view.InternalSubviews);
  431. // BUGBUG: v2 - _needsDisplay needs debugging - test disabled for now.
  432. //Assert.Equal (new Rect (new Point (0, 0), rect.Size), view._needsDisplay);
  433. Assert.True (view.LayoutNeeded);
  434. Assert.False (view.SubViewNeedsDisplay);
  435. Assert.False (view._addingView);
  436. view._addingView = true;
  437. Assert.True (view._addingView);
  438. view.BoundsToScreen (0, 0, out var rcol, out var rrow);
  439. Assert.Equal (1, rcol);
  440. Assert.Equal (1, rrow);
  441. Assert.Equal (rect, view.BoundsToScreen (view.Bounds));
  442. Assert.Equal (top.Bounds, view.ScreenClip (top.Bounds));
  443. Assert.True (view.LayoutStyle == LayoutStyle.Absolute);
  444. var runState = Application.Begin (top);
  445. // BUGBUG: This is a SetRelativeLayout test. It should be moved to SetRelativeLayoutTests.cs
  446. view.Width = Dim.Fill (); // Width should be 79 (Top.Width - 1)
  447. Assert.Equal ("Fill(0)", view.Width.ToString ());
  448. view.Height = Dim.Fill (); // Height should be 24 (Top.Height - 1)
  449. // #3127: Before: Frame was not being set when Width and Height were set to Dim.Fill()
  450. // After: Frame is set to the parent's Frame when Width and Height are set to Dim.Fill()
  451. Assert.Equal (79, view.Bounds.Width);
  452. Assert.Equal (24, view.Bounds.Height);
  453. //view.LayoutStyle = LayoutStyle.Computed;
  454. view.SetRelativeLayout (top.Bounds);
  455. Assert.Equal ("Fill(0)", view.Width.ToString ());
  456. Assert.Equal (1, view.Frame.X);
  457. Assert.Equal (1, view.Frame.Y);
  458. Assert.Equal (79, view.Frame.Width);
  459. Assert.Equal (24, view.Frame.Height);
  460. Assert.Equal (0, view.Bounds.X);
  461. Assert.Equal (0, view.Bounds.Y);
  462. Assert.Equal (79, view.Bounds.Width);
  463. Assert.Equal (24, view.Bounds.Height);
  464. // BUGBUG: This is a SetRelativeLayout test. It should be moved to SetRelativeLayoutTests.cs
  465. view.X = 0;
  466. view.Y = 0;
  467. Assert.Equal ("Absolute(0)", view.X.ToString ());
  468. Assert.Equal ("Fill(0)", view.Width.ToString ());
  469. view.SetRelativeLayout (top.Bounds);
  470. Assert.Equal (0, view.Frame.X);
  471. Assert.Equal (0, view.Frame.Y);
  472. Assert.Equal (80, view.Frame.Width);
  473. Assert.Equal (25, view.Frame.Height);
  474. Assert.Equal (0, view.Bounds.X);
  475. Assert.Equal (0, view.Bounds.Y);
  476. Assert.Equal (80, view.Bounds.Width);
  477. Assert.Equal (25, view.Bounds.Height);
  478. // BUGBUG: This is a layout test. It should be moved to LayoutTests.cs
  479. var layoutStarted = false;
  480. view.LayoutStarted += (s, e) => layoutStarted = true;
  481. view.OnLayoutStarted (null);
  482. Assert.True (layoutStarted);
  483. view.LayoutComplete += (s, e) => layoutStarted = false;
  484. view.OnLayoutComplete (null);
  485. Assert.False (layoutStarted);
  486. // This test has been moved to SetRlativeLayoutTests because it is testing
  487. // SetRelativeLayout. In addition, the old test was bogus because it was testing the wrong thing (and
  488. // because in v1 Pos.Center was broken in this regard!
  489. view.X = Pos.Center () - 41;
  490. view.Y = Pos.Center () - 13;
  491. view.SetRelativeLayout (top.Bounds);
  492. top.LayoutSubviews (); // BUGBUG: v2 - ??
  493. view.BoundsToScreen (0, 0, out rcol, out rrow);
  494. Assert.Equal (-41, rcol);
  495. Assert.Equal (-13, rrow);
  496. Application.End (runState);
  497. }
  498. [Fact, AutoInitShutdown]
  499. public void Visible_Sets_Also_Sets_Subviews ()
  500. {
  501. var button = new Button ("Click Me");
  502. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  503. win.Add (button);
  504. var top = Application.Top;
  505. top.Add (win);
  506. var iterations = 0;
  507. Application.Iteration += (s, a) => {
  508. iterations++;
  509. Assert.True (button.Visible);
  510. Assert.True (button.CanFocus);
  511. Assert.True (button.HasFocus);
  512. Assert.True (win.Visible);
  513. Assert.True (win.CanFocus);
  514. Assert.True (win.HasFocus);
  515. Assert.True (RunesCount () > 0);
  516. win.Visible = false;
  517. Assert.True (button.Visible);
  518. Assert.True (button.CanFocus);
  519. Assert.False (button.HasFocus);
  520. Assert.False (win.Visible);
  521. Assert.True (win.CanFocus);
  522. Assert.False (win.HasFocus);
  523. button.SetFocus ();
  524. Assert.False (button.HasFocus);
  525. Assert.False (win.HasFocus);
  526. win.SetFocus ();
  527. Assert.False (button.HasFocus);
  528. Assert.False (win.HasFocus);
  529. top.Draw ();
  530. Assert.True (RunesCount () == 0);
  531. win.Visible = true;
  532. win.FocusFirst ();
  533. Assert.True (button.HasFocus);
  534. Assert.True (win.HasFocus);
  535. top.Draw ();
  536. Assert.True (RunesCount () > 0);
  537. Application.RequestStop ();
  538. };
  539. Application.Run ();
  540. Assert.Equal (1, iterations);
  541. int RunesCount ()
  542. {
  543. var contents = ((FakeDriver)Application.Driver).Contents;
  544. var runesCount = 0;
  545. for (var i = 0; i < Application.Driver.Rows; i++) {
  546. for (var j = 0; j < Application.Driver.Cols; j++) {
  547. if (contents [i, j].Rune != (Rune)' ') {
  548. runesCount++;
  549. }
  550. }
  551. }
  552. return runesCount;
  553. }
  554. }
  555. [Fact, AutoInitShutdown]
  556. public void GetTopSuperView_Test ()
  557. {
  558. var v1 = new View ();
  559. var fv1 = new FrameView ();
  560. fv1.Add (v1);
  561. var tf1 = new TextField ();
  562. var w1 = new Window ();
  563. w1.Add (fv1, tf1);
  564. var top1 = new Toplevel ();
  565. top1.Add (w1);
  566. var v2 = new View ();
  567. var fv2 = new FrameView ();
  568. fv2.Add (v2);
  569. var tf2 = new TextField ();
  570. var w2 = new Window ();
  571. w2.Add (fv2, tf2);
  572. var top2 = new Toplevel ();
  573. top2.Add (w2);
  574. Assert.Equal (top1, v1.GetTopSuperView ());
  575. Assert.Equal (top2, v2.GetTopSuperView ());
  576. v1.Dispose ();
  577. fv1.Dispose ();
  578. tf1.Dispose ();
  579. w1.Dispose ();
  580. top1.Dispose ();
  581. v2.Dispose ();
  582. fv2.Dispose ();
  583. tf2.Dispose ();
  584. w2.Dispose ();
  585. top2.Dispose ();
  586. }
  587. [Fact, AutoInitShutdown]
  588. public void Clear_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
  589. {
  590. var view = new FrameView {
  591. Width = Dim.Fill (),
  592. Height = Dim.Fill ()
  593. };
  594. view.DrawContent += (s, e) => {
  595. var savedClip = Application.Driver.Clip;
  596. Application.Driver.Clip = new Rect (1, 1, view.Bounds.Width, view.Bounds.Height);
  597. for (var row = 0; row < view.Bounds.Height; row++) {
  598. Application.Driver.Move (1, row + 1);
  599. for (var col = 0; col < view.Bounds.Width; col++) {
  600. Application.Driver.AddStr ($"{col}");
  601. }
  602. }
  603. Application.Driver.Clip = savedClip;
  604. e.Cancel = true;
  605. };
  606. Application.Top.Add (view);
  607. Application.Begin (Application.Top);
  608. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  609. var expected = @"
  610. ┌──────────────────┐
  611. │012345678910111213│
  612. │012345678910111213│
  613. │012345678910111213│
  614. │012345678910111213│
  615. │012345678910111213│
  616. │012345678910111213│
  617. │012345678910111213│
  618. │012345678910111213│
  619. └──────────────────┘
  620. ";
  621. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  622. Assert.Equal (new Rect (0, 0, 20, 10), pos);
  623. view.Clear (view.Frame);
  624. expected = @"
  625. ";
  626. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  627. Assert.Equal (Rect.Empty, pos);
  628. }
  629. [Fact, AutoInitShutdown]
  630. public void Clear_Bounds_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
  631. {
  632. var view = new FrameView {
  633. Width = Dim.Fill (),
  634. Height = Dim.Fill ()
  635. };
  636. view.DrawContent += (s, e) => {
  637. var savedClip = Application.Driver.Clip;
  638. Application.Driver.Clip = new Rect (1, 1, view.Bounds.Width, view.Bounds.Height);
  639. for (var row = 0; row < view.Bounds.Height; row++) {
  640. Application.Driver.Move (1, row + 1);
  641. for (var col = 0; col < view.Bounds.Width; col++) {
  642. Application.Driver.AddStr ($"{col}");
  643. }
  644. }
  645. Application.Driver.Clip = savedClip;
  646. e.Cancel = true;
  647. };
  648. Application.Top.Add (view);
  649. Application.Begin (Application.Top);
  650. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  651. var expected = @"
  652. ┌──────────────────┐
  653. │012345678910111213│
  654. │012345678910111213│
  655. │012345678910111213│
  656. │012345678910111213│
  657. │012345678910111213│
  658. │012345678910111213│
  659. │012345678910111213│
  660. │012345678910111213│
  661. └──────────────────┘
  662. ";
  663. var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  664. Assert.Equal (new Rect (0, 0, 20, 10), pos);
  665. view.Clear (view.Frame);
  666. expected = @"
  667. ";
  668. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  669. Assert.Equal (Rect.Empty, pos);
  670. }
  671. [Fact] [TestRespondersDisposed]
  672. public void IsAdded_Added_Removed ()
  673. {
  674. var top = new Toplevel ();
  675. var view = new View ();
  676. Assert.False (view.IsAdded);
  677. top.Add (view);
  678. Assert.True (view.IsAdded);
  679. top.Remove (view);
  680. Assert.False (view.IsAdded);
  681. top.Dispose ();
  682. view.Dispose ();
  683. }
  684. [Fact, AutoInitShutdown]
  685. public void Visible_Clear_The_View_Output ()
  686. {
  687. var view = new View ("Testing visibility."); // use View, not Label to avoid AutoSize == true
  688. Assert.Equal ("Testing visibility.".Length, view.Frame.Width);
  689. Assert.Equal (1, view.Height);
  690. var win = new Window ();
  691. win.Add (view);
  692. var top = Application.Top;
  693. top.Add (win);
  694. var rs = Application.Begin (top);
  695. Assert.True (view.Visible);
  696. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  697. TestHelpers.AssertDriverContentsWithFrameAre (@"
  698. ┌────────────────────────────┐
  699. │Testing visibility. │
  700. │ │
  701. │ │
  702. └────────────────────────────┘
  703. ", output);
  704. view.Visible = false;
  705. var firstIteration = false;
  706. Application.RunIteration (ref rs, ref firstIteration);
  707. TestHelpers.AssertDriverContentsWithFrameAre (@"
  708. ┌────────────────────────────┐
  709. │ │
  710. │ │
  711. │ │
  712. └────────────────────────────┘
  713. ", output);
  714. Application.End (rs);
  715. }
  716. [Fact, AutoInitShutdown]
  717. public void DrawContentComplete_Event_Is_Always_Called ()
  718. {
  719. var viewCalled = false;
  720. var tvCalled = false;
  721. var view = new View ("View") { Width = 10, Height = 10 };
  722. view.DrawContentComplete += (s, e) => viewCalled = true;
  723. var tv = new TextView { Y = 11, Width = 10, Height = 10 };
  724. tv.DrawContentComplete += (s, e) => tvCalled = true;
  725. Application.Top.Add (view, tv);
  726. Application.Begin (Application.Top);
  727. Assert.True (viewCalled);
  728. Assert.True (tvCalled);
  729. }
  730. [Fact, AutoInitShutdown]
  731. public void GetNormalColor_ColorScheme ()
  732. {
  733. var view = new View { ColorScheme = Colors.Base };
  734. Assert.Equal (view.ColorScheme.Normal, view.GetNormalColor ());
  735. view.Enabled = false;
  736. Assert.Equal (view.ColorScheme.Disabled, view.GetNormalColor ());
  737. view.Dispose ();
  738. }
  739. [Fact, AutoInitShutdown]
  740. public void GetHotNormalColor_ColorScheme ()
  741. {
  742. var view = new View { ColorScheme = Colors.Base };
  743. Assert.Equal (view.ColorScheme.HotNormal, view.GetHotNormalColor ());
  744. view.Enabled = false;
  745. Assert.Equal (view.ColorScheme.Disabled, view.GetHotNormalColor ());
  746. view.Dispose ();
  747. }
  748. [Theory] [AutoInitShutdown]
  749. [InlineData (true)]
  750. [InlineData (false)]
  751. public void Clear_Does_Not_Spillover_Its_Parent (bool label)
  752. {
  753. var root = new View { Width = 20, Height = 10, ColorScheme = Colors.Base };
  754. var v = label ?
  755. new Label (new string ('c', 100)) {
  756. Width = Dim.Fill ()
  757. } :
  758. (View)new TextView {
  759. Height = 1,
  760. Text = new string ('c', 100),
  761. Width = Dim.Fill ()
  762. };
  763. root.Add (v);
  764. Application.Top.Add (root);
  765. var runState = Application.Begin (Application.Top);
  766. if (label) {
  767. Assert.True (v.AutoSize);
  768. Assert.False (v.CanFocus);
  769. Assert.Equal (new Rect (0, 0, 100, 1), v.Frame);
  770. } else {
  771. Assert.False (v.AutoSize);
  772. Assert.True (v.CanFocus);
  773. Assert.Equal (new Rect (0, 0, 20, 1), v.Frame);
  774. }
  775. TestHelpers.AssertDriverContentsWithFrameAre (@"
  776. cccccccccccccccccccc", output);
  777. var attributes = new [] {
  778. Colors.TopLevel.Normal,
  779. Colors.Base.Normal,
  780. Colors.Base.Focus
  781. };
  782. if (label) {
  783. TestHelpers.AssertDriverColorsAre (@"
  784. 111111111111111111110
  785. 111111111111111111110", Application.Driver, attributes);
  786. } else {
  787. TestHelpers.AssertDriverColorsAre (@"
  788. 222222222222222222220
  789. 111111111111111111110", Application.Driver, attributes);
  790. }
  791. if (label) {
  792. root.CanFocus = true;
  793. v.CanFocus = true;
  794. Assert.False (v.HasFocus);
  795. v.SetFocus ();
  796. Assert.True (v.HasFocus);
  797. Application.Refresh ();
  798. TestHelpers.AssertDriverColorsAre (@"
  799. 222222222222222222220
  800. 111111111111111111110", Application.Driver, attributes);
  801. }
  802. Application.End (runState);
  803. }
  804. [Fact, AutoInitShutdown]
  805. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Frame ()
  806. {
  807. var label = new Label ("At 0,0");
  808. var view = new DerivedView {
  809. X = 2,
  810. Y = 2,
  811. Width = 30,
  812. Height = 2,
  813. Text = "A text with some long width\n and also with two lines."
  814. };
  815. var top = Application.Top;
  816. top.Add (label, view);
  817. var runState = Application.Begin (top);
  818. top.Draw ();
  819. TestHelpers.AssertDriverContentsWithFrameAre (@"
  820. At 0,0
  821. A text with some long width
  822. and also with two lines. ", output);
  823. view.Frame = new Rect (1, 1, 10, 1);
  824. Assert.Equal (new Rect (1, 1, 10, 1), view.Frame);
  825. Assert.Equal (LayoutStyle.Absolute, view.LayoutStyle);
  826. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  827. Assert.Equal (new Rect (0, 0, 10, 1), view._needsDisplayRect);
  828. top.Draw ();
  829. TestHelpers.AssertDriverContentsWithFrameAre (@"
  830. At 0,0
  831. A text wit", output);
  832. Application.End (runState);
  833. }
  834. [Fact, AutoInitShutdown]
  835. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Pos_Dim ()
  836. {
  837. var label = new Label ("At 0,0");
  838. var view = new DerivedView {
  839. X = 2,
  840. Y = 2,
  841. Width = 30,
  842. Height = 2,
  843. Text = "A text with some long width\n and also with two lines."
  844. };
  845. var top = Application.Top;
  846. top.Add (label, view);
  847. var runState = Application.Begin (top);
  848. top.Draw ();
  849. TestHelpers.AssertDriverContentsWithFrameAre (@"
  850. At 0,0
  851. A text with some long width
  852. and also with two lines. ", output);
  853. view.X = 1;
  854. view.Y = 1;
  855. view.Width = 10;
  856. view.Height = 1;
  857. Assert.Equal (new Rect (1, 1, 10, 1), view.Frame);
  858. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  859. Assert.Equal (new Rect (0, 0, 30, 2), view._needsDisplayRect);
  860. top.Draw ();
  861. TestHelpers.AssertDriverContentsWithFrameAre (@"
  862. At 0,0
  863. A text wit", output);
  864. Application.End (runState);
  865. }
  866. [Fact, AutoInitShutdown]
  867. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Frame ()
  868. {
  869. var label = new Label ("At 0,0");
  870. var view = new DerivedView {
  871. X = 2,
  872. Y = 2,
  873. Width = 30,
  874. Height = 2,
  875. Text = "A text with some long width\n and also with two lines."
  876. };
  877. var top = Application.Top;
  878. top.Add (label, view);
  879. var runState = Application.Begin (top);
  880. view.Draw ();
  881. TestHelpers.AssertDriverContentsWithFrameAre (@"
  882. At 0,0
  883. A text with some long width
  884. and also with two lines. ", output);
  885. view.Frame = new Rect (1, 1, 10, 1);
  886. Assert.Equal (new Rect (1, 1, 10, 1), view.Frame);
  887. Assert.Equal (LayoutStyle.Absolute, view.LayoutStyle);
  888. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  889. Assert.Equal (new Rect (0, 0, 10, 1), view._needsDisplayRect);
  890. view.Draw ();
  891. TestHelpers.AssertDriverContentsWithFrameAre (@"
  892. At 0,0
  893. A text wit
  894. A text with some long width
  895. and also with two lines. ", output);
  896. Application.End (runState);
  897. }
  898. [Fact, AutoInitShutdown]
  899. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Pos_Dim ()
  900. {
  901. var label = new Label ("At 0,0");
  902. var view = new DerivedView {
  903. X = 2,
  904. Y = 2,
  905. Width = 30,
  906. Height = 2,
  907. Text = "A text with some long width\n and also with two lines."
  908. };
  909. var top = Application.Top;
  910. top.Add (label, view);
  911. var runState = Application.Begin (top);
  912. view.Draw ();
  913. TestHelpers.AssertDriverContentsWithFrameAre (@"
  914. At 0,0
  915. A text with some long width
  916. and also with two lines. ", output);
  917. view.X = 1;
  918. view.Y = 1;
  919. view.Width = 10;
  920. view.Height = 1;
  921. Assert.Equal (new Rect (1, 1, 10, 1), view.Frame);
  922. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  923. Assert.Equal (new Rect (0, 0, 30, 2), view._needsDisplayRect);
  924. view.Draw ();
  925. TestHelpers.AssertDriverContentsWithFrameAre (@"
  926. At 0,0
  927. A text wit
  928. A text with some long width
  929. and also with two lines. ", output);
  930. Application.End (runState);
  931. }
  932. [Fact, AutoInitShutdown]
  933. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Frame ()
  934. {
  935. var label = new Label ("At 0,0");
  936. var view = new DerivedView {
  937. X = 2,
  938. Y = 2,
  939. Width = 30,
  940. Height = 2,
  941. Text = "A text with some long width\n and also with two lines."
  942. };
  943. var top = Application.Top;
  944. top.Add (label, view);
  945. var runState = Application.Begin (top);
  946. TestHelpers.AssertDriverContentsWithFrameAre (@"
  947. At 0,0
  948. A text with some long width
  949. and also with two lines. ", output);
  950. view.Frame = new Rect (3, 3, 10, 1);
  951. Assert.Equal (new Rect (3, 3, 10, 1), view.Frame);
  952. Assert.Equal (LayoutStyle.Absolute, view.LayoutStyle);
  953. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  954. Assert.Equal (new Rect (0, 0, 10, 1), view._needsDisplayRect);
  955. top.Draw ();
  956. TestHelpers.AssertDriverContentsWithFrameAre (@"
  957. At 0,0
  958. A text wit", output);
  959. Application.End (runState);
  960. }
  961. [Fact, AutoInitShutdown]
  962. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Pos_Dim ()
  963. {
  964. var label = new Label ("At 0,0");
  965. var view = new DerivedView {
  966. X = 2,
  967. Y = 2,
  968. Width = 30,
  969. Height = 2,
  970. Text = "A text with some long width\n and also with two lines."
  971. };
  972. var top = Application.Top;
  973. top.Add (label, view);
  974. var runState = Application.Begin (top);
  975. top.Draw ();
  976. TestHelpers.AssertDriverContentsWithFrameAre (@"
  977. At 0,0
  978. A text with some long width
  979. and also with two lines. ", output);
  980. view.X = 3;
  981. view.Y = 3;
  982. view.Width = 10;
  983. view.Height = 1;
  984. Assert.Equal (new Rect (3, 3, 10, 1), view.Frame);
  985. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  986. Assert.Equal (new Rect (0, 0, 30, 2), view._needsDisplayRect);
  987. top.Draw ();
  988. TestHelpers.AssertDriverContentsWithFrameAre (@"
  989. At 0,0
  990. A text wit", output);
  991. Application.End (runState);
  992. }
  993. [Fact, AutoInitShutdown]
  994. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Frame ()
  995. {
  996. var label = new Label ("At 0,0");
  997. var view = new DerivedView {
  998. X = 2,
  999. Y = 2,
  1000. Width = 30,
  1001. Height = 2,
  1002. Text = "A text with some long width\n and also with two lines."
  1003. };
  1004. var top = Application.Top;
  1005. top.Add (label, view);
  1006. var runState = Application.Begin (top);
  1007. view.Draw ();
  1008. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1009. At 0,0
  1010. A text with some long width
  1011. and also with two lines. ", output);
  1012. view.Frame = new Rect (3, 3, 10, 1);
  1013. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  1014. Assert.Equal (new Rect (0, 0, 10, 1), view._needsDisplayRect);
  1015. view.Draw ();
  1016. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1017. At 0,0
  1018. A text with some long width
  1019. A text witith two lines. ", output);
  1020. Application.End (runState);
  1021. }
  1022. [Fact, AutoInitShutdown]
  1023. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Pos_Dim ()
  1024. {
  1025. var label = new Label ("At 0,0");
  1026. var view = new DerivedView {
  1027. X = 2,
  1028. Y = 2,
  1029. Width = 30,
  1030. Height = 2,
  1031. Text = "A text with some long width\n and also with two lines."
  1032. };
  1033. var top = Application.Top;
  1034. top.Add (label, view);
  1035. var runState = Application.Begin (top);
  1036. view.Draw ();
  1037. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1038. At 0,0
  1039. A text with some long width
  1040. and also with two lines. ", output);
  1041. view.X = 3;
  1042. view.Y = 3;
  1043. view.Width = 10;
  1044. view.Height = 1;
  1045. Assert.Equal (new Rect (3, 3, 10, 1), view.Frame);
  1046. Assert.Equal (new Rect (0, 0, 10, 1), view.Bounds);
  1047. Assert.Equal (new Rect (0, 0, 30, 2), view._needsDisplayRect);
  1048. view.Draw ();
  1049. TestHelpers.AssertDriverContentsWithFrameAre (@"
  1050. At 0,0
  1051. A text with some long width
  1052. A text witith two lines. ", output);
  1053. Application.End (runState);
  1054. }
  1055. [Fact, AutoInitShutdown]
  1056. public void Test_Nested_Views_With_Height_Equal_To_One ()
  1057. {
  1058. var v = new View { Width = 11, Height = 3, ColorScheme = new ColorScheme () };
  1059. var top = new View { Width = Dim.Fill (), Height = 1 };
  1060. var bottom = new View { Width = Dim.Fill (), Height = 1, Y = 2 };
  1061. top.Add (new Label ("111"));
  1062. v.Add (top);
  1063. v.Add (new LineView (Orientation.Horizontal) { Y = 1 });
  1064. bottom.Add (new Label ("222"));
  1065. v.Add (bottom);
  1066. v.BeginInit ();
  1067. v.EndInit ();
  1068. v.LayoutSubviews ();
  1069. v.Draw ();
  1070. var looksLike =
  1071. @"
  1072. 111
  1073. ───────────
  1074. 222";
  1075. TestHelpers.AssertDriverContentsAre (looksLike, output);
  1076. v.Dispose ();
  1077. top.Dispose ();
  1078. bottom.Dispose ();
  1079. }
  1080. [Fact, AutoInitShutdown]
  1081. public void Frame_Set_After_Initialize_Update_NeededDisplay ()
  1082. {
  1083. var frame = new FrameView ();
  1084. var label = new Label ("This should be the first line.") {
  1085. ColorScheme = Colors.Menu,
  1086. Width = Dim.Fill (),
  1087. X = 0, // don't overcomplicate unit tests
  1088. Y = 0
  1089. };
  1090. var button = new Button ("Press me!") {
  1091. X = 0, // don't overcomplicate unit tests
  1092. Y = 1
  1093. };
  1094. frame.Add (label, button);
  1095. frame.X = Pos.Center ();
  1096. frame.Y = Pos.Center ();
  1097. frame.Width = 40;
  1098. frame.Height = 8;
  1099. var top = Application.Top;
  1100. top.Add (frame);
  1101. var runState = Application.Begin (top);
  1102. top.LayoutComplete += (s, e) => {
  1103. Assert.Equal (new Rect (0, 0, 80, 25), top._needsDisplayRect);
  1104. };
  1105. frame.LayoutComplete += (s, e) => {
  1106. Assert.Equal (new Rect (0, 0, 40, 8), frame._needsDisplayRect);
  1107. };
  1108. label.LayoutComplete += (s, e) => {
  1109. Assert.Equal (new Rect (0, 0, 38, 1), label._needsDisplayRect);
  1110. };
  1111. button.LayoutComplete += (s, e) => {
  1112. Assert.Equal (new Rect (0, 0, 13, 1), button._needsDisplayRect);
  1113. };
  1114. Assert.True (label.AutoSize);
  1115. Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
  1116. Assert.Equal (new Rect (20, 8, 40, 8), frame.Frame);
  1117. Assert.Equal (new Rect (20, 8, 60, 16), new Rect (
  1118. frame.Frame.Left, frame.Frame.Top,
  1119. frame.Frame.Right, frame.Frame.Bottom));
  1120. Assert.Equal (new Rect (0, 0, 38, 1), label.Frame);
  1121. Assert.Equal (new Rect (0, 1, 13, 1), button.Frame); // this proves frame was set
  1122. Application.End (runState);
  1123. }
  1124. [Fact] [TestRespondersDisposed]
  1125. public void Dispose_View ()
  1126. {
  1127. var view = new View ();
  1128. Assert.NotNull (view.Margin);
  1129. Assert.NotNull (view.Border);
  1130. Assert.NotNull (view.Padding);
  1131. #if DEBUG_IDISPOSABLE
  1132. Assert.Equal (4, Responder.Instances.Count);
  1133. #endif
  1134. view.Dispose ();
  1135. Assert.Null (view.Margin);
  1136. Assert.Null (view.Border);
  1137. Assert.Null (view.Padding);
  1138. }
  1139. public class DerivedView : View {
  1140. public DerivedView () => CanFocus = true;
  1141. public bool IsKeyDown { get; set; }
  1142. public bool IsKeyPress { get; set; }
  1143. public bool IsKeyUp { get; set; }
  1144. public override string Text { get; set; }
  1145. public override bool OnKeyDown (Key keyEvent)
  1146. {
  1147. IsKeyDown = true;
  1148. return true;
  1149. }
  1150. public override bool OnProcessKeyDown (Key keyEvent)
  1151. {
  1152. IsKeyPress = true;
  1153. return true;
  1154. }
  1155. public override bool OnKeyUp (Key keyEvent)
  1156. {
  1157. IsKeyUp = true;
  1158. return true;
  1159. }
  1160. public override void OnDrawContent (Rect contentArea)
  1161. {
  1162. var idx = 0;
  1163. // BUGBUG: v2 - this should use Bounds, not Frame
  1164. for (var r = 0; r < Frame.Height; r++) {
  1165. for (var c = 0; c < Frame.Width; c++) {
  1166. if (idx < Text.Length) {
  1167. var rune = Text [idx];
  1168. if (rune != '\n') {
  1169. AddRune (c, r, (Rune)Text [idx]);
  1170. }
  1171. idx++;
  1172. if (rune == '\n') {
  1173. break;
  1174. }
  1175. }
  1176. }
  1177. }
  1178. ClearLayoutNeeded ();
  1179. ClearNeedsDisplay ();
  1180. }
  1181. }
  1182. }