ScrollBarDemo.cs 16 KB

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