LabelsAsButtons.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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.Scenarios {
  8. [ScenarioMetadata (Name: "Labels As Buttons", Description: "Illustrates that Button is really just a Label++")]
  9. [ScenarioCategory ("Controls")]
  10. [ScenarioCategory ("POC")]
  11. public 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 interesting test case because `moveBtn` and below are laid out relative to this one!
  110. removeLabel.Clicked += () => {
  111. // Now this throw a InvalidOperationException on the TopologicalSort method as is expected.
  112. //Win.Remove (removeLabel);
  113. removeLabel.Visible = false;
  114. Win.SetNeedsDisplay ();
  115. };
  116. var computedFrame = new FrameView ("Computed Layout") {
  117. X = 0,
  118. Y = Pos.Bottom (removeLabel) + 1,
  119. Width = Dim.Percent (50),
  120. Height = 5
  121. };
  122. Win.Add (computedFrame);
  123. // Demonstrates how changing the View.Frame property can move Views
  124. var moveBtn = new Label ("Move This \u263b Label _via Pos") {
  125. X = 0,
  126. Y = Pos.Center () - 1,
  127. Width = 30,
  128. ColorScheme = Colors.Error,
  129. HotKeySpecifier = (System.Rune)'_',
  130. CanFocus = true,
  131. };
  132. moveBtn.Clicked += () => {
  133. moveBtn.X = moveBtn.Frame.X + 5;
  134. // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
  135. //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
  136. };
  137. computedFrame.Add (moveBtn);
  138. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  139. var sizeBtn = new Label ("Size This \u263a Label _via Pos") {
  140. //var sizeBtn = new Label ("Size This x Label _via Pos") {
  141. X = 0,
  142. Y = Pos.Center () + 1,
  143. Width = 30,
  144. ColorScheme = Colors.Error,
  145. HotKeySpecifier = (System.Rune)'_',
  146. CanFocus = true,
  147. };
  148. sizeBtn.Clicked += () => {
  149. sizeBtn.Width = sizeBtn.Frame.Width + 5;
  150. //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
  151. };
  152. computedFrame.Add (sizeBtn);
  153. var absoluteFrame = new FrameView ("Absolute Layout") {
  154. X = Pos.Right (computedFrame),
  155. Y = Pos.Bottom (removeLabel) + 1,
  156. Width = Dim.Fill (),
  157. Height = 5
  158. };
  159. Win.Add (absoluteFrame);
  160. // Demonstrates how changing the View.Frame property can move Views
  161. var moveBtnA = new Label (0, 0, "Move This Label via Frame") {
  162. ColorScheme = Colors.Error,
  163. HotKeySpecifier = (System.Rune)'_',
  164. CanFocus = true,
  165. };
  166. moveBtnA.Clicked += () => {
  167. moveBtnA.Frame = new Rect (moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height);
  168. };
  169. absoluteFrame.Add (moveBtnA);
  170. // Demonstrates how changing the View.Frame property can SIZE Views (#583)
  171. var sizeBtnA = new Label (0, 2, " ~  s  gui.cs   master ↑10 = Со_хранить") {
  172. ColorScheme = Colors.Error,
  173. HotKeySpecifier = (System.Rune)'_',
  174. CanFocus = true,
  175. };
  176. sizeBtnA.Clicked += () => {
  177. sizeBtnA.Frame = new Rect (sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height);
  178. };
  179. absoluteFrame.Add (sizeBtnA);
  180. var label = new Label ("Text Alignment (changes the four Labels above): ") {
  181. X = 2,
  182. Y = Pos.Bottom (computedFrame) + 1,
  183. HotKeySpecifier = (System.Rune)'_',
  184. CanFocus = true,
  185. };
  186. Win.Add (label);
  187. var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) {
  188. X = 4,
  189. Y = Pos.Bottom (label) + 1,
  190. SelectedItem = 2,
  191. };
  192. Win.Add (radioGroup);
  193. // Demo changing hotkey
  194. ustring MoveHotkey (ustring txt)
  195. {
  196. // Remove the '_'
  197. var runes = txt.ToRuneList ();
  198. var i = runes.IndexOf ('_');
  199. ustring start = "";
  200. if (i > -1) {
  201. start = ustring.Make (runes.GetRange (0, i));
  202. }
  203. txt = start + ustring.Make (runes.GetRange (i + 1, runes.Count - (i + 1)));
  204. runes = txt.ToRuneList ();
  205. // Move over one or go to start
  206. i++;
  207. if (i >= runes.Count) {
  208. i = 0;
  209. }
  210. // Slip in the '_'
  211. start = ustring.Make (runes.GetRange (0, i));
  212. return start + ustring.Make ('_') + ustring.Make (runes.GetRange (i, runes.Count - i));
  213. }
  214. var mhkb = "Click to Change th_is Label's Hotkey";
  215. var moveHotKeyBtn = new Label (mhkb) {
  216. X = 2,
  217. Y = Pos.Bottom (radioGroup) + 1,
  218. Width = Dim.Width (computedFrame) - 2,
  219. ColorScheme = Colors.TopLevel,
  220. HotKeySpecifier = (System.Rune)'_',
  221. CanFocus = true,
  222. };
  223. moveHotKeyBtn.Clicked += () => {
  224. moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
  225. };
  226. Win.Add (moveHotKeyBtn);
  227. ustring muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
  228. var moveUnicodeHotKeyBtn = new Label (muhkb) {
  229. X = Pos.Left (absoluteFrame) + 1,
  230. Y = Pos.Bottom (radioGroup) + 1,
  231. Width = Dim.Width (absoluteFrame) - 2,
  232. ColorScheme = Colors.TopLevel,
  233. HotKeySpecifier = (System.Rune)'_',
  234. CanFocus = true,
  235. };
  236. moveUnicodeHotKeyBtn.Clicked += () => {
  237. moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
  238. };
  239. Win.Add (moveUnicodeHotKeyBtn);
  240. radioGroup.SelectedItemChanged += (args) => {
  241. switch (args.SelectedItem) {
  242. case 0:
  243. moveBtn.TextAlignment = TextAlignment.Left;
  244. sizeBtn.TextAlignment = TextAlignment.Left;
  245. moveBtnA.TextAlignment = TextAlignment.Left;
  246. sizeBtnA.TextAlignment = TextAlignment.Left;
  247. moveHotKeyBtn.TextAlignment = TextAlignment.Left;
  248. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
  249. break;
  250. case 1:
  251. moveBtn.TextAlignment = TextAlignment.Right;
  252. sizeBtn.TextAlignment = TextAlignment.Right;
  253. moveBtnA.TextAlignment = TextAlignment.Right;
  254. sizeBtnA.TextAlignment = TextAlignment.Right;
  255. moveHotKeyBtn.TextAlignment = TextAlignment.Right;
  256. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
  257. break;
  258. case 2:
  259. moveBtn.TextAlignment = TextAlignment.Centered;
  260. sizeBtn.TextAlignment = TextAlignment.Centered;
  261. moveBtnA.TextAlignment = TextAlignment.Centered;
  262. sizeBtnA.TextAlignment = TextAlignment.Centered;
  263. moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
  264. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
  265. break;
  266. case 3:
  267. moveBtn.TextAlignment = TextAlignment.Justified;
  268. sizeBtn.TextAlignment = TextAlignment.Justified;
  269. moveBtnA.TextAlignment = TextAlignment.Justified;
  270. sizeBtnA.TextAlignment = TextAlignment.Justified;
  271. moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
  272. moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
  273. break;
  274. }
  275. };
  276. Top.Ready += () => radioGroup.Refresh ();
  277. }
  278. }
  279. }