ScrollBarViewTests.cs 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  1. using System.Collections.ObjectModel;
  2. using System.Reflection;
  3. using Xunit.Abstractions;
  4. namespace Terminal.Gui.ViewsTests;
  5. public class ScrollBarViewTests
  6. {
  7. private static HostView _hostView;
  8. private readonly ITestOutputHelper _output;
  9. private bool _added;
  10. private ScrollBarView _scrollBar;
  11. public ScrollBarViewTests (ITestOutputHelper output) { _output = output; }
  12. [Fact]
  13. [ScrollBarAutoInitShutdown]
  14. public void AutoHideScrollBars_Check ()
  15. {
  16. _scrollBar = new ScrollBarView (_hostView, true);
  17. Application.Begin (_hostView.SuperView as Toplevel);
  18. AddHandlers ();
  19. _hostView.Draw ();
  20. Assert.True (_scrollBar.ShowScrollIndicator);
  21. Assert.True (_scrollBar.Visible);
  22. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  23. Assert.Equal (1, _scrollBar.Viewport.Width);
  24. Assert.Equal (
  25. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  26. _scrollBar.Height.ToString ()
  27. );
  28. Assert.Equal (24, _scrollBar.Viewport.Height);
  29. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  30. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  31. Assert.Equal (
  32. $"Combine(View(Width,HostView(){_hostView.Frame})-Absolute(1))",
  33. _scrollBar.OtherScrollBarView.Width.ToString ()
  34. );
  35. Assert.Equal (79, _scrollBar.OtherScrollBarView.Viewport.Width);
  36. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  37. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  38. _hostView.Lines = 10;
  39. _hostView.SetNeedsDraw ();
  40. _hostView.Draw ();
  41. Assert.False (_scrollBar.ShowScrollIndicator);
  42. Assert.False (_scrollBar.Visible);
  43. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  44. Assert.Equal (1, _scrollBar.Viewport.Width);
  45. Assert.Equal (
  46. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  47. _scrollBar.Height.ToString ()
  48. );
  49. Assert.Equal (24, _scrollBar.Viewport.Height);
  50. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  51. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  52. Assert.Equal (
  53. $"View(Width,HostView(){_hostView.Frame})",
  54. _scrollBar.OtherScrollBarView.Width.ToString ()
  55. );
  56. Assert.Equal (80, _scrollBar.OtherScrollBarView.Viewport.Width);
  57. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  58. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  59. _hostView.Cols = 60;
  60. _hostView.SetNeedsDraw ();
  61. _hostView.Draw ();
  62. Assert.False (_scrollBar.ShowScrollIndicator);
  63. Assert.False (_scrollBar.Visible);
  64. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  65. Assert.Equal (1, _scrollBar.Viewport.Width);
  66. Assert.Equal (
  67. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  68. _scrollBar.Height.ToString ()
  69. );
  70. Assert.Equal (24, _scrollBar.Viewport.Height);
  71. Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  72. Assert.False (_scrollBar.OtherScrollBarView.Visible);
  73. Assert.Equal (
  74. $"View(Width,HostView(){_hostView.Frame})",
  75. _scrollBar.OtherScrollBarView.Width.ToString ()
  76. );
  77. Assert.Equal (80, _scrollBar.OtherScrollBarView.Viewport.Width);
  78. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  79. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  80. _hostView.Lines = 40;
  81. _hostView.SetNeedsDraw ();
  82. _hostView.Draw ();
  83. Assert.True (_scrollBar.ShowScrollIndicator);
  84. Assert.True (_scrollBar.Visible);
  85. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  86. Assert.Equal (1, _scrollBar.Viewport.Width);
  87. Assert.Equal (
  88. $"View(Height,HostView(){_hostView.Frame})",
  89. _scrollBar.Height.ToString ()
  90. );
  91. Assert.Equal (25, _scrollBar.Viewport.Height);
  92. Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  93. Assert.False (_scrollBar.OtherScrollBarView.Visible);
  94. Assert.Equal (
  95. $"View(Width,HostView(){_hostView.Frame})",
  96. _scrollBar.OtherScrollBarView.Width.ToString ()
  97. );
  98. Assert.Equal (80, _scrollBar.OtherScrollBarView.Viewport.Width);
  99. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  100. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  101. _hostView.Cols = 120;
  102. _hostView.SetNeedsDraw ();
  103. _hostView.Draw ();
  104. Assert.True (_scrollBar.ShowScrollIndicator);
  105. Assert.True (_scrollBar.Visible);
  106. Assert.Equal ("Absolute(1)", _scrollBar.Width.ToString ());
  107. Assert.Equal (1, _scrollBar.Viewport.Width);
  108. Assert.Equal (
  109. $"Combine(View(Height,HostView(){_hostView.Frame})-Absolute(1))",
  110. _scrollBar.Height.ToString ()
  111. );
  112. Assert.Equal (24, _scrollBar.Viewport.Height);
  113. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  114. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  115. Assert.Equal (
  116. $"Combine(View(Width,HostView(){_hostView.Frame})-Absolute(1))",
  117. _scrollBar.OtherScrollBarView.Width.ToString ()
  118. );
  119. Assert.Equal (79, _scrollBar.OtherScrollBarView.Viewport.Width);
  120. Assert.Equal ("Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
  121. Assert.Equal (1, _scrollBar.OtherScrollBarView.Viewport.Height);
  122. _hostView.SuperView.Dispose ();
  123. }
  124. [Fact]
  125. [AutoInitShutdown]
  126. public void Both_Default_Draws_Correctly ()
  127. {
  128. var width = 3;
  129. var height = 40;
  130. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  131. var top = new Toplevel ();
  132. top.Add (super);
  133. var horiz = new ScrollBarView
  134. {
  135. Id = "horiz",
  136. Size = width * 2,
  137. // BUGBUG: ScrollBarView should work if Host is null
  138. Host = super,
  139. ShowScrollIndicator = true,
  140. IsVertical = true
  141. };
  142. super.Add (horiz);
  143. var vert = new ScrollBarView
  144. {
  145. Id = "vert",
  146. Size = height * 2,
  147. // BUGBUG: ScrollBarView should work if Host is null
  148. Host = super,
  149. ShowScrollIndicator = true,
  150. IsVertical = true
  151. };
  152. super.Add (vert);
  153. Application.Begin (top);
  154. ((FakeDriver)Application.Driver!).SetBufferSize (width, height);
  155. Application.LayoutAndDrawToplevels ();
  156. var expected = @"
  157. ┌─┐
  158. │▲│
  159. │┬│
  160. │││
  161. │││
  162. │││
  163. │││
  164. │││
  165. │││
  166. │││
  167. │││
  168. │││
  169. │││
  170. │││
  171. │││
  172. │││
  173. │││
  174. │││
  175. │││
  176. │┴│
  177. │░│
  178. │░│
  179. │░│
  180. │░│
  181. │░│
  182. │░│
  183. │░│
  184. │░│
  185. │░│
  186. │░│
  187. │░│
  188. │░│
  189. │░│
  190. │░│
  191. │░│
  192. │░│
  193. │░│
  194. │░│
  195. │▼│
  196. └─┘";
  197. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  198. top.Dispose ();
  199. }
  200. [Fact]
  201. [ScrollBarAutoInitShutdown]
  202. public void ChangedPosition_Negative_Value ()
  203. {
  204. _scrollBar = new ScrollBarView (_hostView, true);
  205. Application.Begin (_hostView.SuperView as Toplevel);
  206. Application.LayoutAndDrawToplevels ();
  207. AddHandlers ();
  208. _scrollBar.Position = -20;
  209. Assert.Equal (0, _scrollBar.Position);
  210. Assert.Equal (_scrollBar.Position, _hostView.Top);
  211. _scrollBar.OtherScrollBarView.Position = -50;
  212. Assert.Equal (0, _scrollBar.OtherScrollBarView.Position);
  213. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  214. _hostView.SuperView.Dispose ();
  215. }
  216. [Fact]
  217. [ScrollBarAutoInitShutdown]
  218. public void ChangedPosition_Scrolling ()
  219. {
  220. _scrollBar = new ScrollBarView (_hostView, true);
  221. Application.Begin (_hostView.SuperView as Toplevel);
  222. Application.LayoutAndDrawToplevels ();
  223. AddHandlers ();
  224. for (var i = 0; i < _scrollBar.Size; i++)
  225. {
  226. _scrollBar.Position += 1;
  227. Assert.Equal (_scrollBar.Position, _hostView.Top);
  228. }
  229. for (int i = _scrollBar.Size - 1; i >= 0; i--)
  230. {
  231. _scrollBar.Position -= 1;
  232. Assert.Equal (_scrollBar.Position, _hostView.Top);
  233. }
  234. for (var i = 0; i < _scrollBar.OtherScrollBarView.Size; i++)
  235. {
  236. _scrollBar.OtherScrollBarView.Position += i;
  237. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  238. }
  239. for (int i = _scrollBar.OtherScrollBarView.Size - 1; i >= 0; i--)
  240. {
  241. _scrollBar.OtherScrollBarView.Position -= 1;
  242. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  243. }
  244. _hostView.SuperView.Dispose ();
  245. }
  246. [Fact]
  247. [ScrollBarAutoInitShutdown]
  248. public void ChangedPosition_Update_The_Hosted_View ()
  249. {
  250. _scrollBar = new ScrollBarView (_hostView, true);
  251. Application.Begin (_hostView.SuperView as Toplevel);
  252. Application.LayoutAndDrawToplevels ();
  253. AddHandlers ();
  254. _scrollBar.Position = 2;
  255. Assert.Equal (_scrollBar.Position, _hostView.Top);
  256. _scrollBar.OtherScrollBarView.Position = 5;
  257. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  258. _hostView.SuperView.Dispose ();
  259. }
  260. [Fact]
  261. [AutoInitShutdown]
  262. public void Visible_Gets_Sets ()
  263. {
  264. var text =
  265. "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  266. var label = new Label { Text = text };
  267. var top = new Toplevel ();
  268. top.Add (label);
  269. var sbv = new ScrollBarView (label, true, false) { Size = 100 };
  270. Application.Begin (top);
  271. Application.LayoutAndDrawToplevels ();
  272. Assert.True (sbv.Visible);
  273. TestHelpers.AssertDriverContentsWithFrameAre (
  274. @"
  275. This is a tes▲
  276. This is a tes┬
  277. This is a tes┴
  278. This is a tes░
  279. This is a tes░
  280. This is a tes▼
  281. ",
  282. _output
  283. );
  284. sbv.Visible = false;
  285. Assert.False (sbv.Visible);
  286. top.Draw ();
  287. TestHelpers.AssertDriverContentsWithFrameAre (
  288. @"
  289. This is a test
  290. This is a test
  291. This is a test
  292. This is a test
  293. This is a test
  294. This is a test
  295. ",
  296. _output
  297. );
  298. sbv.Visible = true;
  299. Assert.True (sbv.Visible);
  300. top.Draw ();
  301. TestHelpers.AssertDriverContentsWithFrameAre (
  302. @"
  303. This is a tes▲
  304. This is a tes┬
  305. This is a tes┴
  306. This is a tes░
  307. This is a tes░
  308. This is a tes▼
  309. ",
  310. _output
  311. );
  312. sbv.Visible = false;
  313. Assert.False (sbv.Visible);
  314. top.Draw ();
  315. TestHelpers.AssertDriverContentsWithFrameAre (
  316. @"
  317. This is a test
  318. This is a test
  319. This is a test
  320. This is a test
  321. This is a test
  322. This is a test
  323. ",
  324. _output
  325. );
  326. top.Dispose ();
  327. }
  328. [Fact (Skip = "#3798 broke - Fix with #3498")]
  329. public void
  330. Constructor_ShowBothScrollIndicator_False_And_IsVertical_False_Refresh_Does_Not_Throws_An_Object_Null_Exception ()
  331. {
  332. var exception = Record.Exception (
  333. () =>
  334. {
  335. Application.Init (new FakeDriver ());
  336. Toplevel top = new ();
  337. var win = new Window { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
  338. ObservableCollection<string> source = [];
  339. for (var i = 0; i < 50; i++)
  340. {
  341. var text = $"item {i} - ";
  342. for (var j = 0; j < 160; j++)
  343. {
  344. var col = j.ToString ();
  345. text += col.Length == 1 ? col [0] : col [1];
  346. }
  347. source.Add (text);
  348. }
  349. var listView = new ListView
  350. {
  351. X = 0,
  352. Y = 0,
  353. Width = Dim.Fill (),
  354. Height = Dim.Fill (),
  355. Source = new ListWrapper<string> (source)
  356. };
  357. win.Add (listView);
  358. var newScrollBarView = new ScrollBarView (listView, false, false) { KeepContentAlwaysInViewport = true };
  359. win.Add (newScrollBarView);
  360. newScrollBarView.ChangedPosition += (s, e) =>
  361. {
  362. listView.LeftItem = newScrollBarView.Position;
  363. if (listView.LeftItem != newScrollBarView.Position)
  364. {
  365. newScrollBarView.Position = listView.LeftItem;
  366. }
  367. Assert.Equal (newScrollBarView.Position, listView.LeftItem);
  368. listView.SetNeedsDraw ();
  369. Application.LayoutAndDrawToplevels ();
  370. };
  371. listView.DrawingContent += (s, e) =>
  372. {
  373. newScrollBarView.Size = listView.MaxLength;
  374. Assert.Equal (newScrollBarView.Size, listView.MaxLength);
  375. newScrollBarView.Position = listView.LeftItem;
  376. Assert.Equal (newScrollBarView.Position, listView.LeftItem);
  377. newScrollBarView.Refresh ();
  378. };
  379. top.Ready += (s, e) =>
  380. {
  381. newScrollBarView.Position = 100;
  382. Assert.Equal (
  383. newScrollBarView.Position,
  384. newScrollBarView.Size
  385. - listView.LeftItem
  386. + (listView.LeftItem - listView.Viewport.Width));
  387. Assert.Equal (newScrollBarView.Position, listView.LeftItem);
  388. Assert.Equal (92, newScrollBarView.Position);
  389. Assert.Equal (92, listView.LeftItem);
  390. Application.RequestStop ();
  391. };
  392. top.Add (win);
  393. Application.Run (top);
  394. top.Dispose ();
  395. Application.Shutdown ();
  396. });
  397. Assert.Null (exception);
  398. }
  399. [Fact (Skip = "#3798 broke - Fix with #3498")]
  400. public void
  401. Constructor_ShowBothScrollIndicator_False_And_IsVertical_True_Refresh_Does_Not_Throws_An_Object_Null_Exception ()
  402. {
  403. Exception exception = Record.Exception (
  404. () =>
  405. {
  406. Application.Init (new FakeDriver ());
  407. Toplevel top = new ();
  408. var win = new Window { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () };
  409. ObservableCollection<string> source = [];
  410. for (var i = 0; i < 50; i++)
  411. {
  412. source.Add ($"item {i}");
  413. }
  414. var listView = new ListView
  415. {
  416. X = 0,
  417. Y = 0,
  418. Width = Dim.Fill (),
  419. Height = Dim.Fill (),
  420. Source = new ListWrapper<string> (source)
  421. };
  422. win.Add (listView);
  423. var newScrollBarView = new ScrollBarView (listView, true, false) { KeepContentAlwaysInViewport = true };
  424. win.Add (newScrollBarView);
  425. newScrollBarView.ChangedPosition += (s, e) =>
  426. {
  427. listView.TopItem = newScrollBarView.Position;
  428. if (listView.TopItem != newScrollBarView.Position)
  429. {
  430. newScrollBarView.Position = listView.TopItem;
  431. }
  432. Assert.Equal (newScrollBarView.Position, listView.TopItem);
  433. listView.SetNeedsDraw ();
  434. Application.LayoutAndDrawToplevels ();
  435. };
  436. listView.DrawingContent += (s, e) =>
  437. {
  438. newScrollBarView.Size = listView.Source.Count;
  439. Assert.Equal (newScrollBarView.Size, listView.Source.Count);
  440. newScrollBarView.Position = listView.TopItem;
  441. Assert.Equal (newScrollBarView.Position, listView.TopItem);
  442. newScrollBarView.Refresh ();
  443. };
  444. top.Ready += (s, e) =>
  445. {
  446. newScrollBarView.Position = 45;
  447. Assert.Equal (
  448. newScrollBarView.Position,
  449. newScrollBarView.Size
  450. - listView.TopItem
  451. + (listView.TopItem - listView.Viewport.Height)
  452. );
  453. Assert.Equal (newScrollBarView.Position, listView.TopItem);
  454. Assert.Equal (27, newScrollBarView.Position);
  455. Assert.Equal (27, listView.TopItem);
  456. Application.RequestStop ();
  457. };
  458. top.Add (win);
  459. Application.Run (top);
  460. top.Dispose ();
  461. Application.Shutdown ();
  462. }
  463. );
  464. Assert.Null (exception);
  465. }
  466. [Fact]
  467. [AutoInitShutdown]
  468. public void ContentBottomRightCorner_Not_Redraw_If_Both_Size_Equal_To_Zero ()
  469. {
  470. var text =
  471. "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  472. var label = new Label { Text = text };
  473. var top = new Toplevel ();
  474. top.Add (label);
  475. var sbv = new ScrollBarView (label, true) { Size = 100 };
  476. sbv.OtherScrollBarView.Size = 100;
  477. Application.Begin (top);
  478. Application.LayoutAndDrawToplevels ();
  479. Assert.Equal (100, sbv.Size);
  480. Assert.Equal (100, sbv.OtherScrollBarView.Size);
  481. Assert.True (sbv.ShowScrollIndicator);
  482. Assert.True (sbv.OtherScrollBarView.ShowScrollIndicator);
  483. Assert.True (sbv.Visible);
  484. Assert.True (sbv.OtherScrollBarView.Visible);
  485. View contentBottomRightCorner =
  486. label.SuperView.Subviews.First (v => v is ScrollBarView.ContentBottomRightCorner);
  487. Assert.True (contentBottomRightCorner is ScrollBarView.ContentBottomRightCorner);
  488. Assert.True (contentBottomRightCorner.Visible);
  489. TestHelpers.AssertDriverContentsWithFrameAre (
  490. @"
  491. This is a tes▲
  492. This is a tes┬
  493. This is a tes┴
  494. This is a tes░
  495. This is a tes▼
  496. ◄├─┤░░░░░░░░►
  497. ",
  498. _output
  499. );
  500. sbv.Size = 0;
  501. sbv.OtherScrollBarView.Size = 0;
  502. Assert.Equal (0, sbv.Size);
  503. Assert.Equal (0, sbv.OtherScrollBarView.Size);
  504. Assert.False (sbv.ShowScrollIndicator);
  505. Assert.False (sbv.OtherScrollBarView.ShowScrollIndicator);
  506. Assert.False (sbv.Visible);
  507. Assert.False (sbv.OtherScrollBarView.Visible);
  508. top.Draw ();
  509. TestHelpers.AssertDriverContentsWithFrameAre (
  510. @"
  511. This is a test
  512. This is a test
  513. This is a test
  514. This is a test
  515. This is a test
  516. This is a test
  517. ",
  518. _output
  519. );
  520. sbv.Size = 50;
  521. sbv.OtherScrollBarView.Size = 50;
  522. Assert.Equal (50, sbv.Size);
  523. Assert.Equal (50, sbv.OtherScrollBarView.Size);
  524. Assert.True (sbv.ShowScrollIndicator);
  525. Assert.True (sbv.OtherScrollBarView.ShowScrollIndicator);
  526. Assert.True (sbv.Visible);
  527. Assert.True (sbv.OtherScrollBarView.Visible);
  528. top.Draw ();
  529. TestHelpers.AssertDriverContentsWithFrameAre (
  530. @"
  531. This is a tes▲
  532. This is a tes┬
  533. This is a tes┴
  534. This is a tes░
  535. This is a tes▼
  536. ◄├──┤░░░░░░░►
  537. ",
  538. _output
  539. );
  540. top.Dispose ();
  541. }
  542. [Fact]
  543. [AutoInitShutdown]
  544. public void ContentBottomRightCorner_Not_Redraw_If_One_Size_Equal_To_Zero ()
  545. {
  546. var text =
  547. "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  548. var label = new Label { Text = text };
  549. var top = new Toplevel ();
  550. top.Add (label);
  551. var sbv = new ScrollBarView (label, true, false) { Size = 100 };
  552. Application.Begin (top);
  553. Application.LayoutAndDrawToplevels ();
  554. Assert.Equal (100, sbv.Size);
  555. Assert.Null (sbv.OtherScrollBarView);
  556. Assert.True (sbv.ShowScrollIndicator);
  557. Assert.True (sbv.Visible);
  558. TestHelpers.AssertDriverContentsWithFrameAre (
  559. @"
  560. This is a tes▲
  561. This is a tes┬
  562. This is a tes┴
  563. This is a tes░
  564. This is a tes░
  565. This is a tes▼
  566. ",
  567. _output
  568. );
  569. sbv.Size = 0;
  570. Assert.Equal (0, sbv.Size);
  571. Assert.False (sbv.ShowScrollIndicator);
  572. Assert.False (sbv.Visible);
  573. top.Draw ();
  574. TestHelpers.AssertDriverContentsWithFrameAre (
  575. @"
  576. This is a test
  577. This is a test
  578. This is a test
  579. This is a test
  580. This is a test
  581. This is a test
  582. ",
  583. _output
  584. );
  585. top.Dispose ();
  586. }
  587. [Fact]
  588. [ScrollBarAutoInitShutdown]
  589. public void DrawContent_Update_The_ScrollBarView_Position ()
  590. {
  591. _scrollBar = new ScrollBarView (_hostView, true);
  592. Application.Begin (_hostView.SuperView as Toplevel);
  593. Application.LayoutAndDrawToplevels ();
  594. AddHandlers ();
  595. _hostView.Top = 3;
  596. _hostView.SetNeedsDraw ();
  597. _hostView.Draw ();
  598. Assert.Equal (_scrollBar.Position, _hostView.Top);
  599. _hostView.Left = 6;
  600. _hostView.SetNeedsDraw ();
  601. _hostView.Draw ();
  602. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  603. _hostView.SuperView.Dispose ();
  604. }
  605. [Fact]
  606. [AutoInitShutdown]
  607. public void Horizontal_Default_Draws_Correctly ()
  608. {
  609. var width = 40;
  610. var height = 3;
  611. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  612. var top = new Toplevel ();
  613. top.Add (super);
  614. var sbv = new ScrollBarView { Id = "sbv", Size = width * 2, ShowScrollIndicator = true };
  615. super.Add (sbv);
  616. Application.Begin (top);
  617. ((FakeDriver)Application.Driver!).SetBufferSize (width, height);
  618. var expected = @"
  619. ┌──────────────────────────────────────┐
  620. │◄├────────────────┤░░░░░░░░░░░░░░░░░░►│
  621. └──────────────────────────────────────┘";
  622. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  623. top.Dispose ();
  624. }
  625. [Fact]
  626. [ScrollBarAutoInitShutdown]
  627. public void Hosting_A_Null_SuperView_View_To_A_ScrollBarView_Throws_ArgumentNullException ()
  628. {
  629. Assert.Throws<ArgumentNullException> (
  630. "The host SuperView parameter can't be null.",
  631. () => new ScrollBarView (new View (), true)
  632. );
  633. Assert.Throws<ArgumentNullException> (
  634. "The host SuperView parameter can't be null.",
  635. () => new ScrollBarView (new View (), false)
  636. );
  637. }
  638. [Fact]
  639. [ScrollBarAutoInitShutdown]
  640. public void Hosting_A_Null_View_To_A_ScrollBarView_Throws_ArgumentNullException ()
  641. {
  642. Assert.Throws<ArgumentNullException> (
  643. "The host parameter can't be null.",
  644. () => new ScrollBarView (null, true)
  645. );
  646. Assert.Throws<ArgumentNullException> (
  647. "The host parameter can't be null.",
  648. () => new ScrollBarView (null, false)
  649. );
  650. }
  651. [Fact]
  652. [ScrollBarAutoInitShutdown]
  653. public void Hosting_A_View_To_A_ScrollBarView ()
  654. {
  655. RemoveHandlers ();
  656. _scrollBar = new ScrollBarView (_hostView, true);
  657. RunState rs = Application.Begin (_hostView.SuperView as Toplevel);
  658. Assert.True (_scrollBar.IsVertical);
  659. Assert.False (_scrollBar.OtherScrollBarView.IsVertical);
  660. Assert.Equal (_scrollBar.Position, _hostView.Top);
  661. Assert.NotEqual (_scrollBar.Size, _hostView.Lines);
  662. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  663. Assert.NotEqual (_scrollBar.OtherScrollBarView.Size, _hostView.Cols);
  664. AddHandlers ();
  665. Application.RunIteration (ref rs);
  666. Assert.Equal (_scrollBar.Position, _hostView.Top);
  667. Assert.Equal (_scrollBar.Size, _hostView.Lines);
  668. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  669. Assert.Equal (_scrollBar.OtherScrollBarView.Size, _hostView.Cols);
  670. _hostView.SuperView.Dispose ();
  671. }
  672. [Fact]
  673. [AutoInitShutdown]
  674. public void Hosting_ShowBothScrollIndicator_Invisible ()
  675. {
  676. var textView = new TextView
  677. {
  678. Width = Dim.Fill (),
  679. Height = Dim.Fill (),
  680. Text =
  681. "This is the help text for the Second Step.\n\nPress the button to see a message box.\n\nEnter name too."
  682. };
  683. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  684. win.Add (textView);
  685. var scrollBar = new ScrollBarView (textView, true);
  686. scrollBar.ChangedPosition += (s, e) =>
  687. {
  688. textView.TopRow = scrollBar.Position;
  689. if (textView.TopRow != scrollBar.Position)
  690. {
  691. scrollBar.Position = textView.TopRow;
  692. }
  693. textView.SetNeedsDraw ();
  694. };
  695. scrollBar.OtherScrollBarView.ChangedPosition += (s, e) =>
  696. {
  697. textView.LeftColumn = scrollBar.OtherScrollBarView.Position;
  698. if (textView.LeftColumn != scrollBar.OtherScrollBarView.Position)
  699. {
  700. scrollBar.OtherScrollBarView.Position = textView.LeftColumn;
  701. }
  702. textView.SetNeedsDraw ();
  703. };
  704. textView.SubviewsLaidOut += (s, e) =>
  705. {
  706. scrollBar.Size = textView.Lines;
  707. scrollBar.Position = textView.TopRow;
  708. if (scrollBar.OtherScrollBarView != null)
  709. {
  710. scrollBar.OtherScrollBarView.Size = textView.Maxlength;
  711. scrollBar.OtherScrollBarView.Position = textView.LeftColumn;
  712. }
  713. };
  714. var top = new Toplevel ();
  715. top.Add (win);
  716. RunState rs = Application.Begin (top);
  717. ((FakeDriver)Application.Driver!).SetBufferSize (45, 20);
  718. Assert.True (scrollBar.AutoHideScrollBars);
  719. Assert.False (scrollBar.ShowScrollIndicator);
  720. Assert.False (scrollBar.OtherScrollBarView.ShowScrollIndicator);
  721. Assert.Equal (5, textView.Lines);
  722. Assert.Equal (42, textView.Maxlength);
  723. Assert.Equal (0, textView.LeftColumn);
  724. Assert.Equal (0, scrollBar.Position);
  725. Assert.Equal (0, scrollBar.OtherScrollBarView.Position);
  726. var expected = @"
  727. ┌───────────────────────────────────────────┐
  728. │This is the help text for the Second Step. │
  729. │ │
  730. │Press the button to see a message box. │
  731. │ │
  732. │Enter name too. │
  733. │ │
  734. │ │
  735. │ │
  736. │ │
  737. │ │
  738. │ │
  739. │ │
  740. │ │
  741. │ │
  742. │ │
  743. │ │
  744. │ │
  745. │ │
  746. └───────────────────────────────────────────┘
  747. ";
  748. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  749. Assert.Equal (new Rectangle (0, 0, 45, 20), pos);
  750. textView.WordWrap = true;
  751. ((FakeDriver)Application.Driver!).SetBufferSize (26, 20);
  752. Application.RunIteration (ref rs);
  753. Assert.True (textView.WordWrap);
  754. Assert.True (scrollBar.AutoHideScrollBars);
  755. Assert.Equal (7, textView.Lines);
  756. Assert.Equal (22, textView.Maxlength);
  757. Assert.Equal (0, textView.LeftColumn);
  758. Assert.Equal (0, scrollBar.Position);
  759. Assert.Equal (0, scrollBar.OtherScrollBarView.Position);
  760. expected = @"
  761. ┌────────────────────────┐
  762. │This is the help text │
  763. │for the Second Step. │
  764. │ │
  765. │Press the button to │
  766. │see a message box. │
  767. │ │
  768. │Enter name too. │
  769. │ │
  770. │ │
  771. │ │
  772. │ │
  773. │ │
  774. │ │
  775. │ │
  776. │ │
  777. │ │
  778. │ │
  779. │ │
  780. └────────────────────────┘
  781. ";
  782. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  783. Assert.Equal (new Rectangle (0, 0, 26, 20), pos);
  784. ((FakeDriver)Application.Driver!).SetBufferSize (10, 10);
  785. Application.RunIteration (ref rs);
  786. Assert.True (textView.WordWrap);
  787. Assert.True (scrollBar.AutoHideScrollBars);
  788. Assert.Equal (20, textView.Lines);
  789. Assert.Equal (7, textView.Maxlength);
  790. Assert.Equal (0, textView.LeftColumn);
  791. Assert.Equal (0, scrollBar.Position);
  792. Assert.Equal (0, scrollBar.OtherScrollBarView.Position);
  793. Assert.True (scrollBar.ShowScrollIndicator);
  794. expected = @"
  795. ┌────────┐
  796. │This ▲│
  797. │is the ┬│
  798. │help ││
  799. │text ┴│
  800. │for ░│
  801. │the ░│
  802. │Second ░│
  803. │Step. ▼│
  804. └────────┘
  805. ";
  806. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  807. Assert.Equal (new Rectangle (0, 0, 10, 10), pos);
  808. top.Dispose ();
  809. }
  810. [Fact]
  811. [ScrollBarAutoInitShutdown]
  812. public void Hosting_Two_Horizontal_ScrollBarView_Throws_ArgumentException ()
  813. {
  814. var top = new Toplevel ();
  815. var host = new View ();
  816. top.Add (host);
  817. var v = new ScrollBarView (host, false);
  818. var h = new ScrollBarView (host, false);
  819. Assert.Throws<ArgumentException> (() => v.OtherScrollBarView = h);
  820. Assert.Throws<ArgumentException> (() => h.OtherScrollBarView = v);
  821. top.Dispose ();
  822. }
  823. [Fact]
  824. [ScrollBarAutoInitShutdown]
  825. public void Hosting_Two_Vertical_ScrollBarView_Throws_ArgumentException ()
  826. {
  827. var top = new Toplevel ();
  828. var host = new View ();
  829. top.Add (host);
  830. var v = new ScrollBarView (host, true);
  831. var h = new ScrollBarView (host, true);
  832. Assert.Throws<ArgumentException> (() => v.OtherScrollBarView = h);
  833. Assert.Throws<ArgumentException> (() => h.OtherScrollBarView = v);
  834. top.Dispose ();
  835. }
  836. [Fact]
  837. [AutoInitShutdown]
  838. public void Internal_Tests ()
  839. {
  840. Toplevel top = new ();
  841. top.Layout ();
  842. Assert.Equal (new Rectangle (0, 0, 80, 25), top.Viewport);
  843. var view = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  844. top.Add (view);
  845. var sbv = new ScrollBarView (view, true);
  846. top.Add (sbv);
  847. Assert.Equal (view, sbv.Host);
  848. sbv.Size = 40;
  849. sbv.Position = 0;
  850. sbv.OtherScrollBarView.Size = 100;
  851. sbv.OtherScrollBarView.Position = 0;
  852. top.Layout ();
  853. // Host bounds is not empty.
  854. Assert.True (sbv.CanScroll (10, out int max, sbv.IsVertical));
  855. Assert.Equal (10, max);
  856. Assert.True (sbv.OtherScrollBarView.CanScroll (10, out max, sbv.OtherScrollBarView.IsVertical));
  857. Assert.Equal (10, max);
  858. Application.Begin (top);
  859. // They are visible so they are drawn.
  860. Assert.True (sbv.Visible);
  861. Assert.True (sbv.OtherScrollBarView.Visible);
  862. top.LayoutSubviews ();
  863. // Now the host bounds is not empty.
  864. Assert.True (sbv.CanScroll (10, out max, sbv.IsVertical));
  865. Assert.Equal (10, max);
  866. Assert.True (sbv.OtherScrollBarView.CanScroll (10, out max, sbv.OtherScrollBarView.IsVertical));
  867. Assert.Equal (10, max);
  868. Assert.True (sbv.CanScroll (50, out max, sbv.IsVertical));
  869. Assert.Equal (40, sbv.Size);
  870. Assert.Equal (16, max); // 16+25=41
  871. Assert.True (sbv.OtherScrollBarView.CanScroll (150, out max, sbv.OtherScrollBarView.IsVertical));
  872. Assert.Equal (100, sbv.OtherScrollBarView.Size);
  873. Assert.Equal (21, max); // 21+80=101
  874. Assert.True (sbv.Visible);
  875. Assert.True (sbv.OtherScrollBarView.Visible);
  876. sbv.KeepContentAlwaysInViewport = false;
  877. sbv.OtherScrollBarView.KeepContentAlwaysInViewport = false;
  878. Assert.True (sbv.CanScroll (50, out max, sbv.IsVertical));
  879. Assert.Equal (39, max);
  880. Assert.True (sbv.OtherScrollBarView.CanScroll (150, out max, sbv.OtherScrollBarView.IsVertical));
  881. Assert.Equal (99, max);
  882. Assert.True (sbv.Visible);
  883. Assert.True (sbv.OtherScrollBarView.Visible);
  884. top.Dispose ();
  885. }
  886. [Fact]
  887. [ScrollBarAutoInitShutdown]
  888. public void KeepContentAlwaysInViewport_False ()
  889. {
  890. _scrollBar = new ScrollBarView (_hostView, true);
  891. RunState rs = Application.Begin (_hostView.SuperView as Toplevel);
  892. AddHandlers ();
  893. Application.RunIteration (ref rs);
  894. _scrollBar.KeepContentAlwaysInViewport = false;
  895. _scrollBar.Position = 50;
  896. Assert.Equal (_scrollBar.Position, _scrollBar.Size - 1);
  897. Assert.Equal (_scrollBar.Position, _hostView.Top);
  898. Assert.Equal (29, _scrollBar.Position);
  899. Assert.Equal (29, _hostView.Top);
  900. _scrollBar.OtherScrollBarView.Position = 150;
  901. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _scrollBar.OtherScrollBarView.Size - 1);
  902. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  903. Assert.Equal (99, _scrollBar.OtherScrollBarView.Position);
  904. Assert.Equal (99, _hostView.Left);
  905. _hostView.SuperView.Dispose ();
  906. }
  907. [Fact]
  908. [ScrollBarAutoInitShutdown]
  909. public void KeepContentAlwaysInViewport_True ()
  910. {
  911. _scrollBar = new ScrollBarView (_hostView, true);
  912. RunState rs = Application.Begin (_hostView.SuperView as Toplevel);
  913. AddHandlers ();
  914. Application.RunIteration (ref rs);
  915. Assert.Equal (80, _hostView.Viewport.Width);
  916. Assert.Equal (25, _hostView.Viewport.Height);
  917. Assert.Equal (79, _scrollBar.OtherScrollBarView.Viewport.Width);
  918. Assert.Equal (24, _scrollBar.Viewport.Height);
  919. Assert.Equal (30, _scrollBar.Size);
  920. Assert.Equal (100, _scrollBar.OtherScrollBarView.Size);
  921. Assert.True (_scrollBar.ShowScrollIndicator);
  922. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  923. Assert.True (_scrollBar.Visible);
  924. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  925. _scrollBar.Position = 50;
  926. Assert.Equal (_scrollBar.Position, _scrollBar.Size - _scrollBar.Viewport.Height);
  927. Assert.Equal (_scrollBar.Position, _hostView.Top);
  928. Assert.Equal (6, _scrollBar.Position);
  929. Assert.Equal (6, _hostView.Top);
  930. Assert.True (_scrollBar.ShowScrollIndicator);
  931. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  932. Assert.True (_scrollBar.Visible);
  933. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  934. _scrollBar.OtherScrollBarView.Position = 150;
  935. Assert.Equal (
  936. _scrollBar.OtherScrollBarView.Position,
  937. _scrollBar.OtherScrollBarView.Size - _scrollBar.OtherScrollBarView.Viewport.Width
  938. );
  939. Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left);
  940. Assert.Equal (21, _scrollBar.OtherScrollBarView.Position);
  941. Assert.Equal (21, _hostView.Left);
  942. Assert.True (_scrollBar.ShowScrollIndicator);
  943. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  944. Assert.True (_scrollBar.Visible);
  945. Assert.True (_scrollBar.OtherScrollBarView.Visible);
  946. _hostView.SuperView.Dispose ();
  947. }
  948. [Fact]
  949. [ScrollBarAutoInitShutdown]
  950. public void OtherScrollBarView_Not_Null ()
  951. {
  952. _scrollBar = new ScrollBarView (_hostView, true);
  953. Application.Begin (_hostView.SuperView as Toplevel);
  954. AddHandlers ();
  955. Assert.NotNull (_scrollBar.OtherScrollBarView);
  956. Assert.NotEqual (_scrollBar, _scrollBar.OtherScrollBarView);
  957. Assert.Equal (_scrollBar.OtherScrollBarView.OtherScrollBarView, _scrollBar);
  958. _hostView.SuperView.Dispose ();
  959. }
  960. [Fact]
  961. [ScrollBarAutoInitShutdown]
  962. public void Scrolling_With_Default_Constructor_Do_Not_Scroll ()
  963. {
  964. var sbv = new ScrollBarView { Position = 1 };
  965. Assert.Equal (1, sbv.Position);
  966. Assert.NotEqual (0, sbv.Position);
  967. sbv.Dispose ();
  968. }
  969. [Fact]
  970. [ScrollBarAutoInitShutdown]
  971. public void ShowScrollIndicator_Check ()
  972. {
  973. _scrollBar = new ScrollBarView (_hostView, true);
  974. RunState rs = Application.Begin (_hostView.SuperView as Toplevel);
  975. AddHandlers ();
  976. Application.RunIteration (ref rs);
  977. Assert.True (_scrollBar.ShowScrollIndicator);
  978. Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator);
  979. _hostView.SuperView.Dispose ();
  980. }
  981. [Fact (Skip = "#3798 broke - Fix with #3498")]
  982. [AutoInitShutdown]
  983. public void ShowScrollIndicator_False_Must_Also_Set_Visible_To_False_To_Not_Respond_To_Events ()
  984. {
  985. // Override CM
  986. Window.DefaultBorderStyle = LineStyle.Single;
  987. Dialog.DefaultButtonAlignment = Alignment.Center;
  988. Dialog.DefaultBorderStyle = LineStyle.Single;
  989. Dialog.DefaultShadow = ShadowStyle.None;
  990. Button.DefaultShadow = ShadowStyle.None;
  991. var clicked = false;
  992. var text = "This is a test\nThis is a test\nThis is a test\nThis is a test\nThis is a test";
  993. var label = new Label { Width = 14, Height = 5, Text = text };
  994. var btn = new Button { X = 14, Text = "Click Me!" };
  995. btn.Accepting += (s, e) => clicked = true;
  996. var top = new Toplevel ();
  997. top.Add (label, btn);
  998. var sbv = new ScrollBarView (label, true, false) { Size = 5 };
  999. Application.Begin (top);
  1000. Application.LayoutAndDrawToplevels ();
  1001. Assert.Equal (5, sbv.Size);
  1002. Assert.Null (sbv.OtherScrollBarView);
  1003. Assert.False (sbv.ShowScrollIndicator);
  1004. Assert.False (sbv.Visible);
  1005. TestHelpers.AssertDriverContentsWithFrameAre (
  1006. @$"
  1007. This is a test{CM.Glyphs.LeftBracket} Click Me! {CM.Glyphs.RightBracket}
  1008. This is a test
  1009. This is a test
  1010. This is a test
  1011. This is a test ",
  1012. _output
  1013. );
  1014. Application.RaiseMouseEvent (new MouseEventArgs { Position = new (15, 0), Flags = MouseFlags.Button1Clicked });
  1015. Assert.Null (Application.MouseGrabView);
  1016. Assert.True (clicked);
  1017. clicked = false;
  1018. sbv.Visible = true;
  1019. Assert.Equal (5, sbv.Size);
  1020. Assert.False (sbv.ShowScrollIndicator);
  1021. Assert.True (sbv.Visible);
  1022. Application.LayoutAndDrawToplevels ();
  1023. Assert.False (sbv.Visible);
  1024. TestHelpers.AssertDriverContentsWithFrameAre (
  1025. @$"
  1026. This is a test{CM.Glyphs.LeftBracket} Click Me! {CM.Glyphs.RightBracket}
  1027. This is a test
  1028. This is a test
  1029. This is a test
  1030. This is a test ",
  1031. _output
  1032. );
  1033. Application.RaiseMouseEvent (new MouseEventArgs { Position = new (15, 0), Flags = MouseFlags.Button1Clicked });
  1034. Assert.Null (Application.MouseGrabView);
  1035. Assert.True (clicked);
  1036. Assert.Equal (5, sbv.Size);
  1037. Assert.False (sbv.ShowScrollIndicator);
  1038. Assert.False (sbv.Visible);
  1039. top.Dispose ();
  1040. }
  1041. [Fact]
  1042. [AutoInitShutdown]
  1043. public void Vertical_Default_Draws_Correctly ()
  1044. {
  1045. var width = 3;
  1046. var height = 40;
  1047. var super = new Window { Id = "super", Width = Dim.Fill (), Height = Dim.Fill () };
  1048. var top = new Toplevel ();
  1049. top.Add (super);
  1050. var sbv = new ScrollBarView
  1051. {
  1052. Id = "sbv",
  1053. Size = height * 2,
  1054. // BUGBUG: ScrollBarView should work if Host is null
  1055. Host = super,
  1056. ShowScrollIndicator = true,
  1057. IsVertical = true
  1058. };
  1059. super.Add (sbv);
  1060. Application.Begin (top);
  1061. ((FakeDriver)Application.Driver!).SetBufferSize (width, height);
  1062. var expected = @"
  1063. ┌─┐
  1064. │▲│
  1065. │┬│
  1066. │││
  1067. │││
  1068. │││
  1069. │││
  1070. │││
  1071. │││
  1072. │││
  1073. │││
  1074. │││
  1075. │││
  1076. │││
  1077. │││
  1078. │││
  1079. │││
  1080. │││
  1081. │││
  1082. │┴│
  1083. │░│
  1084. │░│
  1085. │░│
  1086. │░│
  1087. │░│
  1088. │░│
  1089. │░│
  1090. │░│
  1091. │░│
  1092. │░│
  1093. │░│
  1094. │░│
  1095. │░│
  1096. │░│
  1097. │░│
  1098. │░│
  1099. │░│
  1100. │░│
  1101. │▼│
  1102. └─┘";
  1103. _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  1104. top.Dispose ();
  1105. }
  1106. private void _hostView_DrawContent (object sender, DrawEventArgs e)
  1107. {
  1108. _scrollBar.Size = _hostView.Lines;
  1109. _scrollBar.Position = _hostView.Top;
  1110. _scrollBar.OtherScrollBarView.Size = _hostView.Cols;
  1111. _scrollBar.OtherScrollBarView.Position = _hostView.Left;
  1112. _scrollBar.Refresh ();
  1113. }
  1114. private void _scrollBar_ChangedPosition (object sender, EventArgs e)
  1115. {
  1116. _hostView.Top = _scrollBar.Position;
  1117. if (_hostView.Top != _scrollBar.Position)
  1118. {
  1119. _scrollBar.Position = _hostView.Top;
  1120. }
  1121. _hostView.SetNeedsDraw ();
  1122. }
  1123. private void _scrollBar_OtherScrollBarView_ChangedPosition (object sender, EventArgs e)
  1124. {
  1125. _hostView.Left = _scrollBar.OtherScrollBarView.Position;
  1126. if (_hostView.Left != _scrollBar.OtherScrollBarView.Position)
  1127. {
  1128. _scrollBar.OtherScrollBarView.Position = _hostView.Left;
  1129. }
  1130. _hostView.SetNeedsDraw ();
  1131. }
  1132. private void AddHandlers ()
  1133. {
  1134. if (!_added)
  1135. {
  1136. _hostView.DrawingContent += _hostView_DrawContent;
  1137. _scrollBar.ChangedPosition += _scrollBar_ChangedPosition;
  1138. _scrollBar.OtherScrollBarView.ChangedPosition += _scrollBar_OtherScrollBarView_ChangedPosition;
  1139. }
  1140. _added = true;
  1141. }
  1142. private void RemoveHandlers ()
  1143. {
  1144. if (_added)
  1145. {
  1146. _hostView.DrawingContent -= _hostView_DrawContent;
  1147. _scrollBar.ChangedPosition -= _scrollBar_ChangedPosition;
  1148. _scrollBar.OtherScrollBarView.ChangedPosition -= _scrollBar_OtherScrollBarView_ChangedPosition;
  1149. }
  1150. _added = false;
  1151. }
  1152. public class HostView : View
  1153. {
  1154. public int Cols { get; set; }
  1155. public int Left { get; set; }
  1156. public int Lines { get; set; }
  1157. public int Top { get; set; }
  1158. }
  1159. // This class enables test functions annotated with the [InitShutdown] attribute
  1160. // to have a function called before the test function is called and after.
  1161. //
  1162. // This is necessary because a) Application is a singleton and Init/Shutdown must be called
  1163. // as a pair, and b) all unit test functions should be atomic.
  1164. [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
  1165. public class ScrollBarAutoInitShutdownAttribute : AutoInitShutdownAttribute
  1166. {
  1167. public override void After (MethodInfo methodUnderTest)
  1168. {
  1169. _hostView = null;
  1170. base.After (methodUnderTest);
  1171. }
  1172. public override void Before (MethodInfo methodUnderTest)
  1173. {
  1174. base.Before (methodUnderTest);
  1175. _hostView = new HostView
  1176. {
  1177. Width = Dim.Fill (),
  1178. Height = Dim.Fill (),
  1179. Top = 0,
  1180. Lines = 30,
  1181. Left = 0,
  1182. Cols = 100
  1183. };
  1184. var top = new Toplevel ();
  1185. top.Add (_hostView);
  1186. }
  1187. }
  1188. }