ScrollBarDemo.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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. OptionSelector<Orientation> osOrientation = new ()
  104. {
  105. X = Pos.Right (lblOrientationLabel) + 1,
  106. Y = Pos.Top (lblOrientationLabel),
  107. AssignHotKeys = true,
  108. Orientation = Orientation.Horizontal
  109. };
  110. demoFrame.Add (osOrientation);
  111. osOrientation.ValueChanged += (s, e) =>
  112. {
  113. if (osOrientation.Value == Orientation.Horizontal)
  114. {
  115. scrollBar.Orientation = Orientation.Vertical;
  116. scrollBar.X = Pos.AnchorEnd () - 5;
  117. scrollBar.Y = 0;
  118. scrollBar.Width = scrollWidthHeight.Value;
  119. scrollBar.Height = Dim.Fill ();
  120. controlledList.Visible = true;
  121. }
  122. else
  123. {
  124. scrollBar.Orientation = Orientation.Horizontal;
  125. scrollBar.X = 0;
  126. scrollBar.Y = Pos.AnchorEnd ();
  127. scrollBar.Height = scrollWidthHeight.Value;
  128. scrollBar.Width = Dim.Fill ();
  129. controlledList.Visible = false;
  130. }
  131. };
  132. var lblSize = new Label
  133. {
  134. Text = "Scrollable_ContentSize:",
  135. TextAlignment = Alignment.End,
  136. Y = Pos.Align (Alignment.Start, groupId: 1),
  137. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  138. };
  139. demoFrame.Add (lblSize);
  140. NumericUpDown<int> scrollContentSize = new ()
  141. {
  142. Value = scrollBar.ScrollableContentSize,
  143. X = Pos.Right (lblSize) + 1,
  144. Y = Pos.Top (lblSize)
  145. };
  146. demoFrame.Add (scrollContentSize);
  147. scrollContentSize.ValueChanging += (s, e) =>
  148. {
  149. if (e.NewValue < 0)
  150. {
  151. e.Cancel = true;
  152. return;
  153. }
  154. if (scrollBar.ScrollableContentSize != e.NewValue)
  155. {
  156. scrollBar.ScrollableContentSize = e.NewValue;
  157. controlledList.SetSource (new ObservableCollection<string> (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}")));
  158. }
  159. };
  160. var lblVisibleContentSize = new Label
  161. {
  162. Text = "_VisibleContentSize:",
  163. TextAlignment = Alignment.End,
  164. Y = Pos.Align (Alignment.Start, groupId: 1),
  165. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  166. };
  167. demoFrame.Add (lblVisibleContentSize);
  168. NumericUpDown<int> visibleContentSize = new ()
  169. {
  170. Value = scrollBar.VisibleContentSize,
  171. X = Pos.Right (lblVisibleContentSize) + 1,
  172. Y = Pos.Top (lblVisibleContentSize)
  173. };
  174. demoFrame.Add (visibleContentSize);
  175. visibleContentSize.ValueChanging += (s, e) =>
  176. {
  177. if (e.NewValue < 0)
  178. {
  179. e.Cancel = true;
  180. return;
  181. }
  182. if (scrollBar.VisibleContentSize != e.NewValue)
  183. {
  184. scrollBar.VisibleContentSize = e.NewValue;
  185. }
  186. };
  187. var lblPosition = new Label
  188. {
  189. Text = "_Position:",
  190. TextAlignment = Alignment.End,
  191. Y = Pos.Align (Alignment.Start, groupId: 1),
  192. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  193. };
  194. demoFrame.Add (lblPosition);
  195. NumericUpDown<int> scrollPosition = new ()
  196. {
  197. Value = scrollBar.GetSliderPosition (),
  198. X = Pos.Right (lblPosition) + 1,
  199. Y = Pos.Top (lblPosition)
  200. };
  201. demoFrame.Add (scrollPosition);
  202. scrollPosition.ValueChanging += (s, e) =>
  203. {
  204. if (e.NewValue < 0)
  205. {
  206. e.Cancel = true;
  207. return;
  208. }
  209. if (scrollBar.Position != e.NewValue)
  210. {
  211. scrollBar.Position = e.NewValue;
  212. }
  213. if (scrollBar.Position != e.NewValue)
  214. {
  215. e.Cancel = true;
  216. }
  217. };
  218. var lblOptions = new Label
  219. {
  220. Text = "Options:",
  221. TextAlignment = Alignment.End,
  222. Y = Pos.Align (Alignment.Start, groupId: 1),
  223. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  224. };
  225. demoFrame.Add (lblOptions);
  226. var autoShow = new CheckBox
  227. {
  228. Y = Pos.Top (lblOptions),
  229. X = Pos.Right (lblOptions) + 1,
  230. Text = $"_AutoShow",
  231. CheckedState = scrollBar.AutoShow ? CheckState.Checked : CheckState.UnChecked
  232. };
  233. autoShow.CheckedStateChanging += (s, e) => scrollBar.AutoShow = e.Result == CheckState.Checked;
  234. demoFrame.Add (autoShow);
  235. var lblSliderPosition = new Label
  236. {
  237. Text = "SliderPosition:",
  238. TextAlignment = Alignment.End,
  239. Y = Pos.Align (Alignment.Start, groupId: 1),
  240. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  241. };
  242. demoFrame.Add (lblSliderPosition);
  243. Label scrollSliderPosition = new ()
  244. {
  245. Text = scrollBar.GetSliderPosition ().ToString (),
  246. X = Pos.Right (lblSliderPosition) + 1,
  247. Y = Pos.Top (lblSliderPosition)
  248. };
  249. demoFrame.Add (scrollSliderPosition);
  250. var lblScrolled = new Label
  251. {
  252. Text = "Scrolled:",
  253. TextAlignment = Alignment.End,
  254. Y = Pos.Align (Alignment.Start, groupId: 1),
  255. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  256. };
  257. demoFrame.Add (lblScrolled);
  258. Label scrolled = new ()
  259. {
  260. X = Pos.Right (lblScrolled) + 1,
  261. Y = Pos.Top (lblScrolled)
  262. };
  263. demoFrame.Add (scrolled);
  264. var lblScrollFrame = new Label
  265. {
  266. Y = Pos.Bottom (lblScrolled) + 1
  267. };
  268. demoFrame.Add (lblScrollFrame);
  269. var lblScrollViewport = new Label
  270. {
  271. Y = Pos.Bottom (lblScrollFrame)
  272. };
  273. demoFrame.Add (lblScrollViewport);
  274. var lblScrollContentSize = new Label
  275. {
  276. Y = Pos.Bottom (lblScrollViewport)
  277. };
  278. demoFrame.Add (lblScrollContentSize);
  279. scrollBar.SubViewsLaidOut += (s, e) =>
  280. {
  281. lblScrollFrame.Text = $"Scroll Frame: {scrollBar.Frame.ToString ()}";
  282. lblScrollViewport.Text = $"Scroll Viewport: {scrollBar.Viewport.ToString ()}";
  283. lblScrollContentSize.Text = $"Scroll ContentSize: {scrollBar.GetContentSize ().ToString ()}";
  284. visibleContentSize.Value = scrollBar.VisibleContentSize;
  285. };
  286. EventLog eventLog = new ()
  287. {
  288. X = Pos.AnchorEnd (),
  289. Y = 0,
  290. Height = Dim.Fill (),
  291. BorderStyle = LineStyle.Single,
  292. ViewToLog = scrollBar
  293. };
  294. app.Add (eventLog);
  295. app.Initialized += AppOnInitialized;
  296. void AppOnInitialized (object sender, EventArgs e)
  297. {
  298. scrollBar.ScrollableContentSizeChanged += (s, e) =>
  299. {
  300. eventLog.Log ($"SizeChanged: {e.Value}");
  301. if (scrollContentSize.Value != e.Value)
  302. {
  303. scrollContentSize.Value = e.Value;
  304. }
  305. };
  306. scrollBar.SliderPositionChanged += (s, e) =>
  307. {
  308. eventLog.Log ($"SliderPositionChanged: {e.Value}");
  309. eventLog.Log ($" Position: {scrollBar.Position}");
  310. scrollSliderPosition.Text = e.Value.ToString ();
  311. };
  312. scrollBar.Scrolled += (s, e) =>
  313. {
  314. eventLog.Log ($"Scrolled: {e.Value}");
  315. eventLog.Log ($" SliderPosition: {scrollBar.GetSliderPosition ()}");
  316. scrolled.Text = e.Value.ToString ();
  317. };
  318. scrollBar.PositionChanged += (s, e) =>
  319. {
  320. eventLog.Log ($"PositionChanged: {e.Value}");
  321. scrollPosition.Value = e.Value;
  322. controlledList.Viewport = controlledList.Viewport with { Y = e.Value };
  323. };
  324. controlledList.ViewportChanged += (s, e) =>
  325. {
  326. eventLog.Log ($"ViewportChanged: {e.NewViewport}");
  327. scrollBar.Position = e.NewViewport.Y;
  328. };
  329. }
  330. Application.Run (app);
  331. app.Dispose ();
  332. Application.Shutdown ();
  333. }
  334. }