demo.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. using Terminal.Gui;
  2. using System;
  3. using Mono.Terminal;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Globalization;
  7. using System.Reflection;
  8. using NStack;
  9. static class Demo {
  10. //class Box10x : View, IScrollView {
  11. class Box10x : View {
  12. int w = 40;
  13. int h = 50;
  14. public bool WantCursorPosition { get; set; } = false;
  15. public Box10x (int x, int y) : base (new Rect (x, y, 20, 10))
  16. {
  17. }
  18. public Size GetContentSize ()
  19. {
  20. return new Size (w, h);
  21. }
  22. public void SetCursorPosition (Point pos)
  23. {
  24. throw new NotImplementedException ();
  25. }
  26. public override void Redraw (Rect region)
  27. {
  28. //Point pos = new Point (region.X, region.Y);
  29. Driver.SetAttribute (ColorScheme.Focus);
  30. for (int y = 0; y < h; y++) {
  31. Move (0, y);
  32. Driver.AddStr (y.ToString ());
  33. for (int x = 0; x < w - y.ToString ().Length; x++) {
  34. //Driver.AddRune ((Rune)('0' + (x + y) % 10));
  35. if (y.ToString ().Length < w)
  36. Driver.AddStr (" ");
  37. }
  38. }
  39. //Move (pos.X, pos.Y);
  40. }
  41. }
  42. class Filler : View {
  43. public Filler (Rect rect) : base (rect)
  44. {
  45. }
  46. public override void Redraw (Rect region)
  47. {
  48. Driver.SetAttribute (ColorScheme.Focus);
  49. var f = Frame;
  50. for (int y = 0; y < f.Width; y++) {
  51. Move (0, y);
  52. for (int x = 0; x < f.Height; x++) {
  53. Rune r;
  54. switch (x % 3) {
  55. case 0:
  56. Driver.AddRune (y.ToString ().ToCharArray (0, 1) [0]);
  57. if (y > 9)
  58. Driver.AddRune (y.ToString ().ToCharArray (1, 1) [0]);
  59. r = '.';
  60. break;
  61. case 1:
  62. r = 'o';
  63. break;
  64. default:
  65. r = 'O';
  66. break;
  67. }
  68. Driver.AddRune (r);
  69. }
  70. }
  71. }
  72. }
  73. static void ShowTextAlignments (View container)
  74. {
  75. int i = 0;
  76. string txt = "Hello world, how are you doing today";
  77. container.Add (
  78. new FrameView (new Rect (75, 3, txt.Length + 6, 20), "Text Alignments") {
  79. new Label(new Rect(0, 1, 40, 3), $"{i+1}-{txt}") { TextAlignment = TextAlignment.Left },
  80. new Label(new Rect(0, 5, 40, 3), $"{i+2}-{txt}") { TextAlignment = TextAlignment.Right },
  81. new Label(new Rect(0, 9, 40, 3), $"{i+3}-{txt}") { TextAlignment = TextAlignment.Centered },
  82. new Label(new Rect(0, 13, 40, 3), $"{i+4}-{txt}") { TextAlignment = TextAlignment.Justified }
  83. });
  84. }
  85. static void ShowEntries (View container)
  86. {
  87. var scrollView = new ScrollView (new Rect (50, 10, 20, 8)) {
  88. ContentSize = new Size (20, 50),
  89. //ContentOffset = new Point (0, 0),
  90. ShowVerticalScrollIndicator = true,
  91. ShowHorizontalScrollIndicator = true
  92. };
  93. #if false
  94. scrollView.Add (new Box10x (0, 0));
  95. #else
  96. scrollView.Add (new Filler (new Rect (0, 0, 40, 40)));
  97. #endif
  98. // This is just to debug the visuals of the scrollview when small
  99. var scrollView2 = new ScrollView (new Rect (72, 10, 3, 3)) {
  100. ContentSize = new Size (100, 100),
  101. ShowVerticalScrollIndicator = true,
  102. ShowHorizontalScrollIndicator = true
  103. };
  104. scrollView2.Add (new Box10x (0, 0));
  105. var progress = new ProgressBar (new Rect (68, 1, 10, 1));
  106. bool timer (MainLoop caller)
  107. {
  108. progress.Pulse ();
  109. return true;
  110. }
  111. Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300), timer);
  112. // A little convoluted, this is because I am using this to test the
  113. // layout based on referencing elements of another view:
  114. var login = new Label ("Login: ") { X = 3, Y = 6 };
  115. var password = new Label ("Password: ") {
  116. X = Pos.Left (login),
  117. Y = Pos.Bottom (login) + 1
  118. };
  119. var loginText = new TextField ("") {
  120. X = Pos.Right (password),
  121. Y = Pos.Top (login),
  122. Width = 40
  123. };
  124. var passText = new TextField ("") {
  125. Secret = true,
  126. X = Pos.Left (loginText),
  127. Y = Pos.Top (password),
  128. Width = Dim.Width (loginText)
  129. };
  130. var tf = new Button (3, 19, "Ok");
  131. // Add some content
  132. container.Add (
  133. login,
  134. loginText,
  135. password,
  136. passText,
  137. new FrameView (new Rect (3, 10, 25, 6), "Options"){
  138. new CheckBox (1, 0, "Remember me"),
  139. new RadioGroup (1, 2, new [] { "_Personal", "_Company" }),
  140. },
  141. new ListView (new Rect (59, 6, 16, 4), new string [] {
  142. "First row",
  143. "<>",
  144. "This is a very long row that should overflow what is shown",
  145. "4th",
  146. "There is an empty slot on the second row",
  147. "Whoa",
  148. "This is so cool"
  149. }),
  150. scrollView,
  151. scrollView2,
  152. tf,
  153. new Button (10, 19, "Cancel"),
  154. new TimeField (3, 20, DateTime.Now),
  155. new TimeField (23, 20, DateTime.Now, true),
  156. new DateField (3, 22, DateTime.Now),
  157. new DateField (23, 22, DateTime.Now, true),
  158. progress,
  159. new Label (3, 24, "Press F9 (on Unix, ESC+9 is an alias) to activate the menubar"),
  160. menuKeysStyle,
  161. menuAutoMouseNav
  162. );
  163. container.SendSubviewToBack (tf);
  164. }
  165. public static Label ml2;
  166. static void NewFile ()
  167. {
  168. var d = new Dialog (
  169. "New File", 50, 20,
  170. new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } },
  171. new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } });
  172. ml2 = new Label (1, 1, "Mouse Debug Line");
  173. d.Add (ml2);
  174. Application.Run (d);
  175. }
  176. //
  177. // Creates a nested editor
  178. static void Editor (Toplevel top)
  179. {
  180. var tframe = top.Frame;
  181. var ntop = new Toplevel (tframe);
  182. var menu = new MenuBar (new MenuBarItem [] {
  183. new MenuBarItem ("_File", new MenuItem [] {
  184. new MenuItem ("_Close", "", () => {Application.RequestStop ();}),
  185. }),
  186. new MenuBarItem ("_Edit", new MenuItem [] {
  187. new MenuItem ("_Copy", "", null),
  188. new MenuItem ("C_ut", "", null),
  189. new MenuItem ("_Paste", "", null)
  190. }),
  191. });
  192. ntop.Add (menu);
  193. string fname = null;
  194. foreach (var s in new [] { "/etc/passwd", "c:\\windows\\win.ini" })
  195. if (System.IO.File.Exists (s)) {
  196. fname = s;
  197. break;
  198. }
  199. var win = new Window (fname ?? "Untitled") {
  200. X = 0,
  201. Y = 1,
  202. Width = Dim.Fill (),
  203. Height = Dim.Fill ()
  204. };
  205. ntop.Add (win);
  206. var text = new TextView (new Rect (0, 0, tframe.Width - 2, tframe.Height - 3));
  207. if (fname != null)
  208. text.Text = System.IO.File.ReadAllText (fname);
  209. win.Add (text);
  210. Application.Run (ntop);
  211. }
  212. static bool Quit ()
  213. {
  214. var n = MessageBox.Query (50, 7, "Quit Demo", "Are you sure you want to quit this demo?", "Yes", "No");
  215. return n == 0;
  216. }
  217. static void Close ()
  218. {
  219. MessageBox.ErrorQuery (50, 7, "Error", "There is nothing to close", "Ok");
  220. }
  221. // Watch what happens when I try to introduce a newline after the first open brace
  222. // it introduces a new brace instead, and does not indent. Then watch me fight
  223. // the editor as more oddities happen.
  224. public static void Open ()
  225. {
  226. var d = new OpenDialog ("Open", "Open a file") { AllowsMultipleSelection = true };
  227. Application.Run (d);
  228. if (!d.Canceled)
  229. MessageBox.Query (50, 7, "Selected File", string.Join (", ", d.FilePaths), "Ok");
  230. }
  231. public static void ShowHex (Toplevel top)
  232. {
  233. var tframe = top.Frame;
  234. var ntop = new Toplevel (tframe);
  235. var menu = new MenuBar (new MenuBarItem [] {
  236. new MenuBarItem ("_File", new MenuItem [] {
  237. new MenuItem ("_Close", "", () => {Application.RequestStop ();}),
  238. }),
  239. });
  240. ntop.Add (menu);
  241. var win = new Window ("/etc/passwd") {
  242. X = 0,
  243. Y = 1,
  244. Width = Dim.Fill (),
  245. Height = Dim.Fill ()
  246. };
  247. ntop.Add (win);
  248. var source = System.IO.File.OpenRead ("/etc/passwd");
  249. var hex = new HexView (source) {
  250. X = 0,
  251. Y = 0,
  252. Width = Dim.Fill (),
  253. Height = Dim.Fill ()
  254. };
  255. win.Add (hex);
  256. Application.Run (ntop);
  257. }
  258. public class MenuItemDetails : MenuItem {
  259. ustring title;
  260. string help;
  261. Action action;
  262. public MenuItemDetails (ustring title, string help, Action action) : base (title, help, action)
  263. {
  264. this.title = title;
  265. this.help = help;
  266. this.action = action;
  267. }
  268. public static MenuItemDetails Instance (MenuItem mi)
  269. {
  270. return (MenuItemDetails)mi.GetMenuItem ();
  271. }
  272. }
  273. public delegate MenuItem MenuItemDelegate (MenuItemDetails menuItem);
  274. public static void ShowMenuItem (MenuItem mi)
  275. {
  276. BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
  277. MethodInfo minfo = typeof (MenuItemDetails).GetMethod ("Instance", flags);
  278. MenuItemDelegate mid = (MenuItemDelegate)Delegate.CreateDelegate (typeof (MenuItemDelegate), minfo);
  279. MessageBox.Query (70, 7, mi.Title.ToString (),
  280. $"{mi.Title.ToString ()} selected. Is from submenu: {mi.GetMenuBarItem ()}", "Ok");
  281. }
  282. static void MenuKeysStyle_Toggled (object sender, EventArgs e)
  283. {
  284. menu.UseKeysUpDownAsKeysLeftRight = menuKeysStyle.Checked;
  285. }
  286. static void MenuAutoMouseNav_Toggled (object sender, EventArgs e)
  287. {
  288. menu.WantMousePositionReports = menuAutoMouseNav.Checked;
  289. }
  290. static void Copy ()
  291. {
  292. TextField textField = menu.LastFocused as TextField;
  293. if (textField != null && textField.SelectedLength != 0) {
  294. textField.Copy ();
  295. }
  296. }
  297. static void Cut ()
  298. {
  299. TextField textField = menu.LastFocused as TextField;
  300. if (textField != null && textField.SelectedLength != 0) {
  301. textField.Cut ();
  302. }
  303. }
  304. static void Paste ()
  305. {
  306. TextField textField = menu.LastFocused as TextField;
  307. if (textField != null) {
  308. textField.Paste ();
  309. }
  310. }
  311. static void Help ()
  312. {
  313. MessageBox.Query (50, 7, "Help", "This is a small help\nBe kind.", "Ok");
  314. }
  315. #region Selection Demo
  316. static void ListSelectionDemo ()
  317. {
  318. var d = new Dialog ("Selection Demo", 60, 20,
  319. new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } },
  320. new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } });
  321. var animals = new List<string> () { "Alpaca", "Llama", "Lion", "Shark", "Goat" };
  322. var msg = new Label ("Use space bar or control-t to toggle selection") {
  323. X = 1,
  324. Y = 1,
  325. Width = Dim.Fill () - 1,
  326. Height = 1
  327. };
  328. var list = new ListView (animals) {
  329. X = 1,
  330. Y = 3,
  331. Width = Dim.Fill () - 4,
  332. Height = Dim.Fill () - 4,
  333. AllowsMarking = true,
  334. AllowsMultipleSelection = false
  335. };
  336. d.Add (msg, list);
  337. Application.Run (d);
  338. var result = "";
  339. for (int i = 0; i < animals.Count; i++) {
  340. if (list.Source.IsMarked (i)) {
  341. result += animals [i] + " ";
  342. }
  343. }
  344. MessageBox.Query (60, 10, "Selected Animals", result == "" ? "No animals selected" : result, "Ok");
  345. }
  346. #endregion
  347. public static Label ml;
  348. public static MenuBar menu;
  349. public static CheckBox menuKeysStyle;
  350. public static CheckBox menuAutoMouseNav;
  351. static void Main ()
  352. {
  353. if (Debugger.IsAttached)
  354. CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US");
  355. //Application.UseSystemConsole = true;
  356. Application.Init ();
  357. var top = Application.Top;
  358. //Open ();
  359. #if true
  360. var win = new Window ("Hello") {
  361. X = 0,
  362. Y = 0,
  363. Width = Dim.Fill (),
  364. Height = Dim.Fill ()
  365. };
  366. #else
  367. var tframe = top.Frame;
  368. var win = new Window (new Rect (0, 1, tframe.Width, tframe.Height - 1), "Hello");
  369. #endif
  370. MenuItemDetails [] menuItems = {
  371. new MenuItemDetails ("F_ind", "", null),
  372. new MenuItemDetails ("_Replace", "", null),
  373. new MenuItemDetails ("_Item1", "", null),
  374. new MenuItemDetails ("_Not From Sub Menu", "", null)
  375. };
  376. menuItems [0].Action = () => ShowMenuItem (menuItems [0]);
  377. menuItems [1].Action = () => ShowMenuItem (menuItems [1]);
  378. menuItems [2].Action = () => ShowMenuItem (menuItems [2]);
  379. menuItems [3].Action = () => ShowMenuItem (menuItems [3]);
  380. menu = new MenuBar (new MenuBarItem [] {
  381. new MenuBarItem ("_File", new MenuItem [] {
  382. new MenuItem ("Text Editor Demo", "", () => { Editor (top); }),
  383. new MenuItem ("_New", "Creates new file", NewFile),
  384. new MenuItem ("_Open", "", Open),
  385. new MenuItem ("_Hex", "", () => ShowHex (top)),
  386. new MenuItem ("_Close", "", () => Close ()),
  387. new MenuItem ("_Disabled", "", () => { }, () => false),
  388. null,
  389. new MenuItem ("_Quit", "", () => { if (Quit ()) top.Running = false; })
  390. }),
  391. new MenuBarItem ("_Edit", new MenuItem [] {
  392. new MenuItem ("_Copy", "", Copy),
  393. new MenuItem ("C_ut", "", Cut),
  394. new MenuItem ("_Paste", "", Paste),
  395. new MenuItem ("_Find and Replace",
  396. new MenuBarItem (new MenuItem[] {menuItems [0], menuItems [1] })),
  397. menuItems[3]
  398. }),
  399. new MenuBarItem ("_List Demos", new MenuItem [] {
  400. new MenuItem ("Select Items", "", ListSelectionDemo),
  401. }),
  402. new MenuBarItem ("Test Menu and SubMenus", new MenuItem [] {
  403. new MenuItem ("SubMenu1Item1",
  404. new MenuBarItem (new MenuItem[] {
  405. new MenuItem ("SubMenu2Item1",
  406. new MenuBarItem (new MenuItem [] {
  407. new MenuItem ("SubMenu3Item1",
  408. new MenuBarItem (new MenuItem [] { menuItems [2] })
  409. )
  410. })
  411. )
  412. })
  413. )
  414. }),
  415. });
  416. menuKeysStyle = new CheckBox (3, 25, "UseKeysUpDownAsKeysLeftRight", true);
  417. menuKeysStyle.Toggled += MenuKeysStyle_Toggled;
  418. menuAutoMouseNav = new CheckBox (40, 25, "UseMenuAutoNavigation", true);
  419. menuAutoMouseNav.Toggled += MenuAutoMouseNav_Toggled;
  420. ShowEntries (win);
  421. int count = 0;
  422. ml = new Label (new Rect (3, 18, 47, 1), "Mouse: ");
  423. Application.RootMouseEvent += delegate (MouseEvent me) {
  424. ml.TextColor = Colors.TopLevel.Normal;
  425. ml.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}";
  426. };
  427. var test = new Label (3, 18, "Se iniciará el análisis");
  428. win.Add (test);
  429. win.Add (ml);
  430. ShowTextAlignments (win);
  431. var drag = new Label ("Drag: ") { X = 70, Y = 24 };
  432. var dragText = new TextField ("") {
  433. X = Pos.Right (drag),
  434. Y = Pos.Top (drag),
  435. Width = 40
  436. };
  437. var statusBar = new StatusBar (new StatusItem [] {
  438. new StatusItem(Key.F1, "~F1~ Help", () => Help()),
  439. new StatusItem(Key.F2, "~F2~ Load", null),
  440. new StatusItem(Key.F3, "~F3~ Save", null),
  441. new StatusItem(Key.ControlX, "~^X~ Quit", () => Quit()),
  442. });
  443. win.Add (drag, dragText);
  444. top.Add (win);
  445. //top.Add (menu);
  446. top.Add (menu, statusBar, ml);
  447. Application.Run ();
  448. }
  449. }