ScrollViewTests.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. using System.Text;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class ScrollViewTests
  5. {
  6. private readonly ITestOutputHelper _output;
  7. public ScrollViewTests (ITestOutputHelper output) { _output = output; }
  8. [Fact]
  9. public void Adding_Views ()
  10. {
  11. var sv = new ScrollView { Width = 20, Height = 10, ContentSize = new Size (30, 20) };
  12. sv.Add (
  13. new View { Width = 10, Height = 5 },
  14. new View { X = 12, Y = 7, Width = 10, Height = 5 }
  15. );
  16. Assert.Equal (new Size (30, 20), sv.ContentSize);
  17. Assert.Equal (2, sv.Subviews [0].Subviews.Count);
  18. }
  19. [Fact]
  20. [AutoInitShutdown]
  21. public void AutoHideScrollBars_False_ShowHorizontalScrollIndicator_ShowVerticalScrollIndicator ()
  22. {
  23. var sv = new ScrollView { Width = 10, Height = 10, AutoHideScrollBars = false };
  24. sv.ShowHorizontalScrollIndicator = true;
  25. sv.ShowVerticalScrollIndicator = true;
  26. Application.Top.Add (sv);
  27. Application.Begin (Application.Top);
  28. Assert.Equal (new Rectangle (0, 0, 10, 10), sv.Bounds);
  29. Assert.False (sv.AutoHideScrollBars);
  30. Assert.True (sv.ShowHorizontalScrollIndicator);
  31. Assert.True (sv.ShowVerticalScrollIndicator);
  32. sv.Draw ();
  33. TestHelpers.AssertDriverContentsAre (
  34. @"
  35. ◄├─────┤►
  36. ",
  37. _output
  38. );
  39. sv.ShowHorizontalScrollIndicator = false;
  40. Assert.Equal (new Rectangle (0, 0, 10, 10), sv.Bounds);
  41. sv.ShowVerticalScrollIndicator = true;
  42. Assert.Equal (new Rectangle (0, 0, 10, 10), sv.Bounds);
  43. Assert.False (sv.AutoHideScrollBars);
  44. Assert.False (sv.ShowHorizontalScrollIndicator);
  45. Assert.True (sv.ShowVerticalScrollIndicator);
  46. sv.Draw ();
  47. TestHelpers.AssertDriverContentsAre (
  48. @"
  49. ",
  50. _output
  51. );
  52. sv.ShowHorizontalScrollIndicator = true;
  53. sv.ShowVerticalScrollIndicator = false;
  54. Assert.False (sv.AutoHideScrollBars);
  55. Assert.True (sv.ShowHorizontalScrollIndicator);
  56. Assert.False (sv.ShowVerticalScrollIndicator);
  57. sv.Draw ();
  58. TestHelpers.AssertDriverContentsAre (
  59. @"
  60. ◄├──────┤►
  61. ",
  62. _output
  63. );
  64. sv.ShowHorizontalScrollIndicator = false;
  65. sv.ShowVerticalScrollIndicator = false;
  66. Assert.False (sv.AutoHideScrollBars);
  67. Assert.False (sv.ShowHorizontalScrollIndicator);
  68. Assert.False (sv.ShowVerticalScrollIndicator);
  69. sv.Draw ();
  70. TestHelpers.AssertDriverContentsAre (
  71. @"
  72. ",
  73. _output
  74. );
  75. }
  76. [Fact]
  77. [AutoInitShutdown]
  78. public void AutoHideScrollBars_ShowHorizontalScrollIndicator_ShowVerticalScrollIndicator ()
  79. {
  80. var sv = new ScrollView { Width = 10, Height = 10 };
  81. Application.Top.Add (sv);
  82. Application.Begin (Application.Top);
  83. Assert.True (sv.AutoHideScrollBars);
  84. Assert.False (sv.ShowHorizontalScrollIndicator);
  85. Assert.False (sv.ShowVerticalScrollIndicator);
  86. TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
  87. sv.AutoHideScrollBars = false;
  88. sv.ShowHorizontalScrollIndicator = true;
  89. sv.ShowVerticalScrollIndicator = true;
  90. sv.LayoutSubviews ();
  91. sv.Draw ();
  92. TestHelpers.AssertDriverContentsWithFrameAre (
  93. @"
  94. ◄├─────┤►
  95. ",
  96. _output
  97. );
  98. }
  99. // There are still issue with the lower right corner of the scroll view
  100. [Fact]
  101. [AutoInitShutdown]
  102. public void Clear_Window_Inside_ScrollView ()
  103. {
  104. var topLabel = new Label { X = 15, Text = "At 15,0" };
  105. var sv = new ScrollView
  106. {
  107. X = 3,
  108. Y = 3,
  109. Width = 10,
  110. Height = 10,
  111. ContentSize = new Size (23, 23),
  112. KeepContentAlwaysInViewport = false
  113. };
  114. var bottomLabel = new Label { X = 15, Y = 15, Text = "At 15,15" };
  115. Application.Top.Add (topLabel, sv, bottomLabel);
  116. Application.Begin (Application.Top);
  117. TestHelpers.AssertDriverContentsWithFrameAre (
  118. @"
  119. At 15,0
  120. ◄├┤░░░░░►
  121. At 15,15",
  122. _output
  123. );
  124. Attribute [] attributes =
  125. {
  126. Colors.ColorSchemes ["TopLevel"].Normal,
  127. Colors.ColorSchemes ["TopLevel"].Focus,
  128. Colors.ColorSchemes ["Base"].Normal
  129. };
  130. TestHelpers.AssertDriverAttributesAre (
  131. @"
  132. 00000000000000000000000
  133. 00000000000000000000000
  134. 00000000000000000000000
  135. 00000000000010000000000
  136. 00000000000010000000000
  137. 00000000000010000000000
  138. 00000000000010000000000
  139. 00000000000010000000000
  140. 00000000000010000000000
  141. 00000000000010000000000
  142. 00000000000010000000000
  143. 00000000000010000000000
  144. 00011111111110000000000
  145. 00000000000000000000000
  146. 00000000000000000000000
  147. 00000000000000000000000",
  148. null,
  149. attributes
  150. );
  151. sv.Add (new Window { X = 3, Y = 3, Width = 20, Height = 20 });
  152. Application.Refresh ();
  153. TestHelpers.AssertDriverContentsWithFrameAre (
  154. @"
  155. At 15,0
  156. ┌─────░
  157. │ ░
  158. │ ░
  159. │ ░
  160. │ ░
  161. │ ▼
  162. ◄├┤░░░░░►
  163. At 15,15",
  164. _output
  165. );
  166. TestHelpers.AssertDriverAttributesAre (
  167. @"
  168. 00000000000000000000000
  169. 00000000000000000000000
  170. 00000000000000000000000
  171. 00000000000010000000000
  172. 00000000000010000000000
  173. 00000000000010000000000
  174. 00000022222210000000000
  175. 00000022222210000000000
  176. 00000022222210000000000
  177. 00000022222210000000000
  178. 00000022222210000000000
  179. 00000022222210000000000
  180. 00011111111110000000000
  181. 00000000000000000000000
  182. 00000000000000000000000
  183. 00000000000000000000000",
  184. null,
  185. attributes
  186. );
  187. sv.ContentOffset = new Point (20, 20);
  188. Application.Refresh ();
  189. TestHelpers.AssertDriverContentsWithFrameAre (
  190. @"
  191. At 15,0
  192. │ ▲
  193. │ ░
  194. ──┘ ░
  195. ◄░░░░├─┤►
  196. At 15,15",
  197. _output
  198. );
  199. TestHelpers.AssertDriverAttributesAre (
  200. @"
  201. 00000000000000000000000
  202. 00000000000000000000000
  203. 00000000000000000000000
  204. 00022200000010000000000
  205. 00022200000010000000000
  206. 00022200000010000000000
  207. 00000000000010000000000
  208. 00000000000010000000000
  209. 00000000000010000000000
  210. 00000000000010000000000
  211. 00000000000010000000000
  212. 00000000000010000000000
  213. 00011111111110000000000
  214. 00000000000000000000000
  215. 00000000000000000000000
  216. 00000000000000000000000",
  217. null,
  218. attributes
  219. );
  220. }
  221. [Fact]
  222. public void Constructors_Defaults ()
  223. {
  224. var sv = new ScrollView ();
  225. Assert.Equal (LayoutStyle.Absolute, sv.LayoutStyle);
  226. Assert.True (sv.CanFocus);
  227. Assert.Equal (new Rectangle (0, 0, 0, 0), sv.Frame);
  228. Assert.Equal (Rectangle.Empty, sv.Frame);
  229. Assert.Equal (Point.Empty, sv.ContentOffset);
  230. Assert.Equal (Size.Empty, sv.ContentSize);
  231. Assert.True (sv.AutoHideScrollBars);
  232. Assert.True (sv.KeepContentAlwaysInViewport);
  233. sv = new ScrollView { X = 1, Y = 2, Width = 20, Height = 10 };
  234. Assert.Equal (LayoutStyle.Absolute, sv.LayoutStyle);
  235. Assert.True (sv.CanFocus);
  236. Assert.Equal (new Rectangle (1, 2, 20, 10), sv.Frame);
  237. Assert.Equal (Point.Empty, sv.ContentOffset);
  238. Assert.Equal (Size.Empty, sv.ContentSize);
  239. Assert.True (sv.AutoHideScrollBars);
  240. Assert.True (sv.KeepContentAlwaysInViewport);
  241. }
  242. [Fact]
  243. [SetupFakeDriver]
  244. public void ContentBottomRightCorner_Draw ()
  245. {
  246. ((FakeDriver)Application.Driver).SetBufferSize (30, 30);
  247. var top = new View { Width = 30, Height = 30, ColorScheme = new ColorScheme { Normal = Attribute.Default } };
  248. var size = new Size { Width = 20, Height = 10 };
  249. var sv = new ScrollView
  250. {
  251. X = 1,
  252. Y = 1,
  253. Width = 10,
  254. Height = 5,
  255. ContentSize = size,
  256. ColorScheme = new ColorScheme { Normal = new Attribute (Color.Red, Color.Green) }
  257. };
  258. string text = null;
  259. for (var i = 0; i < size.Height; i++)
  260. {
  261. text += "*".Repeat (size.Width);
  262. if (i < size.Height)
  263. {
  264. text += '\n';
  265. }
  266. }
  267. var view = new View
  268. {
  269. Width = size.Width,
  270. Height = size.Height,
  271. ColorScheme = new ColorScheme { Normal = new Attribute (Color.Blue, Color.Yellow) },
  272. AutoSize = true,
  273. Text = text
  274. };
  275. sv.Add (view);
  276. top.Add (sv);
  277. top.BeginInit ();
  278. top.EndInit ();
  279. top.LayoutSubviews ();
  280. top.Draw ();
  281. View contentBottomRightCorner = sv.Subviews.First (v => v is ScrollBarView.ContentBottomRightCorner);
  282. Assert.True (contentBottomRightCorner is ScrollBarView.ContentBottomRightCorner);
  283. Assert.True (contentBottomRightCorner.Visible);
  284. TestHelpers.AssertDriverContentsWithFrameAre (
  285. @"
  286. *********▲
  287. *********┬
  288. *********┴
  289. *********▼
  290. ◄├──┤░░░► ",
  291. _output
  292. );
  293. Attribute [] attrs = { Attribute.Default, new (Color.Red, Color.Green), new (Color.Blue, Color.Yellow) };
  294. TestHelpers.AssertDriverAttributesAre (
  295. @"
  296. 000000000000
  297. 022222222210
  298. 022222222210
  299. 022222222210
  300. 022222222210
  301. 011111111110
  302. 000000000000",
  303. null,
  304. attrs
  305. );
  306. }
  307. [Fact]
  308. [AutoInitShutdown]
  309. public void
  310. ContentOffset_ContentSize_AutoHideScrollBars_ShowHorizontalScrollIndicator_ShowVerticalScrollIndicator ()
  311. {
  312. var sv = new ScrollView
  313. {
  314. Width = 10, Height = 10, ContentSize = new Size (50, 50), ContentOffset = new Point (25, 25)
  315. };
  316. Application.Top.Add (sv);
  317. Application.Begin (Application.Top);
  318. Assert.Equal (-25, sv.ContentOffset.X);
  319. Assert.Equal (-25, sv.ContentOffset.Y);
  320. Assert.Equal (50, sv.ContentSize.Width);
  321. Assert.Equal (50, sv.ContentSize.Height);
  322. Assert.True (sv.AutoHideScrollBars);
  323. Assert.True (sv.ShowHorizontalScrollIndicator);
  324. Assert.True (sv.ShowVerticalScrollIndicator);
  325. TestHelpers.AssertDriverContentsWithFrameAre (
  326. @"
  327. ◄░░░├─┤░►
  328. ",
  329. _output
  330. );
  331. }
  332. [Fact]
  333. [AutoInitShutdown]
  334. public void ContentSize_AutoHideScrollBars_ShowHorizontalScrollIndicator_ShowVerticalScrollIndicator ()
  335. {
  336. var sv = new ScrollView { Width = 10, Height = 10, ContentSize = new Size (50, 50) };
  337. Application.Top.Add (sv);
  338. Application.Begin (Application.Top);
  339. Assert.Equal (50, sv.ContentSize.Width);
  340. Assert.Equal (50, sv.ContentSize.Height);
  341. Assert.True (sv.AutoHideScrollBars);
  342. Assert.True (sv.ShowHorizontalScrollIndicator);
  343. Assert.True (sv.ShowVerticalScrollIndicator);
  344. TestHelpers.AssertDriverContentsWithFrameAre (
  345. @"
  346. ◄├┤░░░░░►
  347. ",
  348. _output
  349. );
  350. }
  351. [Fact]
  352. [AutoInitShutdown]
  353. public void DrawTextFormatter_Respects_The_Clip_Bounds ()
  354. {
  355. var rule = "0123456789";
  356. var size = new Size (40, 40);
  357. var view = new View { Frame = new Rectangle (Point.Empty, size) };
  358. view.Add (
  359. new Label
  360. {
  361. AutoSize = false, Width = Dim.Fill (), Height = 1, Text = rule.Repeat (size.Width / rule.Length)
  362. }
  363. );
  364. view.Add (
  365. new Label
  366. {
  367. AutoSize = false,
  368. Height = Dim.Fill (),
  369. Width = 1,
  370. Text = rule.Repeat (size.Height / rule.Length),
  371. TextDirection = TextDirection.TopBottom_LeftRight
  372. }
  373. );
  374. view.Add (new Label { X = 1, Y = 1, Text = "[ Press me! ]" });
  375. var scrollView = new ScrollView
  376. {
  377. X = 1,
  378. Y = 1,
  379. Width = 15,
  380. Height = 10,
  381. ContentSize = size,
  382. ShowHorizontalScrollIndicator = true,
  383. ShowVerticalScrollIndicator = true
  384. };
  385. scrollView.Add (view);
  386. var win = new Window { X = 1, Y = 1, Width = 20, Height = 14 };
  387. win.Add (scrollView);
  388. Application.Top.Add (win);
  389. Application.Begin (Application.Top);
  390. var expected = @"
  391. ┌──────────────────┐
  392. │ │
  393. │ 01234567890123▲ │
  394. │ 1[ Press me! ]┬ │
  395. │ 2 │ │
  396. │ 3 ┴ │
  397. │ 4 ░ │
  398. │ 5 ░ │
  399. │ 6 ░ │
  400. │ 7 ░ │
  401. │ 8 ▼ │
  402. │ ◄├───┤░░░░░░░► │
  403. │ │
  404. └──────────────────┘
  405. "
  406. ;
  407. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  408. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  409. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  410. Application.Top.Draw ();
  411. expected = @"
  412. ┌──────────────────┐
  413. │ │
  414. │ 12345678901234▲ │
  415. │ [ Press me! ] ┬ │
  416. │ │ │
  417. │ ┴ │
  418. │ ░ │
  419. │ ░ │
  420. │ ░ │
  421. │ ░ │
  422. │ ▼ │
  423. │ ◄├───┤░░░░░░░► │
  424. │ │
  425. └──────────────────┘
  426. "
  427. ;
  428. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  429. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  430. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  431. Application.Top.Draw ();
  432. expected = @"
  433. ┌──────────────────┐
  434. │ │
  435. │ 23456789012345▲ │
  436. │ Press me! ] ┬ │
  437. │ │ │
  438. │ ┴ │
  439. │ ░ │
  440. │ ░ │
  441. │ ░ │
  442. │ ░ │
  443. │ ▼ │
  444. │ ◄├────┤░░░░░░► │
  445. │ │
  446. └──────────────────┘
  447. "
  448. ;
  449. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  450. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  451. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  452. Application.Top.Draw ();
  453. expected = @"
  454. ┌──────────────────┐
  455. │ │
  456. │ 34567890123456▲ │
  457. │ Press me! ] ┬ │
  458. │ │ │
  459. │ ┴ │
  460. │ ░ │
  461. │ ░ │
  462. │ ░ │
  463. │ ░ │
  464. │ ▼ │
  465. │ ◄├────┤░░░░░░► │
  466. │ │
  467. └──────────────────┘
  468. "
  469. ;
  470. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  471. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  472. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  473. Application.Top.Draw ();
  474. expected = @"
  475. ┌──────────────────┐
  476. │ │
  477. │ 45678901234567▲ │
  478. │ ress me! ] ┬ │
  479. │ │ │
  480. │ ┴ │
  481. │ ░ │
  482. │ ░ │
  483. │ ░ │
  484. │ ░ │
  485. │ ▼ │
  486. │ ◄░├───┤░░░░░░► │
  487. │ │
  488. └──────────────────┘
  489. "
  490. ;
  491. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  492. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  493. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  494. Application.Top.Draw ();
  495. expected = @"
  496. ┌──────────────────┐
  497. │ │
  498. │ 56789012345678▲ │
  499. │ ess me! ] ┬ │
  500. │ │ │
  501. │ ┴ │
  502. │ ░ │
  503. │ ░ │
  504. │ ░ │
  505. │ ░ │
  506. │ ▼ │
  507. │ ◄░├────┤░░░░░► │
  508. │ │
  509. └──────────────────┘
  510. "
  511. ;
  512. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  513. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  514. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  515. Application.Top.Draw ();
  516. expected = @"
  517. ┌──────────────────┐
  518. │ │
  519. │ 67890123456789▲ │
  520. │ ss me! ] ┬ │
  521. │ │ │
  522. │ ┴ │
  523. │ ░ │
  524. │ ░ │
  525. │ ░ │
  526. │ ░ │
  527. │ ▼ │
  528. │ ◄░├────┤░░░░░► │
  529. │ │
  530. └──────────────────┘
  531. "
  532. ;
  533. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  534. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  535. Assert.True (scrollView.OnKeyDown (Key.CursorRight));
  536. Application.Top.Draw ();
  537. expected = @"
  538. ┌──────────────────┐
  539. │ │
  540. │ 78901234567890▲ │
  541. │ s me! ] ┬ │
  542. │ │ │
  543. │ ┴ │
  544. │ ░ │
  545. │ ░ │
  546. │ ░ │
  547. │ ░ │
  548. │ ▼ │
  549. │ ◄░░├───┤░░░░░► │
  550. │ │
  551. └──────────────────┘
  552. ";
  553. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  554. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  555. Assert.True (scrollView.OnKeyDown (Key.End.WithCtrl));
  556. Application.Top.Draw ();
  557. expected = @"
  558. ┌──────────────────┐
  559. │ │
  560. │ 67890123456789▲ │
  561. │ ┬ │
  562. │ │ │
  563. │ ┴ │
  564. │ ░ │
  565. │ ░ │
  566. │ ░ │
  567. │ ░ │
  568. │ ▼ │
  569. │ ◄░░░░░░░├───┤► │
  570. │ │
  571. └──────────────────┘
  572. ";
  573. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  574. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  575. Assert.True (scrollView.OnKeyDown (Key.Home.WithCtrl));
  576. Assert.True (scrollView.OnKeyDown (Key.CursorDown));
  577. Application.Top.Draw ();
  578. expected = @"
  579. ┌──────────────────┐
  580. │ │
  581. │ 1[ Press me! ]▲ │
  582. │ 2 ┬ │
  583. │ 3 │ │
  584. │ 4 ┴ │
  585. │ 5 ░ │
  586. │ 6 ░ │
  587. │ 7 ░ │
  588. │ 8 ░ │
  589. │ 9 ▼ │
  590. │ ◄├───┤░░░░░░░► │
  591. │ │
  592. └──────────────────┘
  593. ";
  594. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  595. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  596. Assert.True (scrollView.OnKeyDown (Key.CursorDown));
  597. Application.Top.Draw ();
  598. expected = @"
  599. ┌──────────────────┐
  600. │ │
  601. │ 2 ▲ │
  602. │ 3 ┬ │
  603. │ 4 │ │
  604. │ 5 ┴ │
  605. │ 6 ░ │
  606. │ 7 ░ │
  607. │ 8 ░ │
  608. │ 9 ░ │
  609. │ 0 ▼ │
  610. │ ◄├───┤░░░░░░░► │
  611. │ │
  612. └──────────────────┘
  613. ";
  614. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  615. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  616. Assert.True (scrollView.OnKeyDown (Key.CursorDown));
  617. Application.Top.Draw ();
  618. expected = @"
  619. ┌──────────────────┐
  620. │ │
  621. │ 3 ▲ │
  622. │ 4 ┬ │
  623. │ 5 │ │
  624. │ 6 ┴ │
  625. │ 7 ░ │
  626. │ 8 ░ │
  627. │ 9 ░ │
  628. │ 0 ░ │
  629. │ 1 ▼ │
  630. │ ◄├───┤░░░░░░░► │
  631. │ │
  632. └──────────────────┘
  633. ";
  634. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  635. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  636. Assert.True (scrollView.OnKeyDown (Key.End));
  637. Application.Top.Draw ();
  638. expected = @"
  639. ┌──────────────────┐
  640. │ │
  641. │ 1 ▲ │
  642. │ 2 ░ │
  643. │ 3 ░ │
  644. │ 4 ░ │
  645. │ 5 ░ │
  646. │ 6 ░ │
  647. │ 7 ┬ │
  648. │ 8 ┴ │
  649. │ 9 ▼ │
  650. │ ◄├───┤░░░░░░░► │
  651. │ │
  652. └──────────────────┘
  653. ";
  654. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  655. Assert.Equal (new Rectangle (1, 1, 21, 14), pos);
  656. }
  657. // There still have an issue with lower right corner of the scroll view
  658. [Fact]
  659. [AutoInitShutdown]
  660. public void Frame_And_Labels_Does_Not_Overspill_ScrollView ()
  661. {
  662. var sv = new ScrollView
  663. {
  664. X = 3,
  665. Y = 3,
  666. Width = 10,
  667. Height = 10,
  668. ContentSize = new Size (50, 50)
  669. };
  670. for (var i = 0; i < 8; i++)
  671. {
  672. sv.Add (new CustomButton ("█", $"Button {i}", 20, 3) { Y = i * 3 });
  673. }
  674. Application.Top.Add (sv);
  675. Application.Begin (Application.Top);
  676. TestHelpers.AssertDriverContentsWithFrameAre (
  677. @"
  678. █████████▲
  679. ██████But┬
  680. █████████┴
  681. ┌────────░
  682. │ But░
  683. └────────░
  684. ┌────────░
  685. │ But░
  686. └────────▼
  687. ◄├┤░░░░░► ",
  688. _output
  689. );
  690. sv.ContentOffset = new Point (5, 5);
  691. sv.LayoutSubviews ();
  692. Application.Refresh ();
  693. TestHelpers.AssertDriverContentsWithFrameAre (
  694. @"
  695. ─────────▲
  696. ─────────┬
  697. Button 2│
  698. ─────────┴
  699. ─────────░
  700. Button 3░
  701. ─────────░
  702. ─────────░
  703. Button 4▼
  704. ◄├─┤░░░░► ",
  705. _output
  706. );
  707. }
  708. [Fact]
  709. public void KeyBindings_Command ()
  710. {
  711. var sv = new ScrollView { Width = 20, Height = 10, ContentSize = new Size (40, 20) };
  712. sv.Add (
  713. new View { Width = 20, Height = 5 },
  714. new View { X = 22, Y = 7, Width = 10, Height = 5 }
  715. );
  716. sv.BeginInit ();
  717. sv.EndInit ();
  718. Assert.True (sv.KeepContentAlwaysInViewport);
  719. Assert.True (sv.AutoHideScrollBars);
  720. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  721. Assert.False (sv.OnKeyDown (Key.CursorUp));
  722. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  723. Assert.True (sv.OnKeyDown (Key.CursorDown));
  724. Assert.Equal (new Point (0, -1), sv.ContentOffset);
  725. Assert.True (sv.OnKeyDown (Key.CursorUp));
  726. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  727. Assert.False (sv.OnKeyDown (Key.PageUp));
  728. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  729. Assert.True (sv.OnKeyDown (Key.PageDown));
  730. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  731. Assert.False (sv.OnKeyDown (Key.PageDown));
  732. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  733. Assert.False (sv.OnKeyDown (Key.CursorDown));
  734. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  735. Assert.True (sv.OnKeyDown (Key.V.WithAlt));
  736. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  737. Assert.True (sv.OnKeyDown (Key.V.WithCtrl));
  738. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  739. Assert.False (sv.OnKeyDown (Key.CursorLeft));
  740. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  741. Assert.True (sv.OnKeyDown (Key.CursorRight));
  742. Assert.Equal (new Point (-1, -10), sv.ContentOffset);
  743. Assert.True (sv.OnKeyDown (Key.CursorLeft));
  744. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  745. Assert.False (sv.OnKeyDown (Key.PageUp.WithCtrl));
  746. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  747. Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl));
  748. Assert.Equal (new Point (-20, -10), sv.ContentOffset);
  749. Assert.False (sv.OnKeyDown (Key.CursorRight));
  750. Assert.Equal (new Point (-20, -10), sv.ContentOffset);
  751. Assert.True (sv.OnKeyDown (Key.Home));
  752. Assert.Equal (new Point (-20, 0), sv.ContentOffset);
  753. Assert.False (sv.OnKeyDown (Key.Home));
  754. Assert.Equal (new Point (-20, 0), sv.ContentOffset);
  755. Assert.True (sv.OnKeyDown (Key.End));
  756. Assert.Equal (new Point (-20, -10), sv.ContentOffset);
  757. Assert.False (sv.OnKeyDown (Key.End));
  758. Assert.Equal (new Point (-20, -10), sv.ContentOffset);
  759. Assert.True (sv.OnKeyDown (Key.Home.WithCtrl));
  760. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  761. Assert.False (sv.OnKeyDown (Key.Home.WithCtrl));
  762. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  763. Assert.True (sv.OnKeyDown (Key.End.WithCtrl));
  764. Assert.Equal (new Point (-20, -10), sv.ContentOffset);
  765. Assert.False (sv.OnKeyDown (Key.End.WithCtrl));
  766. Assert.Equal (new Point (-20, -10), sv.ContentOffset);
  767. Assert.True (sv.OnKeyDown (Key.Home));
  768. Assert.Equal (new Point (-20, 0), sv.ContentOffset);
  769. Assert.True (sv.OnKeyDown (Key.Home.WithCtrl));
  770. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  771. sv.KeepContentAlwaysInViewport = false;
  772. Assert.False (sv.KeepContentAlwaysInViewport);
  773. Assert.True (sv.AutoHideScrollBars);
  774. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  775. Assert.False (sv.OnKeyDown (Key.CursorUp));
  776. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  777. Assert.True (sv.OnKeyDown (Key.CursorDown));
  778. Assert.Equal (new Point (0, -1), sv.ContentOffset);
  779. Assert.True (sv.OnKeyDown (Key.CursorUp));
  780. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  781. Assert.False (sv.OnKeyDown (Key.PageUp));
  782. Assert.Equal (new Point (0, 0), sv.ContentOffset);
  783. Assert.True (sv.OnKeyDown (Key.PageDown));
  784. Assert.Equal (new Point (0, -10), sv.ContentOffset);
  785. Assert.True (sv.OnKeyDown (Key.PageDown));
  786. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  787. Assert.False (sv.OnKeyDown (Key.PageDown));
  788. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  789. Assert.False (sv.OnKeyDown (Key.CursorDown));
  790. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  791. Assert.True (sv.OnKeyDown (Key.V.WithAlt));
  792. Assert.Equal (new Point (0, -9), sv.ContentOffset);
  793. Assert.True (sv.OnKeyDown (Key.V.WithCtrl));
  794. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  795. Assert.False (sv.OnKeyDown (Key.CursorLeft));
  796. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  797. Assert.True (sv.OnKeyDown (Key.CursorRight));
  798. Assert.Equal (new Point (-1, -19), sv.ContentOffset);
  799. Assert.True (sv.OnKeyDown (Key.CursorLeft));
  800. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  801. Assert.False (sv.OnKeyDown (Key.PageUp.WithCtrl));
  802. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  803. Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl));
  804. Assert.Equal (new Point (-20, -19), sv.ContentOffset);
  805. Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl));
  806. Assert.Equal (new Point (-39, -19), sv.ContentOffset);
  807. Assert.False (sv.OnKeyDown (Key.PageDown.WithCtrl));
  808. Assert.Equal (new Point (-39, -19), sv.ContentOffset);
  809. Assert.False (sv.OnKeyDown (Key.CursorRight));
  810. Assert.Equal (new Point (-39, -19), sv.ContentOffset);
  811. Assert.True (sv.OnKeyDown (Key.PageUp.WithCtrl));
  812. Assert.Equal (new Point (-19, -19), sv.ContentOffset);
  813. Assert.True (sv.OnKeyDown (Key.Home));
  814. Assert.Equal (new Point (-19, 0), sv.ContentOffset);
  815. Assert.False (sv.OnKeyDown (Key.Home));
  816. Assert.Equal (new Point (-19, 0), sv.ContentOffset);
  817. Assert.True (sv.OnKeyDown (Key.End));
  818. Assert.Equal (new Point (-19, -19), sv.ContentOffset);
  819. Assert.False (sv.OnKeyDown (Key.End));
  820. Assert.Equal (new Point (-19, -19), sv.ContentOffset);
  821. Assert.True (sv.OnKeyDown (Key.Home.WithCtrl));
  822. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  823. Assert.False (sv.OnKeyDown (Key.Home.WithCtrl));
  824. Assert.Equal (new Point (0, -19), sv.ContentOffset);
  825. Assert.True (sv.OnKeyDown (Key.End.WithCtrl));
  826. Assert.Equal (new Point (-39, -19), sv.ContentOffset);
  827. Assert.False (sv.OnKeyDown (Key.End.WithCtrl));
  828. Assert.Equal (new Point (-39, -19), sv.ContentOffset);
  829. }
  830. [Fact]
  831. [AutoInitShutdown]
  832. public void Remove_Added_View_Is_Allowed ()
  833. {
  834. var sv = new ScrollView { Width = 20, Height = 20, ContentSize = new Size (100, 100) };
  835. sv.Add (
  836. new View { Width = Dim.Fill (), Height = Dim.Fill (50), Id = "View1" },
  837. new View { Y = 51, Width = Dim.Fill (), Height = Dim.Fill (), Id = "View2" }
  838. );
  839. Application.Top.Add (sv);
  840. Application.Begin (Application.Top);
  841. Assert.Equal (4, sv.Subviews.Count);
  842. Assert.Equal (2, sv.Subviews [0].Subviews.Count);
  843. sv.Remove (sv.Subviews [0].Subviews [1]);
  844. Assert.Equal (4, sv.Subviews.Count);
  845. Assert.Single (sv.Subviews [0].Subviews);
  846. Assert.Equal ("View1", sv.Subviews [0].Subviews [0].Id);
  847. }
  848. private class CustomButton : FrameView
  849. {
  850. private readonly Label labelFill;
  851. private readonly Label labelText;
  852. public CustomButton (string fill, string text, int width, int height)
  853. {
  854. Width = width;
  855. Height = height;
  856. //labelFill = new Label { AutoSize = false, X = Pos.Center (), Y = Pos.Center (), Width = Dim.Fill (), Height = Dim.Fill (), Visible = false };
  857. labelFill = new Label { AutoSize = false, Width = Dim.Fill (), Height = Dim.Fill (), Visible = false };
  858. labelFill.LayoutComplete += (s, e) =>
  859. {
  860. var fillText = new StringBuilder ();
  861. for (var i = 0; i < labelFill.Bounds.Height; i++)
  862. {
  863. if (i > 0)
  864. {
  865. fillText.AppendLine ("");
  866. }
  867. for (var j = 0; j < labelFill.Bounds.Width; j++)
  868. {
  869. fillText.Append (fill);
  870. }
  871. }
  872. labelFill.Text = fillText.ToString ();
  873. };
  874. labelText = new Label { X = Pos.Center (), Y = Pos.Center (), Text = text };
  875. Add (labelFill, labelText);
  876. CanFocus = true;
  877. }
  878. public override bool OnEnter (View view)
  879. {
  880. Border.LineStyle = LineStyle.None;
  881. Border.Thickness = new Thickness (0);
  882. labelFill.Visible = true;
  883. view = this;
  884. return base.OnEnter (view);
  885. }
  886. public override bool OnLeave (View view)
  887. {
  888. Border.LineStyle = LineStyle.Single;
  889. Border.Thickness = new Thickness (1);
  890. labelFill.Visible = false;
  891. if (view == null)
  892. {
  893. view = this;
  894. }
  895. return base.OnLeave (view);
  896. }
  897. }
  898. }