LabelsAsButtons.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. using NStack;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Terminal.Gui;
  7. namespace UICatalog {
  8. [ScenarioMetadata (Name: "Labels As Buttons", Description: "Illustrates that Button is really just a Label++")]
  9. [ScenarioCategory ("Controls")]
  10. [ScenarioCategory ("POC")]
  11. class LabelsAsLabels : Scenario {
  12. public override void Setup ()
  13. {
  14. // Add a label & text field so we can demo IsDefault
  15. var editLabel = new Label ("TextField (to demo IsDefault):") {
  16. X = 0,
  17. Y = 0,
  18. };
  19. Win.Add (editLabel);
  20. // Add a TextField using Absolute layout.
  21. var edit = new TextField (31, 0, 15, "");
  22. Win.Add (edit);
  23. // This is the default Label (IsDefault = true); if user presses ENTER in the TextField
  24. // the scenario will quit
  25. var defaultLabel = new Label ("_Quit") {
  26. X = Pos.Center (),
  27. //TODO: Change to use Pos.AnchorEnd()
  28. Y = Pos.Bottom (Win) - 3,
  29. //IsDefault = true,
  30. HotKeySpecifier = (System.Rune)'_',
  31. CanFocus = true,
  32. };
  33. defaultLabel.Clicked += () => Application.RequestStop ();
  34. Win.Add (defaultLabel);
  35. var swapLabel = new Label (50, 0, "S_wap Default (Absolute Layout)") {
  36. HotKeySpecifier = (System.Rune)'_',
  37. CanFocus = true,
  38. };
  39. swapLabel.Clicked += () => {
  40. //defaultLabel.IsDefault = !defaultLabel.IsDefault;
  41. //swapLabel.IsDefault = !swapLabel.IsDefault;
  42. };
  43. Win.Add (swapLabel);
  44. static void DoMessage (Label Label, ustring txt)
  45. {
  46. Label.Clicked += () => {
  47. var btnText = Label.Text.ToString ();
  48. MessageBox.Query ("Message", $"Did you click {txt}?", "Yes", "No");
  49. };
  50. }
  51. var colorLabelsLabel = new Label ("Color Labels:") {
  52. X = 0,
  53. Y = Pos.Bottom (editLabel) + 1,
  54. };
  55. Win.Add (colorLabelsLabel);
  56. //With this method there is no need to call Top.Ready += () => Top.Redraw (Top.Bounds);
  57. var x = Pos.Right (colorLabelsLabel) + 2;
  58. foreach (var colorScheme in Colors.ColorSchemes) {
  59. var colorLabel = new Label ($"{colorScheme.Key}") {
  60. ColorScheme = colorScheme.Value,
  61. X = x,
  62. Y = Pos.Y (colorLabelsLabel),
  63. HotKeySpecifier = (System.Rune)'_',
  64. CanFocus = true,
  65. };
  66. DoMessage (colorLabel, colorLabel.Text);
  67. Win.Add (colorLabel);
  68. x += colorLabel.Text.Length + 2;
  69. }
  70. Top.Ready += () => Top.Redraw (Top.Bounds);
  71. Label Label;
  72. Win.Add (Label = new Label ("A super long _Label that will probably expose a bug in clipping or wrapping of text. Will it?") {
  73. X = 2,
  74. Y = Pos.Bottom (colorLabelsLabel) + 1,
  75. HotKeySpecifier = (System.Rune)'_',
  76. CanFocus = true,
  77. });
  78. DoMessage (Label, Label.Text);
  79. // Note the 'N' in 'Newline' will be the hotkey
  80. Win.Add (Label = new Label ("a Newline\nin the Label") {
  81. X = 2,
  82. Y = Pos.Bottom (Label) + 1,
  83. HotKeySpecifier = (System.Rune)'_',
  84. CanFocus = true,
  85. });
  86. Label.Clicked += () => MessageBox.Query ("Message", "Question?", "Yes", "No");
  87. var textChanger = new Label ("Te_xt Changer") {
  88. X = 2,
  89. Y = Pos.Bottom (Label) + 1,
  90. HotKeySpecifier = (System.Rune)'_',
  91. CanFocus = true,
  92. };
  93. Win.Add (textChanger);
  94. textChanger.Clicked += () => textChanger.Text += "!";
  95. Win.Add (Label = new Label ("Lets see if this will move as \"Text Changer\" grows") {
  96. X = Pos.Right (textChanger) + 2,
  97. Y = Pos.Y (textChanger),
  98. HotKeySpecifier = (System.Rune)'_',
  99. CanFocus = true,
  100. });
  101. var removeLabel = new Label ("Remove this Label") {
  102. X = 2,
  103. Y = Pos.Bottom (Label) + 1,
  104. ColorScheme = Colors.Error,
  105. HotKeySpecifier = (System.Rune)'_',
  106. CanFocus = true,
  107. };
  108. Win.Add (removeLabel);
  109. // This in intresting test case because `moveBtn` and below are laid out relative to this one!
  110. removeLabel.Clicked += () => Win.Remove (removeLabel);
  111. var computedFrame = new FrameView ("Computed Layout") {
  112. X = 0,
  113. Y = Pos.Bottom (removeLabel) + 1,
  114. Width = Dim.Percent (50),
  115. Height = 5
  116. };
  117. Win.Add (computedFrame);
  118. // Demonstrates how changing the View.Frame property can move Views
  119. var moveBtn = new Label ("Move This \u263b Label _via Pos") {
  120. X = 0,
  121. Y = Pos.Center () - 1,
  122. Width = 30,
  123. ColorScheme = Colors.Error,
  124. HotKeySpecifier = (System.Rune)'_',
  125. CanFocus = true,
  126. };
  127. moveBtn.Clicked += () => {
  128. moveBtn.X = moveBtn.Frame.X + 5;
  129. // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
  130. //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
  131. };
  132. computedFrame.Add (moveBtn);
  133. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  134. var sizeBtn = new Label ("Size This \u263a Label _via Pos") {
  135. //var sizeBtn = new Label ("Size This x Label _via Pos") {
  136. X = 0,
  137. Y = Pos.Center () + 1,
  138. Width = 30,
  139. ColorScheme = Colors.Error,
  140. HotKeySpecifier = (System.Rune)'_',
  141. CanFocus = true,
  142. };
  143. sizeBtn.Clicked += () => {
  144. sizeBtn.Width = sizeBtn.Frame.Width + 5;
  145. //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
  146. };
  147. computedFrame.Add (sizeBtn);
  148. var absoluteFrame = new FrameView ("Absolute Layout") {
  149. X = Pos.Right (computedFrame),
  150. Y = Pos.Bottom (removeLabel) + 1,
  151. Width = Dim.Fill (),
  152. Height = 5
  153. };
  154. Win.Add (absoluteFrame);
  155. // Demonstrates how changing the View.Frame property can move Views
  156. var moveBtnA = new Label (0, 0, "Move This Label via Frame") {
  157. ColorScheme = Colors.Error,
  158. HotKeySpecifier = (System.Rune)'_',
  159. CanFocus = true,
  160. };
  161. moveBtnA.Clicked += () => {
  162. moveBtnA.Frame = new Rect (moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height);
  163. };
  164. absoluteFrame.Add (moveBtnA);
  165. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  166. var sizeBtnA = new Label (0, 2, " ~  s  gui.cs   master ↑10 = Со_хранить") {
  167. ColorScheme = Colors.Error,
  168. HotKeySpecifier = (System.Rune)'_',
  169. CanFocus = true,
  170. };
  171. sizeBtnA.Clicked += () => {
  172. sizeBtnA.Frame = new Rect (sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height);
  173. };
  174. absoluteFrame.Add (sizeBtnA);
  175. var label = new Label ("Text Alignment (changes the four Labels above): ") {
  176. X = 2,
  177. Y = Pos.Bottom (computedFrame) + 1,
  178. HotKeySpecifier = (System.Rune)'_',
  179. CanFocus = true,
  180. };
  181. Win.Add (label);
  182. var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) {
  183. X = 4,
  184. Y = Pos.Bottom (label) + 1,
  185. SelectedItem = 2,
  186. };
  187. Win.Add (radioGroup);
  188. // Demo changing hotkey
  189. ustring MoveHotkey (ustring txt)
  190. {
  191. // Remove the '_'
  192. var runes = txt.ToRuneList ();
  193. var i = runes.IndexOf ('_');
  194. ustring start = "";
  195. if (i > -1) {
  196. start = ustring.Make (runes.GetRange (0, i));
  197. }
  198. txt = start + ustring.Make (runes.GetRange (i + 1, runes.Count - (i + 1)));
  199. runes = txt.ToRuneList ();
  200. // Move over one or go to start
  201. i++;
  202. if (i >= runes.Count) {
  203. i = 0;
  204. }
  205. // Slip in the '_'
  206. start = ustring.Make (runes.GetRange (0, i));
  207. return start + ustring.Make ('_') + ustring.Make (runes.GetRange (i, runes.Count - i));
  208. }
  209. var mhkb = "Click to Change th_is Label's Hotkey";
  210. var moveHotKeyBtn = new Label (mhkb) {
  211. X = 2,
  212. Y = Pos.Bottom (radioGroup) + 1,
  213. Width = mhkb.Length + 10,
  214. ColorScheme = Colors.TopLevel,
  215. HotKeySpecifier = (System.Rune)'_',
  216. CanFocus = true,
  217. };
  218. moveHotKeyBtn.Clicked += () => {
  219. moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
  220. };
  221. Win.Add (moveHotKeyBtn);
  222. ustring muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
  223. var moveUnicodeHotKeyBtn = new Label (muhkb) {
  224. X = Pos.Left (absoluteFrame) + 1,
  225. Y = Pos.Bottom (radioGroup) + 1,
  226. Width = muhkb.Length + 30,
  227. ColorScheme = Colors.TopLevel,
  228. HotKeySpecifier = (System.Rune)'_',
  229. CanFocus = true,
  230. };
  231. moveUnicodeHotKeyBtn.Clicked += () => {
  232. moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
  233. };
  234. Win.Add (moveUnicodeHotKeyBtn);
  235. radioGroup.SelectedItemChanged += (args) => {
  236. switch (args.SelectedItem) {
  237. case 0:
  238. moveBtn.TextAlignment = TextAlignment.Left;
  239. sizeBtn.TextAlignment = TextAlignment.Left;
  240. moveBtnA.TextAlignment = TextAlignment.Left;
  241. sizeBtnA.TextAlignment = TextAlignment.Left;
  242. moveHotKeyBtn.TextAlignment = TextAlignment.Left;
  243. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
  244. break;
  245. case 1:
  246. moveBtn.TextAlignment = TextAlignment.Right;
  247. sizeBtn.TextAlignment = TextAlignment.Right;
  248. moveBtnA.TextAlignment = TextAlignment.Right;
  249. sizeBtnA.TextAlignment = TextAlignment.Right;
  250. moveHotKeyBtn.TextAlignment = TextAlignment.Right;
  251. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
  252. break;
  253. case 2:
  254. moveBtn.TextAlignment = TextAlignment.Centered;
  255. sizeBtn.TextAlignment = TextAlignment.Centered;
  256. moveBtnA.TextAlignment = TextAlignment.Centered;
  257. sizeBtnA.TextAlignment = TextAlignment.Centered;
  258. moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
  259. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
  260. break;
  261. case 3:
  262. moveBtn.TextAlignment = TextAlignment.Justified;
  263. sizeBtn.TextAlignment = TextAlignment.Justified;
  264. moveBtnA.TextAlignment = TextAlignment.Justified;
  265. sizeBtnA.TextAlignment = TextAlignment.Justified;
  266. moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
  267. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
  268. break;
  269. }
  270. };
  271. }
  272. }
  273. }