LabelsAsButtons.cs 9.9 KB

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