ScrollBarDemo.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. using System.Collections.ObjectModel;
  2. namespace UICatalog.Scenarios;
  3. [ScenarioMetadata ("ScrollBar Demo", "Demonstrates ScrollBar.")]
  4. [ScenarioCategory ("Scrolling")]
  5. public class ScrollBarDemo : Scenario
  6. {
  7. public override void Main ()
  8. {
  9. Application.Init ();
  10. Window app = new ()
  11. {
  12. Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
  13. Arrangement = ViewArrangement.Fixed
  14. };
  15. var demoFrame = new FrameView
  16. {
  17. Title = "Demo View",
  18. X = 0,
  19. Width = 75,
  20. Height = 25 + 4,
  21. SchemeName = "Base",
  22. Arrangement = ViewArrangement.Resizable
  23. };
  24. demoFrame!.Padding!.Thickness = new (1);
  25. demoFrame.Padding.Diagnostics = ViewDiagnosticFlags.Ruler;
  26. app.Add (demoFrame);
  27. var scrollBar = new ScrollBar
  28. {
  29. X = Pos.AnchorEnd () - 5,
  30. AutoShow = false,
  31. ScrollableContentSize = 100,
  32. Height = Dim.Fill ()
  33. };
  34. demoFrame.Add (scrollBar);
  35. ListView controlledList = new ()
  36. {
  37. X = Pos.AnchorEnd (),
  38. Width = 5,
  39. Height = Dim.Fill (),
  40. SchemeName = "Error"
  41. };
  42. demoFrame.Add (controlledList);
  43. // populate the list box with Size items of the form "{n:00000}"
  44. controlledList.SetSource (new ObservableCollection<string> (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}")));
  45. int GetMaxLabelWidth (int groupId)
  46. {
  47. return demoFrame.SubViews.Max (v =>
  48. {
  49. if (v.Y.Has<PosAlign> (out PosAlign pos) && pos.GroupId == groupId)
  50. {
  51. return v.Text.GetColumns ();
  52. }
  53. return 0;
  54. });
  55. }
  56. var lblWidthHeight = new Label
  57. {
  58. Text = "_Width/Height:",
  59. TextAlignment = Alignment.End,
  60. Y = Pos.Align (Alignment.Start, AlignmentModes.StartToEnd, 1),
  61. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  62. };
  63. demoFrame.Add (lblWidthHeight);
  64. NumericUpDown<int> scrollWidthHeight = new ()
  65. {
  66. Value = 1,
  67. X = Pos.Right (lblWidthHeight) + 1,
  68. Y = Pos.Top (lblWidthHeight)
  69. };
  70. demoFrame.Add (scrollWidthHeight);
  71. scrollWidthHeight.ValueChanging += (s, e) =>
  72. {
  73. if (e.NewValue < 1
  74. || e.NewValue
  75. > (scrollBar.Orientation == Orientation.Vertical
  76. ? scrollBar.SuperView?.GetContentSize ().Width
  77. : scrollBar.SuperView?.GetContentSize ().Height))
  78. {
  79. // TODO: This must be handled in the ScrollSlider if Width and Height being virtual
  80. e.Cancel = true;
  81. return;
  82. }
  83. if (scrollBar.Orientation == Orientation.Vertical)
  84. {
  85. scrollBar.Width = e.NewValue;
  86. }
  87. else
  88. {
  89. scrollBar.Height = e.NewValue;
  90. }
  91. };
  92. var lblOrientationLabel = new Label
  93. {
  94. Text = "_Orientation:",
  95. TextAlignment = Alignment.End,
  96. Y = Pos.Align (Alignment.Start, groupId: 1),
  97. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  98. };
  99. demoFrame.Add (lblOrientationLabel);
  100. OptionSelector<Orientation> osOrientation = new ()
  101. {
  102. X = Pos.Right (lblOrientationLabel) + 1,
  103. Y = Pos.Top (lblOrientationLabel),
  104. AssignHotKeys = true,
  105. Orientation = Orientation.Horizontal
  106. };
  107. demoFrame.Add (osOrientation);
  108. osOrientation.ValueChanged += (s, e) =>
  109. {
  110. if (osOrientation.Value == Orientation.Horizontal)
  111. {
  112. scrollBar.Orientation = Orientation.Vertical;
  113. scrollBar.X = Pos.AnchorEnd () - 5;
  114. scrollBar.Y = 0;
  115. scrollBar.Width = scrollWidthHeight.Value;
  116. scrollBar.Height = Dim.Fill ();
  117. controlledList.Visible = true;
  118. }
  119. else
  120. {
  121. scrollBar.Orientation = Orientation.Horizontal;
  122. scrollBar.X = 0;
  123. scrollBar.Y = Pos.AnchorEnd ();
  124. scrollBar.Height = scrollWidthHeight.Value;
  125. scrollBar.Width = Dim.Fill ();
  126. controlledList.Visible = false;
  127. }
  128. };
  129. var lblSize = new Label
  130. {
  131. Text = "Scrollable_ContentSize:",
  132. TextAlignment = Alignment.End,
  133. Y = Pos.Align (Alignment.Start, groupId: 1),
  134. Width = Dim.Func (_ => GetMaxLabelWidth (1))
  135. };
  136. demoFrame.Add (lblSize);
  137. NumericUpDown<int> scrollContentSize = new ()
  138. {
  139. Value = scrollBar.ScrollableContentSize,
  140. X = Pos.Right (lblSize) + 1,
  141. Y = Pos.Top (lblSize)
  142. };
  143. demoFrame.Add (scrollContentSize);
  144. scrollContentSize.ValueChanging += (s, e) =>
  145. {
  146. if (e.NewValue < 0)
  147. {
  148. e.Cancel = true;
  149. return;
  150. }
  151. if (scrollBar.ScrollableContentSize != e.NewValue)
  152. {
  153. scrollBar.ScrollableContentSize = e.NewValue;
  154. controlledList.SetSource (
  155. new ObservableCollection<string> (
  156. Enumerable.Range (0, scrollBar.ScrollableContentSize)
  157. .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. }