ListColumns.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. namespace UICatalog.Scenarios;
  6. [ScenarioMetadata ("ListColumns", "Implements a columned list via a data table.")]
  7. [ScenarioCategory ("TableView")]
  8. [ScenarioCategory ("Controls")]
  9. [ScenarioCategory ("Dialogs")]
  10. [ScenarioCategory ("Text and Formatting")]
  11. [ScenarioCategory ("Scrolling")]
  12. public class ListColumns : Scenario
  13. {
  14. private Scheme _alternatingScheme;
  15. private DataTable _currentTable;
  16. private TableView _listColView;
  17. private MenuItem _miAlternatingColors;
  18. private MenuItem _miAlwaysUseNormalColorForVerticalCellLines;
  19. private MenuItem _miBottomline;
  20. private MenuItem _miCellLines;
  21. private MenuItem _miCursor;
  22. private MenuItem _miExpandLastColumn;
  23. private MenuItem _miOrientVertical;
  24. private MenuItem _miScrollParallel;
  25. private MenuItem _miSmoothScrolling;
  26. private MenuItem _miTopline;
  27. /// <summary>
  28. /// Builds a simple list in which values are the index. This helps testing that scrolling etc is working
  29. /// correctly and not skipping out values when paging
  30. /// </summary>
  31. /// <param name="items"></param>
  32. /// <returns></returns>
  33. public static IList BuildSimpleList (int items)
  34. {
  35. List<object> list = new ();
  36. for (var i = 0; i < items; i++)
  37. {
  38. list.Add ("Item " + i);
  39. }
  40. return list;
  41. }
  42. public override void Main ()
  43. {
  44. // Init
  45. Application.Init ();
  46. // Setup - Create a top-level application window and configure it.
  47. Toplevel top = new ();
  48. Window appWindow = new ()
  49. {
  50. Title = GetQuitKeyAndName ()
  51. };
  52. _listColView = new ()
  53. {
  54. Width = Dim.Fill (),
  55. Height = Dim.Fill (),
  56. Style = new ()
  57. {
  58. ShowHeaders = false,
  59. ShowHorizontalHeaderOverline = false,
  60. ShowHorizontalHeaderUnderline = false,
  61. ShowHorizontalBottomline = false,
  62. ExpandLastColumn = false
  63. }
  64. };
  65. var listColStyle = new ListColumnStyle ();
  66. var menu = new MenuBar
  67. {
  68. Menus =
  69. [
  70. new (
  71. "_File",
  72. new MenuItem []
  73. {
  74. new (
  75. "Open_BigListExample",
  76. "",
  77. () => OpenSimpleList (true)
  78. ),
  79. new (
  80. "Open_SmListExample",
  81. "",
  82. () => OpenSimpleList (false)
  83. ),
  84. new (
  85. "_CloseExample",
  86. "",
  87. () => CloseExample ()
  88. ),
  89. new ("_Quit", "", () => Quit ())
  90. }
  91. ),
  92. new (
  93. "_View",
  94. new []
  95. {
  96. _miTopline =
  97. new ("_TopLine", "", () => ToggleTopline ())
  98. {
  99. Checked = _listColView.Style
  100. .ShowHorizontalHeaderOverline,
  101. CheckType = MenuItemCheckStyle.Checked
  102. },
  103. _miBottomline = new (
  104. "_BottomLine",
  105. "",
  106. () => ToggleBottomline ()
  107. )
  108. {
  109. Checked = _listColView.Style
  110. .ShowHorizontalBottomline,
  111. CheckType = MenuItemCheckStyle.Checked
  112. },
  113. _miCellLines = new (
  114. "_CellLines",
  115. "",
  116. () => ToggleCellLines ()
  117. )
  118. {
  119. Checked = _listColView.Style
  120. .ShowVerticalCellLines,
  121. CheckType = MenuItemCheckStyle.Checked
  122. },
  123. _miExpandLastColumn = new (
  124. "_ExpandLastColumn",
  125. "",
  126. () => ToggleExpandLastColumn ()
  127. )
  128. {
  129. Checked = _listColView.Style.ExpandLastColumn,
  130. CheckType = MenuItemCheckStyle.Checked
  131. },
  132. _miAlwaysUseNormalColorForVerticalCellLines =
  133. new (
  134. "_AlwaysUseNormalColorForVerticalCellLines",
  135. "",
  136. () =>
  137. ToggleAlwaysUseNormalColorForVerticalCellLines ()
  138. )
  139. {
  140. Checked = _listColView.Style
  141. .AlwaysUseNormalColorForVerticalCellLines,
  142. CheckType = MenuItemCheckStyle.Checked
  143. },
  144. _miSmoothScrolling = new (
  145. "_SmoothHorizontalScrolling",
  146. "",
  147. () => ToggleSmoothScrolling ()
  148. )
  149. {
  150. Checked = _listColView.Style
  151. .SmoothHorizontalScrolling,
  152. CheckType = MenuItemCheckStyle.Checked
  153. },
  154. _miAlternatingColors = new (
  155. "Alternating Colors",
  156. "",
  157. () => ToggleAlternatingColors ()
  158. ) { CheckType = MenuItemCheckStyle.Checked },
  159. _miCursor = new (
  160. "Invert Selected Cell First Character",
  161. "",
  162. () =>
  163. ToggleInvertSelectedCellFirstCharacter ()
  164. )
  165. {
  166. Checked = _listColView.Style
  167. .InvertSelectedCellFirstCharacter,
  168. CheckType = MenuItemCheckStyle.Checked
  169. }
  170. }
  171. ),
  172. new (
  173. "_List",
  174. new []
  175. {
  176. //new MenuItem ("_Hide Headers", "", HideHeaders),
  177. _miOrientVertical = new (
  178. "_OrientVertical",
  179. "",
  180. () => ToggleVerticalOrientation ()
  181. )
  182. {
  183. Checked = listColStyle.Orientation
  184. == Orientation.Vertical,
  185. CheckType = MenuItemCheckStyle.Checked
  186. },
  187. _miScrollParallel = new (
  188. "_ScrollParallel",
  189. "",
  190. () => ToggleScrollParallel ()
  191. )
  192. {
  193. Checked = listColStyle.ScrollParallel,
  194. CheckType = MenuItemCheckStyle.Checked
  195. },
  196. new ("Set _Max Cell Width", "", SetListMaxWidth),
  197. new ("Set Mi_n Cell Width", "", SetListMinWidth)
  198. }
  199. )
  200. ]
  201. };
  202. var statusBar = new StatusBar (
  203. new Shortcut []
  204. {
  205. new (Key.F2, "OpenBigListEx", () => OpenSimpleList (true)),
  206. new (Key.F3, "CloseExample", CloseExample),
  207. new (Key.F4, "OpenSmListEx", () => OpenSimpleList (false)),
  208. new (Application.QuitKey, "Quit", Quit)
  209. }
  210. );
  211. appWindow.Add (_listColView);
  212. var selectedCellLabel = new Label
  213. {
  214. X = 0,
  215. Y = Pos.Bottom (_listColView),
  216. Text = "0,0",
  217. Width = Dim.Fill (),
  218. TextAlignment = Alignment.End
  219. };
  220. appWindow.Add (selectedCellLabel);
  221. _listColView.SelectedCellChanged += (s, e) => { selectedCellLabel.Text = $"{_listColView.SelectedRow},{_listColView.SelectedColumn}"; };
  222. _listColView.KeyDown += TableViewKeyPress;
  223. //SetupScrollBar ();
  224. _alternatingScheme = new ()
  225. {
  226. Disabled = appWindow.GetAttributeForRole(VisualRole.Disabled),
  227. HotFocus = appWindow.GetAttributeForRole (VisualRole.HotFocus),
  228. Focus = appWindow.GetAttributeForRole(VisualRole.Focus),
  229. Normal = new (Color.White, Color.BrightBlue)
  230. };
  231. // if user clicks the mouse in TableView
  232. _listColView.MouseClick += (s, e) => { _listColView.ScreenToCell (e.Position, out int? clickedCol); };
  233. _listColView.KeyBindings.ReplaceCommands (Key.Space, Command.Accept);
  234. top.Add (menu, appWindow, statusBar);
  235. appWindow.Y = 1;
  236. appWindow.Height = Dim.Fill(Dim.Func (_ => statusBar.Frame.Height));
  237. // Run - Start the application.
  238. Application.Run (top);
  239. top.Dispose ();
  240. // Shutdown - Calling Application.Shutdown is required.
  241. Application.Shutdown ();
  242. }
  243. private void CloseExample () { _listColView.Table = null; }
  244. private void OpenSimpleList (bool big) { SetTable (BuildSimpleList (big ? 1023 : 31)); }
  245. private void Quit () { Application.RequestStop (); }
  246. private void RunListWidthDialog (string prompt, Action<TableView, int> setter, Func<TableView, int> getter)
  247. {
  248. var accepted = false;
  249. var ok = new Button { Text = "Ok", IsDefault = true };
  250. ok.Accepting += (s, e) =>
  251. {
  252. accepted = true;
  253. Application.RequestStop ();
  254. };
  255. var cancel = new Button { Text = "Cancel" };
  256. cancel.Accepting += (s, e) => { Application.RequestStop (); };
  257. var d = new Dialog { Title = prompt, Buttons = [ok, cancel] };
  258. var tf = new TextField { Text = getter (_listColView).ToString (), X = 0, Y = 0, Width = Dim.Fill () };
  259. d.Add (tf);
  260. tf.SetFocus ();
  261. Application.Run (d);
  262. d.Dispose ();
  263. if (accepted)
  264. {
  265. try
  266. {
  267. setter (_listColView, int.Parse (tf.Text));
  268. }
  269. catch (Exception ex)
  270. {
  271. MessageBox.ErrorQuery (60, 20, "Failed to set", ex.Message, "Ok");
  272. }
  273. }
  274. }
  275. private void SetListMaxWidth ()
  276. {
  277. RunListWidthDialog ("MaxCellWidth", (s, v) => s.MaxCellWidth = v, s => s.MaxCellWidth);
  278. _listColView.SetNeedsDraw ();
  279. }
  280. private void SetListMinWidth ()
  281. {
  282. RunListWidthDialog ("MinCellWidth", (s, v) => s.MinCellWidth = v, s => s.MinCellWidth);
  283. _listColView.SetNeedsDraw ();
  284. }
  285. private void SetTable (IList list)
  286. {
  287. _listColView.Table = new ListTableSource (list, _listColView);
  288. if ((ListTableSource)_listColView.Table != null)
  289. {
  290. _currentTable = ((ListTableSource)_listColView.Table).DataTable;
  291. }
  292. }
  293. //private void SetupScrollBar ()
  294. //{
  295. // var scrollBar = new ScrollBarView (_listColView, true); // (listColView, true, true);
  296. // scrollBar.ChangedPosition += (s, e) =>
  297. // {
  298. // _listColView.RowOffset = scrollBar.Position;
  299. // if (_listColView.RowOffset != scrollBar.Position)
  300. // {
  301. // scrollBar.Position = _listColView.RowOffset;
  302. // }
  303. // _listColView.SetNeedsDraw ();
  304. // };
  305. // /*
  306. // scrollBar.OtherScrollBarView.ChangedPosition += (s,e) => {
  307. // listColView.ColumnOffset = scrollBar.OtherScrollBarView.Position;
  308. // if (listColView.ColumnOffset != scrollBar.OtherScrollBarView.Position) {
  309. // scrollBar.OtherScrollBarView.Position = listColView.ColumnOffset;
  310. // }
  311. // listColView.SetNeedsDraw ();
  312. // };
  313. // */
  314. // _listColView.DrawingContent += (s, e) =>
  315. // {
  316. // scrollBar.Size = _listColView.Table?.Rows ?? 0;
  317. // scrollBar.Position = _listColView.RowOffset;
  318. // //scrollBar.OtherScrollBarView.Size = listColView.Table?.Columns - 1 ?? 0;
  319. // //scrollBar.OtherScrollBarView.Position = listColView.ColumnOffset;
  320. // scrollBar.Refresh ();
  321. // };
  322. //}
  323. private void TableViewKeyPress (object sender, Key e)
  324. {
  325. if (e.KeyCode == Key.Delete)
  326. {
  327. // set all selected cells to null
  328. foreach (Point pt in _listColView.GetAllSelectedCells ())
  329. {
  330. _currentTable.Rows [pt.Y] [pt.X] = DBNull.Value;
  331. }
  332. _listColView.Update ();
  333. e.Handled = true;
  334. }
  335. }
  336. private void ToggleAlternatingColors ()
  337. {
  338. //toggle menu item
  339. _miAlternatingColors.Checked = !_miAlternatingColors.Checked;
  340. if (_miAlternatingColors.Checked == true)
  341. {
  342. _listColView.Style.RowColorGetter = a => { return a.RowIndex % 2 == 0 ? _alternatingScheme : null; };
  343. }
  344. else
  345. {
  346. _listColView.Style.RowColorGetter = null;
  347. }
  348. _listColView.SetNeedsDraw ();
  349. }
  350. private void ToggleAlwaysUseNormalColorForVerticalCellLines ()
  351. {
  352. _miAlwaysUseNormalColorForVerticalCellLines.Checked =
  353. !_miAlwaysUseNormalColorForVerticalCellLines.Checked;
  354. _listColView.Style.AlwaysUseNormalColorForVerticalCellLines =
  355. (bool)_miAlwaysUseNormalColorForVerticalCellLines.Checked;
  356. _listColView.Update ();
  357. }
  358. private void ToggleBottomline ()
  359. {
  360. _miBottomline.Checked = !_miBottomline.Checked;
  361. _listColView.Style.ShowHorizontalBottomline = (bool)_miBottomline.Checked;
  362. _listColView.Update ();
  363. }
  364. private void ToggleCellLines ()
  365. {
  366. _miCellLines.Checked = !_miCellLines.Checked;
  367. _listColView.Style.ShowVerticalCellLines = (bool)_miCellLines.Checked;
  368. _listColView.Update ();
  369. }
  370. private void ToggleExpandLastColumn ()
  371. {
  372. _miExpandLastColumn.Checked = !_miExpandLastColumn.Checked;
  373. _listColView.Style.ExpandLastColumn = (bool)_miExpandLastColumn.Checked;
  374. _listColView.Update ();
  375. }
  376. private void ToggleInvertSelectedCellFirstCharacter ()
  377. {
  378. //toggle menu item
  379. _miCursor.Checked = !_miCursor.Checked;
  380. _listColView.Style.InvertSelectedCellFirstCharacter = (bool)_miCursor.Checked;
  381. _listColView.SetNeedsDraw ();
  382. }
  383. private void ToggleScrollParallel ()
  384. {
  385. _miScrollParallel.Checked = !_miScrollParallel.Checked;
  386. if ((ListTableSource)_listColView.Table != null)
  387. {
  388. ((ListTableSource)_listColView.Table).Style.ScrollParallel = (bool)_miScrollParallel.Checked;
  389. _listColView.SetNeedsDraw ();
  390. }
  391. }
  392. private void ToggleSmoothScrolling ()
  393. {
  394. _miSmoothScrolling.Checked = !_miSmoothScrolling.Checked;
  395. _listColView.Style.SmoothHorizontalScrolling = (bool)_miSmoothScrolling.Checked;
  396. _listColView.Update ();
  397. }
  398. private void ToggleTopline ()
  399. {
  400. _miTopline.Checked = !_miTopline.Checked;
  401. _listColView.Style.ShowHorizontalHeaderOverline = (bool)_miTopline.Checked;
  402. _listColView.Update ();
  403. }
  404. private void ToggleVerticalOrientation ()
  405. {
  406. _miOrientVertical.Checked = !_miOrientVertical.Checked;
  407. if ((ListTableSource)_listColView.Table != null)
  408. {
  409. ((ListTableSource)_listColView.Table).Style.Orientation = (bool)_miOrientVertical.Checked
  410. ? Orientation.Vertical
  411. : Orientation.Horizontal;
  412. _listColView.SetNeedsDraw ();
  413. }
  414. }
  415. }