ScrollBarDemo.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.Linq;
  4. using Terminal.Gui;
  5. namespace UICatalog.Scenarios;
  6. [ScenarioMetadata ("ScrollBar Demo", "Demonstrates ScrollBar.")]
  7. [ScenarioCategory ("Scrolling")]
  8. public class ScrollBarDemo : Scenario
  9. {
  10. public override void Main ()
  11. {
  12. Application.Init ();
  13. Window app = new ()
  14. {
  15. Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
  16. Arrangement = ViewArrangement.Fixed
  17. };
  18. var demoFrame = new FrameView ()
  19. {
  20. Title = "Demo View",
  21. X = 0,
  22. Width = 75,
  23. Height = 25 + 4,
  24. ColorScheme = Colors.ColorSchemes ["Base"],
  25. Arrangement = ViewArrangement.Resizable
  26. };
  27. demoFrame!.Padding!.Thickness = new (1);
  28. demoFrame.Padding.Diagnostics = ViewDiagnosticFlags.Ruler;
  29. app.Add (demoFrame);
  30. var scrollBar = new ScrollBar
  31. {
  32. X = Pos.AnchorEnd () - 5,
  33. AutoShow = false,
  34. ScrollableContentSize = 100,
  35. Height = Dim.Fill()
  36. };
  37. demoFrame.Add (scrollBar);
  38. ListView controlledList = new ()
  39. {
  40. X = Pos.AnchorEnd (),
  41. Width = 5,
  42. Height = Dim.Fill (),
  43. ColorScheme = Colors.ColorSchemes ["Error"],
  44. };
  45. demoFrame.Add (controlledList);
  46. // populate the list box with Size items of the form "{n:00000}"
  47. controlledList.SetSource (new ObservableCollection<string> (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}")));
  48. int GetMaxLabelWidth (int groupId)
  49. {
  50. return demoFrame.Subviews.Max (
  51. v =>
  52. {
  53. if (v.Y.Has<PosAlign> (out var pos) && pos.GroupId == groupId)
  54. {
  55. return v.Text.GetColumns ();
  56. }
  57. return 0;
  58. });
  59. }
  60. var lblWidthHeight = new Label
  61. {
  62. Text = "_Width/Height:",
  63. TextAlignment = Alignment.End,
  64. Y = Pos.Align (Alignment.Start, AlignmentModes.StartToEnd, groupId: 1),
  65. Width = Dim.Func (() => GetMaxLabelWidth (1))
  66. };
  67. demoFrame.Add (lblWidthHeight);
  68. NumericUpDown<int> scrollWidthHeight = new ()
  69. {
  70. Value = 1,
  71. X = Pos.Right (lblWidthHeight) + 1,
  72. Y = Pos.Top (lblWidthHeight),
  73. };
  74. demoFrame.Add (scrollWidthHeight);
  75. scrollWidthHeight.ValueChanging += (s, e) =>
  76. {
  77. if (e.NewValue < 1
  78. || (e.NewValue
  79. > (scrollBar.Orientation == Orientation.Vertical
  80. ? scrollBar.SuperView?.GetContentSize ().Width
  81. : scrollBar.SuperView?.GetContentSize ().Height)))
  82. {
  83. // TODO: This must be handled in the ScrollSlider if Width and Height being virtual
  84. e.Cancel = true;
  85. return;
  86. }
  87. if (scrollBar.Orientation == Orientation.Vertical)
  88. {
  89. scrollBar.Width = e.NewValue;
  90. }
  91. else
  92. {
  93. scrollBar.Height = e.NewValue;
  94. }
  95. };
  96. var lblOrientationLabel = new Label
  97. {
  98. Text = "_Orientation:",
  99. TextAlignment = Alignment.End,
  100. Y = Pos.Align (Alignment.Start, groupId: 1),
  101. Width = Dim.Func (() => GetMaxLabelWidth (1))
  102. };
  103. demoFrame.Add (lblOrientationLabel);
  104. var rgOrientation = new RadioGroup
  105. {
  106. X = Pos.Right (lblOrientationLabel) + 1,
  107. Y = Pos.Top (lblOrientationLabel),
  108. RadioLabels = ["Vertical", "Horizontal"],
  109. Orientation = Orientation.Horizontal
  110. };
  111. demoFrame.Add (rgOrientation);
  112. rgOrientation.SelectedItemChanged += (s, e) =>
  113. {
  114. if (e.SelectedItem == e.PreviousSelectedItem)
  115. {
  116. return;
  117. }
  118. if (rgOrientation.SelectedItem == 0)
  119. {
  120. scrollBar.Orientation = Orientation.Vertical;
  121. scrollBar.X = Pos.AnchorEnd () - 5;
  122. scrollBar.Y = 0;
  123. scrollBar.Width = scrollWidthHeight.Value;
  124. scrollBar.Height = Dim.Fill ();
  125. controlledList.Visible = true;
  126. }
  127. else
  128. {
  129. scrollBar.Orientation = Orientation.Horizontal;
  130. scrollBar.X = 0;
  131. scrollBar.Y = Pos.AnchorEnd ();
  132. scrollBar.Height = scrollWidthHeight.Value;
  133. scrollBar.Width = Dim.Fill ();
  134. controlledList.Visible = false;
  135. }
  136. };
  137. var lblSize = new Label
  138. {
  139. Text = "Scrollable_ContentSize:",
  140. TextAlignment = Alignment.End,
  141. Y = Pos.Align (Alignment.Start, groupId: 1),
  142. Width = Dim.Func (() => GetMaxLabelWidth (1))
  143. };
  144. demoFrame.Add (lblSize);
  145. NumericUpDown<int> scrollContentSize = new ()
  146. {
  147. Value = scrollBar.ScrollableContentSize,
  148. X = Pos.Right (lblSize) + 1,
  149. Y = Pos.Top (lblSize)
  150. };
  151. demoFrame.Add (scrollContentSize);
  152. scrollContentSize.ValueChanging += (s, e) =>
  153. {
  154. if (e.NewValue < 0)
  155. {
  156. e.Cancel = true;
  157. return;
  158. }
  159. if (scrollBar.ScrollableContentSize != e.NewValue)
  160. {
  161. scrollBar.ScrollableContentSize = e.NewValue;
  162. controlledList.SetSource (new ObservableCollection<string> (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}")));
  163. }
  164. };
  165. var lblVisibleContentSize = new Label
  166. {
  167. Text = "_VisibleContentSize:",
  168. TextAlignment = Alignment.End,
  169. Y = Pos.Align (Alignment.Start, groupId: 1),
  170. Width = Dim.Func (() => GetMaxLabelWidth (1))
  171. };
  172. demoFrame.Add (lblVisibleContentSize);
  173. NumericUpDown<int> visibleContentSize = new ()
  174. {
  175. Value = scrollBar.VisibleContentSize,
  176. X = Pos.Right (lblVisibleContentSize) + 1,
  177. Y = Pos.Top (lblVisibleContentSize)
  178. };
  179. demoFrame.Add (visibleContentSize);
  180. visibleContentSize.ValueChanging += (s, e) =>
  181. {
  182. if (e.NewValue < 0)
  183. {
  184. e.Cancel = true;
  185. return;
  186. }
  187. if (scrollBar.VisibleContentSize != e.NewValue)
  188. {
  189. scrollBar.VisibleContentSize = e.NewValue;
  190. }
  191. };
  192. var lblPosition = new Label
  193. {
  194. Text = "_Position:",
  195. TextAlignment = Alignment.End,
  196. Y = Pos.Align (Alignment.Start, groupId: 1),
  197. Width = Dim.Func (() => GetMaxLabelWidth (1))
  198. };
  199. demoFrame.Add (lblPosition);
  200. NumericUpDown<int> scrollPosition = new ()
  201. {
  202. Value = scrollBar.GetSliderPosition (),
  203. X = Pos.Right (lblPosition) + 1,
  204. Y = Pos.Top (lblPosition)
  205. };
  206. demoFrame.Add (scrollPosition);
  207. scrollPosition.ValueChanging += (s, e) =>
  208. {
  209. if (e.NewValue < 0)
  210. {
  211. e.Cancel = true;
  212. return;
  213. }
  214. if (scrollBar.Position != e.NewValue)
  215. {
  216. scrollBar.Position = e.NewValue;
  217. }
  218. if (scrollBar.Position != e.NewValue)
  219. {
  220. e.Cancel = true;
  221. }
  222. };
  223. var lblOptions = new Label
  224. {
  225. Text = "Options:",
  226. TextAlignment = Alignment.End,
  227. Y = Pos.Align (Alignment.Start, groupId: 1),
  228. Width = Dim.Func (() => GetMaxLabelWidth (1))
  229. };
  230. demoFrame.Add (lblOptions);
  231. var autoShow = new CheckBox
  232. {
  233. Y = Pos.Top (lblOptions),
  234. X = Pos.Right (lblOptions) + 1,
  235. Text = $"_AutoShow",
  236. CheckedState = scrollBar.AutoShow ? CheckState.Checked : CheckState.UnChecked
  237. };
  238. autoShow.CheckedStateChanging += (s, e) => scrollBar.AutoShow = e.NewValue == CheckState.Checked;
  239. demoFrame.Add (autoShow);
  240. var lblSliderPosition = new Label
  241. {
  242. Text = "SliderPosition:",
  243. TextAlignment = Alignment.End,
  244. Y = Pos.Align (Alignment.Start, groupId: 1),
  245. Width = Dim.Func (() => GetMaxLabelWidth (1))
  246. };
  247. demoFrame.Add (lblSliderPosition);
  248. Label scrollSliderPosition = new ()
  249. {
  250. Text = scrollBar.GetSliderPosition ().ToString (),
  251. X = Pos.Right (lblSliderPosition) + 1,
  252. Y = Pos.Top (lblSliderPosition)
  253. };
  254. demoFrame.Add (scrollSliderPosition);
  255. var lblScrolled = new Label
  256. {
  257. Text = "Scrolled:",
  258. TextAlignment = Alignment.End,
  259. Y = Pos.Align (Alignment.Start, groupId: 1),
  260. Width = Dim.Func (() => GetMaxLabelWidth (1))
  261. };
  262. demoFrame.Add (lblScrolled);
  263. Label scrolled = new ()
  264. {
  265. X = Pos.Right (lblScrolled) + 1,
  266. Y = Pos.Top (lblScrolled)
  267. };
  268. demoFrame.Add (scrolled);
  269. var lblScrollFrame = new Label
  270. {
  271. Y = Pos.Bottom (lblScrolled) + 1
  272. };
  273. demoFrame.Add (lblScrollFrame);
  274. var lblScrollViewport = new Label
  275. {
  276. Y = Pos.Bottom (lblScrollFrame)
  277. };
  278. demoFrame.Add (lblScrollViewport);
  279. var lblScrollContentSize = new Label
  280. {
  281. Y = Pos.Bottom (lblScrollViewport)
  282. };
  283. demoFrame.Add (lblScrollContentSize);
  284. scrollBar.SubviewsLaidOut += (s, e) =>
  285. {
  286. lblScrollFrame.Text = $"Scroll Frame: {scrollBar.Frame.ToString ()}";
  287. lblScrollViewport.Text = $"Scroll Viewport: {scrollBar.Viewport.ToString ()}";
  288. lblScrollContentSize.Text = $"Scroll ContentSize: {scrollBar.GetContentSize ().ToString ()}";
  289. visibleContentSize.Value = scrollBar.VisibleContentSize;
  290. };
  291. EventLog eventLog = new ()
  292. {
  293. X = Pos.AnchorEnd (),
  294. Y = 0,
  295. Height = Dim.Fill (),
  296. BorderStyle = LineStyle.Single,
  297. ViewToLog = scrollBar
  298. };
  299. app.Add (eventLog);
  300. app.Initialized += AppOnInitialized;
  301. void AppOnInitialized (object sender, EventArgs e)
  302. {
  303. scrollBar.ScrollableContentSizeChanged += (s, e) =>
  304. {
  305. eventLog.Log ($"SizeChanged: {e.CurrentValue}");
  306. if (scrollContentSize.Value != e.CurrentValue)
  307. {
  308. scrollContentSize.Value = e.CurrentValue;
  309. }
  310. };
  311. scrollBar.SliderPositionChanged += (s, e) =>
  312. {
  313. eventLog.Log ($"SliderPositionChanged: {e.CurrentValue}");
  314. eventLog.Log ($" Position: {scrollBar.Position}");
  315. scrollSliderPosition.Text = e.CurrentValue.ToString ();
  316. };
  317. scrollBar.Scrolled += (s, e) =>
  318. {
  319. eventLog.Log ($"Scrolled: {e.CurrentValue}");
  320. eventLog.Log ($" SliderPosition: {scrollBar.GetSliderPosition ()}");
  321. scrolled.Text = e.CurrentValue.ToString ();
  322. };
  323. scrollBar.PositionChanged += (s, e) =>
  324. {
  325. eventLog.Log ($"PositionChanged: {e.CurrentValue}");
  326. scrollPosition.Value = e.CurrentValue;
  327. controlledList.Viewport = controlledList.Viewport with { Y = e.CurrentValue };
  328. };
  329. controlledList.ViewportChanged += (s, e) =>
  330. {
  331. eventLog.Log ($"ViewportChanged: {e.NewViewport}");
  332. scrollBar.Position = e.NewViewport.Y;
  333. };
  334. }
  335. Application.Run (app);
  336. app.Dispose ();
  337. Application.Shutdown ();
  338. }
  339. }