PosJustification.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Terminal.Gui;
  5. namespace UICatalog.Scenarios;
  6. [ScenarioMetadata ("PosJustification", "Shows off Pos.Justify")]
  7. [ScenarioCategory ("Layout")]
  8. public sealed class PosJustification : Scenario
  9. {
  10. private readonly Aligner _horizJustifier = new ();
  11. private int _leftMargin;
  12. private readonly Aligner _vertJustifier = new ();
  13. private int _topMargin;
  14. public override void Main ()
  15. {
  16. // Init
  17. Application.Init ();
  18. // Setup - Create a top-level application window and configure it.
  19. Window appWindow = new ()
  20. {
  21. Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()} - {GetDescription ()}"
  22. };
  23. SetupHorizontalControls (appWindow);
  24. SetupVerticalControls (appWindow);
  25. Setup3by3Grid (appWindow);
  26. // Run - Start the application.
  27. Application.Run (appWindow);
  28. appWindow.Dispose ();
  29. // Shutdown - Calling Application.Shutdown is required.
  30. Application.Shutdown ();
  31. }
  32. private void SetupHorizontalControls (Window appWindow)
  33. {
  34. ColorScheme colorScheme = Colors.ColorSchemes ["Toplevel"];
  35. RadioGroup justification = new ()
  36. {
  37. X = Pos.Justify (_horizJustifier.Alignment),
  38. Y = Pos.Center (),
  39. RadioLabels = GetUniqueEnumNames<Alignment> (false).ToArray (),
  40. ColorScheme = colorScheme
  41. };
  42. justification.SelectedItemChanged += (s, e) =>
  43. {
  44. _horizJustifier.Alignment =
  45. (Alignment)Enum.Parse (typeof (Alignment), justification.SelectedItem.ToString ());
  46. foreach (View view in appWindow.Subviews.Where (v => v.X is Pos.PosJustify))
  47. {
  48. if (view.X is Pos.PosJustify j)
  49. {
  50. var newJust = new Pos.PosJustify (_horizJustifier.Alignment)
  51. {
  52. Justifier =
  53. {
  54. PutSpaceBetweenItems = _horizJustifier.PutSpaceBetweenItems
  55. }
  56. };
  57. view.X = newJust;
  58. }
  59. }
  60. };
  61. appWindow.Add (justification);
  62. CheckBox putSpaces = new ()
  63. {
  64. X = Pos.Justify (_horizJustifier.Alignment),
  65. Y = Pos.Top (justification),
  66. ColorScheme = colorScheme,
  67. Text = "Spaces"
  68. };
  69. putSpaces.Toggled += (s, e) =>
  70. {
  71. _horizJustifier.PutSpaceBetweenItems = e.NewValue is { } && e.NewValue.Value;
  72. foreach (View view in appWindow.Subviews.Where (v => v.X is Pos.PosJustify))
  73. {
  74. if (view.X is Pos.PosJustify j)
  75. {
  76. j.Justifier.PutSpaceBetweenItems = _horizJustifier.PutSpaceBetweenItems;
  77. }
  78. }
  79. };
  80. appWindow.Add (putSpaces);
  81. CheckBox margin = new ()
  82. {
  83. X = Pos.Left (putSpaces),
  84. Y = Pos.Bottom (putSpaces),
  85. ColorScheme = colorScheme,
  86. Text = "Margin"
  87. };
  88. margin.Toggled += (s, e) =>
  89. {
  90. _leftMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
  91. foreach (View view in appWindow.Subviews.Where (v => v.X is Pos.PosJustify))
  92. {
  93. // Skip the justification radio group
  94. if (view != justification)
  95. {
  96. view.Margin.Thickness = new (_leftMargin, 0, 0, 0);
  97. }
  98. }
  99. appWindow.LayoutSubviews ();
  100. };
  101. appWindow.Add (margin);
  102. List<Button> addedViews = new List<Button> ();
  103. addedViews.Add (
  104. new()
  105. {
  106. X = Pos.Justify (_horizJustifier.Alignment),
  107. Y = Pos.Center (),
  108. Text = NumberToWords.Convert (0)
  109. });
  110. Buttons.NumericUpDown<int> addedViewsUpDown = new Buttons.NumericUpDown<int>
  111. {
  112. X = Pos.Justify (_horizJustifier.Alignment),
  113. Y = Pos.Top (justification),
  114. Width = 9,
  115. Title = "Added",
  116. ColorScheme = colorScheme,
  117. BorderStyle = LineStyle.None,
  118. Value = addedViews.Count
  119. };
  120. addedViewsUpDown.Border.Thickness = new (0, 1, 0, 0);
  121. addedViewsUpDown.ValueChanging += (s, e) =>
  122. {
  123. if (e.NewValue < 0)
  124. {
  125. e.Cancel = true;
  126. return;
  127. }
  128. // Add or remove buttons
  129. if (e.NewValue < e.OldValue)
  130. {
  131. // Remove buttons
  132. for (int i = e.OldValue - 1; i >= e.NewValue; i--)
  133. {
  134. Button button = addedViews [i];
  135. appWindow.Remove (button);
  136. addedViews.RemoveAt (i);
  137. button.Dispose ();
  138. }
  139. }
  140. if (e.NewValue > e.OldValue)
  141. {
  142. // Add buttons
  143. for (int i = e.OldValue; i < e.NewValue; i++)
  144. {
  145. var button = new Button
  146. {
  147. X = Pos.Justify (_horizJustifier.Alignment),
  148. Y = Pos.Center (),
  149. Text = NumberToWords.Convert (i + 1)
  150. };
  151. appWindow.Add (button);
  152. addedViews.Add (button);
  153. }
  154. }
  155. };
  156. appWindow.Add (addedViewsUpDown);
  157. appWindow.Add (addedViews [0]);
  158. }
  159. private void SetupVerticalControls (Window appWindow)
  160. {
  161. ColorScheme colorScheme = Colors.ColorSchemes ["Error"];
  162. RadioGroup justification = new ()
  163. {
  164. X = 0,
  165. Y = Pos.Justify (_vertJustifier.Alignment),
  166. RadioLabels = GetUniqueEnumNames<Alignment> (true).Reverse ().ToArray (),
  167. ColorScheme = colorScheme
  168. };
  169. justification.SelectedItemChanged += (s, e) =>
  170. {
  171. _vertJustifier.Alignment =
  172. (Alignment)Enum.Parse (typeof (Alignment), justification.SelectedItem.ToString ());
  173. foreach (View view in appWindow.Subviews.Where (v => v.Y is Pos.PosJustify))
  174. {
  175. if (view.Y is Pos.PosJustify j)
  176. {
  177. var newJust = new Pos.PosJustify (_vertJustifier.Alignment)
  178. {
  179. Justifier =
  180. {
  181. PutSpaceBetweenItems = _vertJustifier.PutSpaceBetweenItems
  182. }
  183. };
  184. view.Y = newJust;
  185. }
  186. }
  187. };
  188. appWindow.Add (justification);
  189. CheckBox putSpaces = new ()
  190. {
  191. X = 0,
  192. Y = Pos.Justify (_vertJustifier.Alignment),
  193. ColorScheme = colorScheme,
  194. Text = "Spaces"
  195. };
  196. putSpaces.Toggled += (s, e) =>
  197. {
  198. _vertJustifier.PutSpaceBetweenItems = e.NewValue is { } && e.NewValue.Value;
  199. foreach (View view in appWindow.Subviews.Where (v => v.Y is Pos.PosJustify))
  200. {
  201. if (view.Y is Pos.PosJustify j)
  202. {
  203. j.Justifier.PutSpaceBetweenItems = _vertJustifier.PutSpaceBetweenItems;
  204. }
  205. }
  206. };
  207. appWindow.Add (putSpaces);
  208. CheckBox margin = new ()
  209. {
  210. X = Pos.Right (putSpaces) + 1,
  211. Y = Pos.Top (putSpaces),
  212. ColorScheme = colorScheme,
  213. Text = "Margin"
  214. };
  215. margin.Toggled += (s, e) =>
  216. {
  217. _topMargin = e.NewValue is { } && e.NewValue.Value ? 1 : 0;
  218. foreach (View view in appWindow.Subviews.Where (v => v.Y is Pos.PosJustify))
  219. {
  220. // Skip the justification radio group
  221. if (view != justification)
  222. {
  223. view.Margin.Thickness = new (0, _topMargin, 0, 0);
  224. }
  225. }
  226. appWindow.LayoutSubviews ();
  227. };
  228. appWindow.Add (margin);
  229. List<CheckBox> addedViews = new List<CheckBox> ();
  230. addedViews.Add (
  231. new()
  232. {
  233. X = 0,
  234. Y = Pos.Justify (_vertJustifier.Alignment),
  235. Text = NumberToWords.Convert (0)
  236. });
  237. Buttons.NumericUpDown<int> addedViewsUpDown = new Buttons.NumericUpDown<int>
  238. {
  239. X = 0,
  240. Y = Pos.Justify (_vertJustifier.Alignment),
  241. Width = 9,
  242. Title = "Added",
  243. ColorScheme = colorScheme,
  244. BorderStyle = LineStyle.None,
  245. Value = addedViews.Count
  246. };
  247. addedViewsUpDown.Border.Thickness = new (0, 1, 0, 0);
  248. addedViewsUpDown.ValueChanging += (s, e) =>
  249. {
  250. if (e.NewValue < 0)
  251. {
  252. e.Cancel = true;
  253. return;
  254. }
  255. // Add or remove buttons
  256. if (e.NewValue < e.OldValue)
  257. {
  258. // Remove buttons
  259. for (int i = e.OldValue - 1; i >= e.NewValue; i--)
  260. {
  261. CheckBox button = addedViews [i];
  262. appWindow.Remove (button);
  263. addedViews.RemoveAt (i);
  264. button.Dispose ();
  265. }
  266. }
  267. if (e.NewValue > e.OldValue)
  268. {
  269. // Add buttons
  270. for (int i = e.OldValue; i < e.NewValue; i++)
  271. {
  272. var button = new CheckBox
  273. {
  274. X = 0,
  275. Y = Pos.Justify (_vertJustifier.Alignment),
  276. Text = NumberToWords.Convert (i + 1)
  277. };
  278. appWindow.Add (button);
  279. addedViews.Add (button);
  280. }
  281. }
  282. };
  283. appWindow.Add (addedViewsUpDown);
  284. appWindow.Add (addedViews [0]);
  285. }
  286. private static IEnumerable<string> GetUniqueEnumNames<T> (bool reverse) where T : Enum
  287. {
  288. HashSet<int> values = new HashSet<int> ();
  289. string [] names = Enum.GetNames (typeof (T));
  290. if (reverse)
  291. {
  292. names = Enum.GetNames (typeof (T)).Reverse ().ToArray ();
  293. }
  294. foreach (string name in names)
  295. {
  296. var value = (int)Enum.Parse (typeof (T), name);
  297. if (values.Add (value))
  298. {
  299. yield return name;
  300. }
  301. }
  302. }
  303. private void Setup3by3Grid (Window appWindow)
  304. {
  305. var container = new View
  306. {
  307. Title = "3 by 3",
  308. BorderStyle = LineStyle.Single,
  309. X = Pos.AnchorEnd (),
  310. Y = Pos.AnchorEnd (),
  311. Width = Dim.Percent (30),
  312. Height = Dim.Percent (30)
  313. };
  314. for (var i = 0; i < 9; i++)
  315. {
  316. var v = new View
  317. {
  318. Title = $"{i}",
  319. BorderStyle = LineStyle.Dashed,
  320. Height = 3,
  321. Width = 5
  322. };
  323. v.X = Pos.Justify (Alignment.Right, i / 3);
  324. v.Y = Pos.Justify (Alignment.Justified, i % 3 + 10);
  325. container.Add (v);
  326. }
  327. appWindow.Add (container);
  328. }
  329. }