TileViewTests.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. using System;
  2. using System.Linq;
  3. using Terminal.Gui;
  4. using Xunit;
  5. using Xunit.Abstractions;
  6. namespace UnitTests {
  7. public class TileViewTests {
  8. readonly ITestOutputHelper output;
  9. public TileViewTests (ITestOutputHelper output)
  10. {
  11. this.output = output;
  12. }
  13. [Fact, AutoInitShutdown]
  14. public void TestTileView_Vertical ()
  15. {
  16. var tileView = Get11By3TileView (out var line);
  17. tileView.Redraw (tileView.Bounds);
  18. string looksLike =
  19. @"
  20. 11111│22222
  21. 11111│22222
  22. │ ";
  23. TestHelpers.AssertDriverContentsAre (looksLike, output);
  24. // Keyboard movement on splitter should have no effect if it is not focused
  25. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  26. tileView.SetNeedsDisplay ();
  27. tileView.Redraw (tileView.Bounds);
  28. TestHelpers.AssertDriverContentsAre (looksLike, output);
  29. }
  30. [Fact, AutoInitShutdown]
  31. public void TestTileView_Vertical_WithBorder ()
  32. {
  33. var tileView = Get11By3TileView (out var line, true);
  34. tileView.Redraw (tileView.Bounds);
  35. string looksLike =
  36. @"
  37. ┌────┬────┐
  38. │1111│2222│
  39. └────┴────┘";
  40. TestHelpers.AssertDriverContentsAre (looksLike, output);
  41. // Keyboard movement on splitter should have no effect if it is not focused
  42. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  43. tileView.SetNeedsDisplay ();
  44. tileView.Redraw (tileView.Bounds);
  45. TestHelpers.AssertDriverContentsAre (looksLike, output);
  46. }
  47. [Fact, AutoInitShutdown]
  48. public void TestTileView_Vertical_Focused ()
  49. {
  50. var tileView = Get11By3TileView (out var line);
  51. SetInputFocusLine (tileView);
  52. tileView.Redraw (tileView.Bounds);
  53. string looksLike =
  54. @"
  55. 11111│22222
  56. 11111◊22222
  57. │ ";
  58. TestHelpers.AssertDriverContentsAre (looksLike, output);
  59. // Now while focused move the splitter 1 unit right
  60. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  61. tileView.Redraw (tileView.Bounds);
  62. looksLike =
  63. @"
  64. 111111│2222
  65. 111111◊2222
  66. │ ";
  67. TestHelpers.AssertDriverContentsAre (looksLike, output);
  68. // and 2 to the left
  69. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  70. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  71. tileView.Redraw (tileView.Bounds);
  72. looksLike =
  73. @"
  74. 1111│222222
  75. 1111◊222222
  76. │ ";
  77. TestHelpers.AssertDriverContentsAre (looksLike, output);
  78. }
  79. [Fact, AutoInitShutdown]
  80. public void TestTileView_Vertical_Focused_WithBorder ()
  81. {
  82. var tileView = Get11By3TileView (out var line, true);
  83. SetInputFocusLine (tileView);
  84. tileView.Redraw (tileView.Bounds);
  85. string looksLike =
  86. @"
  87. ┌────┬────┐
  88. │1111◊2222│
  89. └────┴────┘";
  90. TestHelpers.AssertDriverContentsAre (looksLike, output);
  91. // Now while focused move the splitter 1 unit right
  92. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  93. tileView.Redraw (tileView.Bounds);
  94. looksLike =
  95. @"
  96. ┌─────┬───┐
  97. │11111◊222│
  98. └─────┴───┘";
  99. TestHelpers.AssertDriverContentsAre (looksLike, output);
  100. // and 2 to the left
  101. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  102. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  103. tileView.Redraw (tileView.Bounds);
  104. looksLike =
  105. @"
  106. ┌───┬─────┐
  107. │111◊22222│
  108. └───┴─────┘";
  109. TestHelpers.AssertDriverContentsAre (looksLike, output);
  110. }
  111. [Fact, AutoInitShutdown]
  112. public void TestTileView_Vertical_Focused_50PercentSplit ()
  113. {
  114. var tileView = Get11By3TileView (out var line);
  115. SetInputFocusLine (tileView);
  116. tileView.SetSplitterPos(0,Pos.Percent (50));
  117. Assert.IsType<Pos.PosFactor> (tileView.SplitterDistances.ElementAt(0));
  118. tileView.Redraw (tileView.Bounds);
  119. string looksLike =
  120. @"
  121. 11111│22222
  122. 11111◊22222
  123. │ ";
  124. TestHelpers.AssertDriverContentsAre (looksLike, output);
  125. // Now while focused move the splitter 1 unit right
  126. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  127. tileView.Redraw (tileView.Bounds);
  128. looksLike =
  129. @"
  130. 111111│2222
  131. 111111◊2222
  132. │ ";
  133. TestHelpers.AssertDriverContentsAre (looksLike, output);
  134. // Even when moving the splitter location it should stay a Percentage based one
  135. Assert.IsType<Pos.PosFactor> (tileView.SplitterDistances.ElementAt(0));
  136. // and 2 to the left
  137. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  138. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  139. tileView.Redraw (tileView.Bounds);
  140. looksLike =
  141. @"
  142. 1111│222222
  143. 1111◊222222
  144. │ ";
  145. TestHelpers.AssertDriverContentsAre (looksLike, output);
  146. // Even when moving the splitter location it should stay a Percentage based one
  147. Assert.IsType<Pos.PosFactor> (tileView.SplitterDistances.ElementAt (0));
  148. }
  149. [Fact, AutoInitShutdown]
  150. public void TestTileView_Horizontal ()
  151. {
  152. var tileView = Get11By3TileView (out var line);
  153. tileView.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  154. tileView.Redraw (tileView.Bounds);
  155. string looksLike =
  156. @"
  157. 11111111111
  158. ───────────
  159. 22222222222";
  160. TestHelpers.AssertDriverContentsAre (looksLike, output);
  161. // Keyboard movement on splitter should have no effect if it is not focused
  162. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  163. tileView.SetNeedsDisplay ();
  164. tileView.Redraw (tileView.Bounds);
  165. TestHelpers.AssertDriverContentsAre (looksLike, output);
  166. }
  167. [Fact, AutoInitShutdown]
  168. public void TestTileView_Vertical_View1MinSize_Absolute ()
  169. {
  170. var tileView = Get11By3TileView (out var line);
  171. SetInputFocusLine (tileView);
  172. tileView.Tiles.ElementAt(0).MinSize = 6;
  173. // distance is too small (below 6)
  174. tileView.SetSplitterPos(0, 2);
  175. // Should bound the value to the minimum distance
  176. Assert.Equal (6, tileView.SplitterDistances.ElementAt (0));
  177. tileView.Redraw (tileView.Bounds);
  178. // so should ignore the 2 distance and stick to 6
  179. string looksLike =
  180. @"
  181. 111111│2222
  182. 111111◊2222
  183. │ ";
  184. TestHelpers.AssertDriverContentsAre (looksLike, output);
  185. // Keyboard movement on splitter should have no effect because it
  186. // would take us below the minimum splitter size
  187. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  188. tileView.SetNeedsDisplay ();
  189. tileView.Redraw (tileView.Bounds);
  190. TestHelpers.AssertDriverContentsAre (looksLike, output);
  191. // but we can continue to move the splitter right if we want
  192. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  193. tileView.SetNeedsDisplay ();
  194. tileView.Redraw (tileView.Bounds);
  195. looksLike =
  196. @"
  197. 1111111│222
  198. 1111111◊222
  199. │ ";
  200. TestHelpers.AssertDriverContentsAre (looksLike, output);
  201. }
  202. [Fact, AutoInitShutdown]
  203. public void TestTileView_Vertical_View1MinSize_Absolute_WithBorder ()
  204. {
  205. var tileView = Get11By3TileView (out var line,true);
  206. SetInputFocusLine (tileView);
  207. tileView.Tiles.ElementAt(0).MinSize = 5;
  208. // distance is too small (below 5)
  209. tileView.SetSplitterPos(0,2);
  210. // Should bound the value to the minimum distance
  211. Assert.Equal (6, tileView.SplitterDistances.ElementAt(0));
  212. tileView.Redraw (tileView.Bounds);
  213. // so should ignore the 2 distance and stick to 5
  214. string looksLike =
  215. @"
  216. ┌─────┬───┐
  217. │11111◊222│
  218. └─────┴───┘";
  219. TestHelpers.AssertDriverContentsAre (looksLike, output);
  220. // Keyboard movement on splitter should have no effect because it
  221. // would take us below the minimum splitter size
  222. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  223. tileView.SetNeedsDisplay ();
  224. tileView.Redraw (tileView.Bounds);
  225. TestHelpers.AssertDriverContentsAre (looksLike, output);
  226. // but we can continue to move the splitter right if we want
  227. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  228. tileView.SetNeedsDisplay ();
  229. tileView.Redraw (tileView.Bounds);
  230. looksLike =
  231. @"
  232. ┌──────┬──┐
  233. │111111◊22│
  234. └──────┴──┘";
  235. TestHelpers.AssertDriverContentsAre (looksLike, output);
  236. }
  237. [Fact, AutoInitShutdown]
  238. public void TestTileView_Vertical_View2MinSize_Absolute ()
  239. {
  240. var tileView = Get11By3TileView (out var line);
  241. SetInputFocusLine (tileView);
  242. tileView.Tiles.ElementAt(1).MinSize = 6;
  243. // distance leaves too little space for view2 (less than 6 would remain)
  244. tileView.SetSplitterPos(0,8);
  245. // Should bound the value to the minimum distance
  246. Assert.Equal (4, tileView.SplitterDistances.ElementAt(0));
  247. tileView.Redraw (tileView.Bounds);
  248. // so should ignore the 2 distance and stick to 6
  249. string looksLike =
  250. @"
  251. 1111│222222
  252. 1111◊222222
  253. │ ";
  254. TestHelpers.AssertDriverContentsAre (looksLike, output);
  255. // Keyboard movement on splitter should have no effect because it
  256. // would take us below the minimum splitter size
  257. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  258. tileView.SetNeedsDisplay ();
  259. tileView.Redraw (tileView.Bounds);
  260. TestHelpers.AssertDriverContentsAre (looksLike, output);
  261. // but we can continue to move the splitter left if we want
  262. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  263. tileView.SetNeedsDisplay ();
  264. tileView.Redraw (tileView.Bounds);
  265. looksLike =
  266. @"
  267. 111│2222222
  268. 111◊2222222
  269. │ ";
  270. TestHelpers.AssertDriverContentsAre (looksLike, output);
  271. }
  272. [Fact, AutoInitShutdown]
  273. public void TestTileView_Vertical_View2MinSize_Absolute_WithBorder ()
  274. {
  275. var tileView = Get11By3TileView (out var line, true);
  276. SetInputFocusLine (tileView);
  277. tileView.Tiles.ElementAt(1).MinSize = 5;
  278. // distance leaves too little space for view2 (less than 5 would remain)
  279. tileView.SetSplitterPos(0,8);
  280. // Should bound the value to the minimum distance
  281. Assert.Equal (4, tileView.SplitterDistances.ElementAt(0));
  282. tileView.Redraw (tileView.Bounds);
  283. // so should ignore the 2 distance and stick to 6
  284. string looksLike =
  285. @"
  286. ┌───┬─────┐
  287. │111◊22222│
  288. └───┴─────┘";
  289. TestHelpers.AssertDriverContentsAre (looksLike, output);
  290. // Keyboard movement on splitter should have no effect because it
  291. // would take us below the minimum splitter size
  292. line.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()));
  293. tileView.SetNeedsDisplay ();
  294. tileView.Redraw (tileView.Bounds);
  295. TestHelpers.AssertDriverContentsAre (looksLike, output);
  296. // but we can continue to move the splitter left if we want
  297. line.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
  298. tileView.SetNeedsDisplay ();
  299. tileView.Redraw (tileView.Bounds);
  300. looksLike =
  301. @"
  302. ┌──┬──────┐
  303. │11◊222222│
  304. └──┴──────┘";
  305. TestHelpers.AssertDriverContentsAre (looksLike, output);
  306. }
  307. [Fact, AutoInitShutdown]
  308. public void TestTileView_InsertPanelAtStart ()
  309. {
  310. var tileView = Get11By3TileView (out var line, true);
  311. SetInputFocusLine (tileView);
  312. tileView.InsertTile (0);
  313. tileView.Redraw (tileView.Bounds);
  314. // so should ignore the 2 distance and stick to 6
  315. string looksLike =
  316. @"
  317. ┌──┬───┬──┐
  318. │ │111│22│
  319. └──┴───┴──┘";
  320. TestHelpers.AssertDriverContentsAre (looksLike, output);
  321. }
  322. [Fact, AutoInitShutdown]
  323. public void TestTileView_InsertPanelMiddle()
  324. {
  325. var tileView = Get11By3TileView (out var line, true);
  326. SetInputFocusLine (tileView);
  327. tileView.InsertTile (1);
  328. tileView.Redraw (tileView.Bounds);
  329. // so should ignore the 2 distance and stick to 6
  330. string looksLike =
  331. @"
  332. ┌──┬───┬──┐
  333. │11│ │22│
  334. └──┴───┴──┘";
  335. TestHelpers.AssertDriverContentsAre (looksLike, output);
  336. }
  337. [Fact, AutoInitShutdown]
  338. public void TestTileView_InsertPanelAtEnd ()
  339. {
  340. var tileView = Get11By3TileView (out var line, true);
  341. SetInputFocusLine (tileView);
  342. tileView.InsertTile (2);
  343. tileView.Redraw (tileView.Bounds);
  344. // so should ignore the 2 distance and stick to 6
  345. string looksLike =
  346. @"
  347. ┌──┬───┬──┐
  348. │11│222│ │
  349. └──┴───┴──┘";
  350. TestHelpers.AssertDriverContentsAre (looksLike, output);
  351. }
  352. [Fact, AutoInitShutdown]
  353. public void TestTileView_Horizontal_Focused ()
  354. {
  355. var tileView = Get11By3TileView (out var line);
  356. tileView.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  357. SetInputFocusLine (tileView);
  358. tileView.Redraw (tileView.Bounds);
  359. string looksLike =
  360. @"
  361. 11111111111
  362. ─────◊─────
  363. 22222222222";
  364. TestHelpers.AssertDriverContentsAre (looksLike, output);
  365. // Now move splitter line down
  366. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  367. tileView.Redraw (tileView.Bounds);
  368. looksLike =
  369. @"
  370. 11111111111
  371. 11111111111
  372. ─────◊─────";
  373. TestHelpers.AssertDriverContentsAre (looksLike, output);
  374. // And 2 up
  375. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  376. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  377. tileView.Redraw (tileView.Bounds);
  378. looksLike =
  379. @"
  380. ─────◊─────
  381. 22222222222
  382. 22222222222";
  383. TestHelpers.AssertDriverContentsAre (looksLike, output);
  384. }
  385. [Fact, AutoInitShutdown]
  386. public void TestTileView_Horizontal_View1MinSize_Absolute ()
  387. {
  388. var tileView = Get11By3TileView (out var line);
  389. tileView.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  390. SetInputFocusLine (tileView);
  391. tileView.Tiles.ElementAt(0).MinSize = 1;
  392. // 0 should not be allowed because it brings us below minimum size of View1
  393. tileView.SetSplitterPos(0,0);
  394. Assert.Equal ((Pos)1, tileView.SplitterDistances.ElementAt(0));
  395. tileView.Redraw (tileView.Bounds);
  396. string looksLike =
  397. @"
  398. 11111111111
  399. ─────◊─────
  400. 22222222222";
  401. TestHelpers.AssertDriverContentsAre (looksLike, output);
  402. // Now move splitter line down (allowed
  403. line.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()));
  404. tileView.Redraw (tileView.Bounds);
  405. looksLike =
  406. @"
  407. 11111111111
  408. 11111111111
  409. ─────◊─────";
  410. TestHelpers.AssertDriverContentsAre (looksLike, output);
  411. // And up 2 (only 1 is allowed because of minimum size of 1 on view1)
  412. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  413. line.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()));
  414. tileView.Redraw (tileView.Bounds);
  415. looksLike =
  416. @"
  417. 11111111111
  418. ─────◊─────
  419. 22222222222";
  420. TestHelpers.AssertDriverContentsAre (looksLike, output);
  421. }
  422. [Fact, AutoInitShutdown]
  423. public void TestTileView_CannotSetSplitterPosToFuncEtc ()
  424. {
  425. var tileView = Get11By3TileView ();
  426. var ex = Assert.Throws<ArgumentException> (() => tileView.SetSplitterPos(0,Pos.Right (tileView)));
  427. Assert.Equal ("Only Percent and Absolute values are supported. Passed value was PosCombine", ex.Message);
  428. ex = Assert.Throws<ArgumentException> (() => tileView.SetSplitterPos(0,Pos.Function (() => 1)));
  429. Assert.Equal ("Only Percent and Absolute values are supported. Passed value was PosFunc", ex.Message);
  430. // Also not allowed because this results in a PosCombine
  431. ex = Assert.Throws<ArgumentException> (() => tileView.SetSplitterPos(0, Pos.Percent (50) - 1));
  432. Assert.Equal ("Only Percent and Absolute values are supported. Passed value was PosCombine", ex.Message);
  433. }
  434. [Fact,AutoInitShutdown]
  435. public void TestNestedContainer2LeftAnd1Right_RendersNicely()
  436. {
  437. var tileView = GetNestedContainer2Left1Right (false);
  438. Assert.Equal (20,tileView.Frame.Width);
  439. Assert.Equal (10, tileView.Tiles.ElementAt(0).View.Frame.Width);
  440. Assert.Equal (9, tileView.Tiles.ElementAt (1).View.Frame.Width);
  441. Assert.IsType<TileView> (tileView.Tiles.ElementAt (0).View);
  442. var left = (TileView)tileView.Tiles.ElementAt (0).View;
  443. Assert.Same (left.SuperView, tileView);
  444. Assert.Equal(2, left.Tiles.ElementAt (0).View.Subviews.Count);
  445. Assert.IsType<Label> (left.Tiles.ElementAt (0).View.Subviews [0]);
  446. Assert.IsType<Label> (left.Tiles.ElementAt (0).View.Subviews [1]);
  447. var onesTop = (Label)left.Tiles.ElementAt (0).View.Subviews [0];
  448. var onesBottom = (Label)left.Tiles.ElementAt (0).View.Subviews [1];
  449. Assert.Same (left.Tiles.ElementAt (0).View, onesTop.SuperView);
  450. Assert.Same (left.Tiles.ElementAt (0).View, onesBottom.SuperView);
  451. Assert.Equal (10, onesTop.Frame.Width);
  452. Assert.Equal (10, onesBottom.Frame.Width);
  453. tileView.Redraw (tileView.Bounds);
  454. string looksLike =
  455. @"
  456. 1111111111│222222222
  457. 1111111111│222222222
  458. ──────────┤
  459. │";
  460. TestHelpers.AssertDriverContentsAre (looksLike, output);
  461. }
  462. [Fact,AutoInitShutdown]
  463. public void TestNestedContainer3RightAnd1Down_RendersNicely()
  464. {
  465. var tileView = GetNestedContainer3Right1Down (false);
  466. tileView.Redraw (tileView.Bounds);
  467. string looksLike =
  468. @"
  469. 111111│222222│333333
  470. 111111│222222│333333
  471. 111111│222222│333333
  472. 111111│222222│333333
  473. 111111│222222│333333
  474. 111111│222222├──────
  475. 111111│222222│444444
  476. 111111│222222│444444
  477. 111111│222222│444444
  478. 111111│222222│444444
  479. ";
  480. TestHelpers.AssertDriverContentsAre (looksLike, output);
  481. // It looks good but lets double check the measurements incase
  482. // anything is sticking out but drawn over
  483. // 3 panels + 2 splitters
  484. Assert.Equal(5,tileView.Subviews.Count);
  485. // Check X and Widths of Tiles
  486. Assert.Equal(0,tileView.Tiles.ElementAt(0).View.Frame.X);
  487. Assert.Equal(6,tileView.Tiles.ElementAt(0).View.Frame.Width);
  488. Assert.Equal(7,tileView.Tiles.ElementAt(1).View.Frame.X);
  489. Assert.Equal(6,tileView.Tiles.ElementAt(1).View.Frame.Width);
  490. Assert.Equal(14,tileView.Tiles.ElementAt(2).View.Frame.X);
  491. Assert.Equal(6,tileView.Tiles.ElementAt(2).View.Frame.Width);
  492. // Check Y and Heights of Tiles
  493. Assert.Equal(0,tileView.Tiles.ElementAt(0).View.Frame.Y);
  494. Assert.Equal(10,tileView.Tiles.ElementAt(0).View.Frame.Height);
  495. Assert.Equal(0,tileView.Tiles.ElementAt(1).View.Frame.Y);
  496. Assert.Equal(10,tileView.Tiles.ElementAt(1).View.Frame.Height);
  497. Assert.Equal(0,tileView.Tiles.ElementAt(2).View.Frame.Y);
  498. Assert.Equal(10,tileView.Tiles.ElementAt(2).View.Frame.Height);
  499. // Check Sub containers in last panel
  500. var subSplit = (TileView)tileView.Tiles.ElementAt(2).View;
  501. Assert.Equal(0,subSplit.Tiles.ElementAt(0).View.Frame.X);
  502. Assert.Equal(6,subSplit.Tiles.ElementAt(0).View.Frame.Width);
  503. Assert.Equal(0,subSplit.Tiles.ElementAt(0).View.Frame.Y);
  504. Assert.Equal(5,subSplit.Tiles.ElementAt(0).View.Frame.Height);
  505. Assert.IsType<TextView>(subSplit.Tiles.ElementAt(0).View.Subviews.Single());
  506. Assert.Equal(0,subSplit.Tiles.ElementAt(1).View.Frame.X);
  507. Assert.Equal(6,subSplit.Tiles.ElementAt(1).View.Frame.Width);
  508. Assert.Equal(6,subSplit.Tiles.ElementAt(1).View.Frame.Y);
  509. Assert.Equal(4,subSplit.Tiles.ElementAt(1).View.Frame.Height);
  510. Assert.IsType<TextView>(subSplit.Tiles.ElementAt(1).View.Subviews.Single());
  511. }
  512. [Fact,AutoInitShutdown]
  513. public void TestNestedContainer3RightAnd1Down_WithBorder_RendersNicely()
  514. {
  515. var tileView = GetNestedContainer3Right1Down (true);
  516. tileView.Redraw (tileView.Bounds);
  517. string looksLike =
  518. @"
  519. ┌─────┬──────┬─────┐
  520. │11111│222222│33333│
  521. │11111│222222│33333│
  522. │11111│222222│33333│
  523. │11111│222222│33333│
  524. │11111│222222├─────┤
  525. │11111│222222│44444│
  526. │11111│222222│44444│
  527. │11111│222222│44444│
  528. └─────┴──────┴─────┘";
  529. TestHelpers.AssertDriverContentsAre (looksLike, output);
  530. // It looks good but lets double check the measurements incase
  531. // anything is sticking out but drawn over
  532. // 3 panels + 2 splitters
  533. Assert.Equal(5,tileView.Subviews.Count);
  534. // Check X and Widths of Tiles
  535. Assert.Equal(1,tileView.Tiles.ElementAt(0).View.Frame.X);
  536. Assert.Equal(5,tileView.Tiles.ElementAt(0).View.Frame.Width);
  537. Assert.Equal(7,tileView.Tiles.ElementAt(1).View.Frame.X);
  538. Assert.Equal(6,tileView.Tiles.ElementAt(1).View.Frame.Width);
  539. Assert.Equal(14,tileView.Tiles.ElementAt(2).View.Frame.X);
  540. Assert.Equal(5,tileView.Tiles.ElementAt(2).View.Frame.Width);
  541. // Check Y and Heights of Tiles
  542. Assert.Equal(1,tileView.Tiles.ElementAt(0).View.Frame.Y);
  543. Assert.Equal(8,tileView.Tiles.ElementAt(0).View.Frame.Height);
  544. Assert.Equal(1,tileView.Tiles.ElementAt(1).View.Frame.Y);
  545. Assert.Equal(8,tileView.Tiles.ElementAt(1).View.Frame.Height);
  546. Assert.Equal(1,tileView.Tiles.ElementAt(2).View.Frame.Y);
  547. Assert.Equal(8,tileView.Tiles.ElementAt(2).View.Frame.Height);
  548. // Check Sub containers in last panel
  549. var subSplit = (TileView)tileView.Tiles.ElementAt(2).View;
  550. Assert.Equal(0,subSplit.Tiles.ElementAt(0).View.Frame.X);
  551. Assert.Equal(5,subSplit.Tiles.ElementAt(0).View.Frame.Width);
  552. Assert.Equal(0,subSplit.Tiles.ElementAt(0).View.Frame.Y);
  553. Assert.Equal(4,subSplit.Tiles.ElementAt(0).View.Frame.Height);
  554. Assert.IsType<TextView>(subSplit.Tiles.ElementAt(0).View.Subviews.Single());
  555. Assert.Equal(0,subSplit.Tiles.ElementAt(1).View.Frame.X);
  556. Assert.Equal(5,subSplit.Tiles.ElementAt(1).View.Frame.Width);
  557. Assert.Equal(5,subSplit.Tiles.ElementAt(1).View.Frame.Y);
  558. Assert.Equal(3,subSplit.Tiles.ElementAt(1).View.Frame.Height);
  559. Assert.IsType<TextView>(subSplit.Tiles.ElementAt(1).View.Subviews.Single());
  560. }
  561. [Fact,AutoInitShutdown]
  562. public void TestNestedContainer3RightAnd1Down_WithTitledBorder_RendersNicely()
  563. {
  564. var tileView = GetNestedContainer3Right1Down (true,true);
  565. tileView.Redraw (tileView.Bounds);
  566. string looksLike =
  567. @"
  568. ┌T1───┬T2────┬T3───┐
  569. │11111│222222│33333│
  570. │11111│222222│33333│
  571. │11111│222222│33333│
  572. │11111│222222│33333│
  573. │11111│222222├T4───┤
  574. │11111│222222│44444│
  575. │11111│222222│44444│
  576. │11111│222222│44444│
  577. └─────┴──────┴─────┘";
  578. TestHelpers.AssertDriverContentsAre (looksLike, output);
  579. }
  580. [Fact, AutoInitShutdown]
  581. public void TestNestedContainer3RightAnd1Down_WithBorder_RemovingTiles ()
  582. {
  583. var tileView = GetNestedContainer3Right1Down (true);
  584. tileView.Redraw (tileView.Bounds);
  585. string looksLike =
  586. @"
  587. ┌─────┬──────┬─────┐
  588. │11111│222222│33333│
  589. │11111│222222│33333│
  590. │11111│222222│33333│
  591. │11111│222222│33333│
  592. │11111│222222├─────┤
  593. │11111│222222│44444│
  594. │11111│222222│44444│
  595. │11111│222222│44444│
  596. └─────┴──────┴─────┘";
  597. TestHelpers.AssertDriverContentsAre (looksLike, output);
  598. var toRemove = tileView.Tiles.ElementAt(1);
  599. var removed = tileView.RemoveTile (1);
  600. Assert.Same(toRemove, removed);
  601. Assert.DoesNotContain(removed,tileView.Tiles);
  602. tileView.Redraw (tileView.Bounds);
  603. looksLike =
  604. @"
  605. ┌─────────┬────────┐
  606. │111111111│33333333│
  607. │111111111│33333333│
  608. │111111111│33333333│
  609. │111111111│33333333│
  610. │111111111├────────┤
  611. │111111111│44444444│
  612. │111111111│44444444│
  613. │111111111│44444444│
  614. └─────────┴────────┘";
  615. TestHelpers.AssertDriverContentsAre (looksLike, output);
  616. // cannot remove at this index because there is only one horizontal tile left
  617. Assert.Null (tileView.RemoveTile (2));
  618. tileView.RemoveTile (0);
  619. tileView.Redraw (tileView.Bounds);
  620. looksLike =
  621. @"
  622. ┌──────────────────┐
  623. │333333333333333333│
  624. │333333333333333333│
  625. │333333333333333333│
  626. │333333333333333333│
  627. ├──────────────────┤
  628. │444444444444444444│
  629. │444444444444444444│
  630. │444444444444444444│
  631. └──────────────────┘";
  632. TestHelpers.AssertDriverContentsAre (looksLike, output);
  633. Assert.NotNull(tileView.RemoveTile (0));
  634. tileView.Redraw (tileView.Bounds);
  635. looksLike =
  636. @"
  637. ┌──────────────────┐
  638. │ │
  639. │ │
  640. │ │
  641. │ │
  642. │ │
  643. │ │
  644. │ │
  645. │ │
  646. └──────────────────┘";
  647. TestHelpers.AssertDriverContentsAre (looksLike, output);
  648. // cannot remove
  649. Assert.Null (tileView.RemoveTile (0));
  650. }
  651. [Theory,AutoInitShutdown]
  652. [InlineData(true)]
  653. [InlineData(false)]
  654. public void TestTileView_IndexOf(bool recursive)
  655. {
  656. var tv = new TileView();
  657. var lbl1 = new Label();
  658. var lbl2 = new Label();
  659. var frame = new FrameView();
  660. var sub = new Label();
  661. frame.Add(sub);
  662. // IndexOf returns -1 when view not found
  663. Assert.Equal(-1,tv.IndexOf(lbl1, recursive));
  664. Assert.Equal(-1,tv.IndexOf(lbl2, recursive));
  665. // IndexOf supports looking for Tile.View
  666. Assert.Equal(0,tv.IndexOf(tv.Tiles.ElementAt(0).View, recursive));
  667. Assert.Equal(1,tv.IndexOf(tv.Tiles.ElementAt(1).View, recursive));
  668. // IndexOf supports looking for Tile.View.Subviews
  669. tv.Tiles.ElementAt(0).View.Add(lbl1);
  670. Assert.Equal(0,tv.IndexOf(lbl1, recursive));
  671. tv.Tiles.ElementAt(1).View.Add(lbl2);
  672. Assert.Equal(1,tv.IndexOf(lbl2, recursive));
  673. // IndexOf supports looking deep into subviews only when
  674. // the recursive true value is passed
  675. tv.Tiles.ElementAt(1).View.Add(frame);
  676. if(recursive)
  677. {
  678. Assert.Equal(1,tv.IndexOf(sub, recursive));
  679. }
  680. else
  681. {
  682. Assert.Equal(-1,tv.IndexOf(sub, recursive));
  683. }
  684. }
  685. /// <summary>
  686. /// Creates a vertical orientation root container with left pane split into
  687. /// two (with horizontal splitter line).
  688. /// </summary>
  689. /// <param name="withBorder"></param>
  690. /// <returns></returns>
  691. private TileView GetNestedContainer2Left1Right(bool withBorder)
  692. {
  693. var container = GetTileView (20, 10,withBorder);
  694. Assert.True (container.TrySplitTile (0,2, out var newContainer));
  695. newContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  696. newContainer.ColorScheme = new ColorScheme ();
  697. container.ColorScheme = new ColorScheme ();
  698. container.LayoutSubviews ();
  699. return container;
  700. }
  701. /// <summary>
  702. /// Creates a vertical orientation root container with 3 tiles.
  703. /// The rightmost is split horizontally
  704. /// </summary>
  705. /// <param name="withBorder"></param>
  706. /// <returns></returns>
  707. private TileView GetNestedContainer3Right1Down(bool withBorder, bool withTitles = false)
  708. {
  709. var container =
  710. new TileView (3)
  711. {
  712. Width = 20,
  713. Height = 10,
  714. IntegratedBorder = withBorder ? BorderStyle.Single : BorderStyle.None
  715. };
  716. Assert.True (container.TrySplitTile (2,2, out var newContainer));
  717. newContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
  718. int i=0;
  719. foreach(var tile in container.Tiles.Take(2).Union(newContainer.Tiles))
  720. {
  721. i++;
  722. if(withTitles)
  723. {
  724. tile.Title = "T"+i;
  725. }
  726. tile.View.Add(new TextView{
  727. Width = Dim.Fill(),
  728. Height = Dim.Fill(),
  729. Text =
  730. string.Join('\n',
  731. Enumerable.Repeat(
  732. new string(i.ToString()[0],100)
  733. ,10).ToArray()),
  734. WordWrap = false
  735. });
  736. }
  737. newContainer.ColorScheme = new ColorScheme ();
  738. container.ColorScheme = new ColorScheme ();
  739. container.LayoutSubviews ();
  740. return container;
  741. }
  742. private LineView GetLine (TileView tileView)
  743. {
  744. return tileView.Subviews.OfType<LineView> ().Single ();
  745. }
  746. private void SetInputFocusLine (TileView tileView)
  747. {
  748. var line = GetLine (tileView);
  749. line.SetFocus ();
  750. Assert.True (line.HasFocus);
  751. }
  752. private TileView Get11By3TileView(out LineView line, bool withBorder = false)
  753. {
  754. var split = Get11By3TileView (withBorder);
  755. line = GetLine (split);
  756. return split;
  757. }
  758. private TileView Get11By3TileView (bool withBorder = false)
  759. {
  760. return GetTileView (11, 3, withBorder);
  761. }
  762. private TileView GetTileView (int width, int height, bool withBorder = false)
  763. {
  764. var container = new TileView () {
  765. Width = width,
  766. Height = height,
  767. };
  768. container.IntegratedBorder = withBorder ? BorderStyle.Single : BorderStyle.None;
  769. container.Tiles.ElementAt(0).View.Add (new Label (new string ('1', 100)) { Width = Dim.Fill(), Height = 1, AutoSize = false});
  770. container.Tiles.ElementAt (0).View.Add (new Label (new string ('1', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false,Y = 1});
  771. container.Tiles.ElementAt (1).View.Add (new Label (new string ('2', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false });
  772. container.Tiles.ElementAt (1).View.Add (new Label (new string ('2', 100)) { Width = Dim.Fill (), Height = 1, AutoSize = false,Y = 1});
  773. container.Tiles.ElementAt (0).MinSize = 0;
  774. container.Tiles.ElementAt (1).MinSize = 0;
  775. Application.Top.Add (container);
  776. container.ColorScheme = new ColorScheme ();
  777. container.LayoutSubviews ();
  778. container.BeginInit ();
  779. container.EndInit ();
  780. return container;
  781. }
  782. }
  783. }