ASCIICustomButton.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using Terminal.Gui;
  5. namespace UICatalog.Scenarios {
  6. [ScenarioMetadata (Name: "ASCIICustomButtonTest", Description: "ASCIICustomButton sample")]
  7. [ScenarioCategory ("Controls")]
  8. public class ASCIICustomButtonTest : Scenario {
  9. private static bool smallerWindow;
  10. private ScrollViewTestWindow scrollViewTestWindow;
  11. private MenuItem miSmallerWindow;
  12. public override void Init (ColorScheme colorScheme)
  13. {
  14. Application.Init ();
  15. scrollViewTestWindow = new ScrollViewTestWindow ();
  16. var menu = new MenuBar (new MenuBarItem [] {
  17. new MenuBarItem("Window Size", new MenuItem [] {
  18. miSmallerWindow = new MenuItem ("Smaller Window", "", ChangeWindowSize) {
  19. CheckType = MenuItemCheckStyle.Checked
  20. },
  21. null,
  22. new MenuItem("Quit", "",() => Application.RequestStop(),null,null, Key.Q | Key.CtrlMask)
  23. })
  24. });
  25. Application.Top.Add (menu, scrollViewTestWindow);
  26. Application.Run ();
  27. }
  28. private void ChangeWindowSize ()
  29. {
  30. smallerWindow = (bool)(miSmallerWindow.Checked = !miSmallerWindow.Checked);
  31. scrollViewTestWindow.Dispose ();
  32. Application.Top.Remove (scrollViewTestWindow);
  33. scrollViewTestWindow = new ScrollViewTestWindow ();
  34. Application.Top.Add (scrollViewTestWindow);
  35. }
  36. public override void Run ()
  37. {
  38. }
  39. public class ASCIICustomButton : Button {
  40. public string Description => $"Description of: {id}";
  41. public event Action<ASCIICustomButton> PointerEnter;
  42. private Label fill;
  43. private FrameView border;
  44. private string id;
  45. public ASCIICustomButton (string text, Pos x, Pos y, int width, int height) : base (text)
  46. {
  47. CustomInitialize ("", text, x, y, width, height);
  48. }
  49. public ASCIICustomButton (string id, string text, Pos x, Pos y, int width, int height) : base (text)
  50. {
  51. CustomInitialize (id, text, x, y, width, height);
  52. }
  53. private void CustomInitialize (string id, string text, Pos x, Pos y, int width, int height)
  54. {
  55. this.id = id;
  56. X = x;
  57. Y = y;
  58. Frame = new Rect {
  59. Width = width,
  60. Height = height
  61. };
  62. border = new FrameView () {
  63. Width = width,
  64. Height = height
  65. };
  66. AutoSize = false;
  67. var fillText = new System.Text.StringBuilder ();
  68. for (int i = 0; i < Bounds.Height; i++) {
  69. if (i > 0) {
  70. fillText.AppendLine ("");
  71. }
  72. for (int j = 0; j < Bounds.Width; j++) {
  73. fillText.Append ("█");
  74. }
  75. }
  76. fill = new Label (fillText.ToString ()) {
  77. Visible = false,
  78. CanFocus = false
  79. };
  80. var title = new Label (text) {
  81. X = Pos.Center (),
  82. Y = Pos.Center (),
  83. };
  84. border.MouseClick += This_MouseClick;
  85. border.Subviews [0].MouseClick += This_MouseClick;
  86. fill.MouseClick += This_MouseClick;
  87. title.MouseClick += This_MouseClick;
  88. Add (border, fill, title);
  89. }
  90. private void This_MouseClick (MouseEventArgs obj)
  91. {
  92. OnMouseEvent (obj.MouseEvent);
  93. }
  94. public override bool OnMouseEvent (MouseEvent mouseEvent)
  95. {
  96. Debug.WriteLine ($"{mouseEvent.Flags}");
  97. if (mouseEvent.Flags == MouseFlags.Button1Clicked) {
  98. if (!HasFocus && SuperView != null) {
  99. if (!SuperView.HasFocus) {
  100. SuperView.SetFocus ();
  101. }
  102. SetFocus ();
  103. SetNeedsDisplay ();
  104. }
  105. OnClicked ();
  106. return true;
  107. }
  108. return base.OnMouseEvent (mouseEvent);
  109. }
  110. public override bool OnEnter (View view)
  111. {
  112. border.Visible = false;
  113. fill.Visible = true;
  114. PointerEnter.Invoke (this);
  115. view = this;
  116. return base.OnEnter (view);
  117. }
  118. public override bool OnLeave (View view)
  119. {
  120. border.Visible = true;
  121. fill.Visible = false;
  122. if (view == null)
  123. view = this;
  124. return base.OnLeave (view);
  125. }
  126. }
  127. public class ScrollViewTestWindow : Window {
  128. private List<Button> buttons;
  129. private const int BUTTONS_ON_PAGE = 7;
  130. private const int BUTTON_HEIGHT = 3;
  131. private ScrollView scrollView;
  132. private ASCIICustomButton selected;
  133. public ScrollViewTestWindow ()
  134. {
  135. Title = "ScrollViewTestWindow";
  136. Label titleLabel = null;
  137. if (smallerWindow) {
  138. Width = 80;
  139. Height = 25;
  140. scrollView = new ScrollView () {
  141. X = 3,
  142. Y = 1,
  143. Width = 24,
  144. Height = BUTTONS_ON_PAGE * BUTTON_HEIGHT,
  145. ShowVerticalScrollIndicator = true,
  146. ShowHorizontalScrollIndicator = false
  147. };
  148. } else {
  149. Width = Dim.Fill ();
  150. Height = Dim.Fill ();
  151. titleLabel = new Label ("DOCUMENTS") {
  152. X = 0,
  153. Y = 0
  154. };
  155. scrollView = new ScrollView () {
  156. X = 0,
  157. Y = 1,
  158. Width = 27,
  159. Height = BUTTONS_ON_PAGE * BUTTON_HEIGHT,
  160. ShowVerticalScrollIndicator = true,
  161. ShowHorizontalScrollIndicator = false
  162. };
  163. }
  164. scrollView.ClearKeybindings ();
  165. buttons = new List<Button> ();
  166. Button prevButton = null;
  167. int count = 20;
  168. for (int j = 0; j < count; j++) {
  169. Pos yPos = prevButton == null ? 0 : Pos.Bottom (prevButton);
  170. var button = new ASCIICustomButton (j.ToString (), $"section {j}", 0, yPos, 25, BUTTON_HEIGHT);
  171. button.Id = $"button{j}";
  172. button.Clicked += Button_Clicked;
  173. button.PointerEnter += Button_PointerEnter;
  174. button.MouseClick += Button_MouseClick;
  175. button.KeyPress += Button_KeyPress;
  176. scrollView.Add (button);
  177. buttons.Add (button);
  178. prevButton = button;
  179. }
  180. var closeButton = new ASCIICustomButton ("close", "Close", 0, Pos.Bottom (prevButton), 25, BUTTON_HEIGHT);
  181. closeButton.Clicked += Button_Clicked;
  182. closeButton.PointerEnter += Button_PointerEnter;
  183. closeButton.MouseClick += Button_MouseClick;
  184. closeButton.KeyPress += Button_KeyPress;
  185. scrollView.Add (closeButton);
  186. buttons.Add (closeButton);
  187. var pages = buttons.Count / BUTTONS_ON_PAGE;
  188. if (buttons.Count % BUTTONS_ON_PAGE > 0)
  189. pages++;
  190. scrollView.ContentSize = new Size (25, pages * BUTTONS_ON_PAGE * BUTTON_HEIGHT);
  191. if (smallerWindow) {
  192. Add (scrollView);
  193. } else {
  194. Add (titleLabel, scrollView);
  195. }
  196. }
  197. private void Button_KeyPress (KeyEventEventArgs obj)
  198. {
  199. switch (obj.KeyEvent.Key) {
  200. case Key.End:
  201. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  202. -(scrollView.ContentSize.Height - scrollView.Frame.Height
  203. + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0)));
  204. obj.Handled = true;
  205. return;
  206. case Key.Home:
  207. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, 0);
  208. obj.Handled = true;
  209. return;
  210. case Key.PageDown:
  211. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  212. Math.Max (scrollView.ContentOffset.Y - scrollView.Frame.Height,
  213. -(scrollView.ContentSize.Height - scrollView.Frame.Height
  214. + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0))));
  215. obj.Handled = true;
  216. return;
  217. case Key.PageUp:
  218. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  219. Math.Min (scrollView.ContentOffset.Y + scrollView.Frame.Height, 0));
  220. obj.Handled = true;
  221. return;
  222. }
  223. }
  224. private void Button_MouseClick (MouseEventArgs obj)
  225. {
  226. if (obj.MouseEvent.Flags == MouseFlags.WheeledDown) {
  227. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  228. scrollView.ContentOffset.Y - BUTTON_HEIGHT);
  229. obj.Handled = true;
  230. } else if (obj.MouseEvent.Flags == MouseFlags.WheeledUp) {
  231. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  232. Math.Min (scrollView.ContentOffset.Y + BUTTON_HEIGHT, 0));
  233. obj.Handled = true;
  234. }
  235. }
  236. private void Button_Clicked ()
  237. {
  238. MessageBox.Query ("Button clicked.", $"'{selected.Text}' clicked!", "Ok");
  239. if (selected.Text == "Close") {
  240. Application.RequestStop ();
  241. }
  242. }
  243. private void Button_PointerEnter (ASCIICustomButton obj)
  244. {
  245. bool? moveDown;
  246. if (obj.Frame.Y > selected?.Frame.Y) {
  247. moveDown = true;
  248. } else if (obj.Frame.Y < selected?.Frame.Y) {
  249. moveDown = false;
  250. } else {
  251. moveDown = null;
  252. }
  253. var offSet = selected != null ? obj.Frame.Y - selected.Frame.Y + (-scrollView.ContentOffset.Y % BUTTON_HEIGHT) : 0;
  254. selected = obj;
  255. if (moveDown == true && selected.Frame.Y + scrollView.ContentOffset.Y + BUTTON_HEIGHT >= scrollView.Frame.Height && offSet != BUTTON_HEIGHT) {
  256. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  257. Math.Min (scrollView.ContentOffset.Y - BUTTON_HEIGHT, -(selected.Frame.Y - scrollView.Frame.Height + BUTTON_HEIGHT)));
  258. } else if (moveDown == true && selected.Frame.Y + scrollView.ContentOffset.Y >= scrollView.Frame.Height) {
  259. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  260. scrollView.ContentOffset.Y - BUTTON_HEIGHT);
  261. } else if (moveDown == true && selected.Frame.Y + scrollView.ContentOffset.Y < 0) {
  262. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  263. -selected.Frame.Y);
  264. } else if (moveDown == false && selected.Frame.Y < -scrollView.ContentOffset.Y) {
  265. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  266. Math.Max (scrollView.ContentOffset.Y + BUTTON_HEIGHT, selected.Frame.Y));
  267. } else if (moveDown == false && selected.Frame.Y + scrollView.ContentOffset.Y > scrollView.Frame.Height) {
  268. scrollView.ContentOffset = new Point (scrollView.ContentOffset.X,
  269. -(selected.Frame.Y - scrollView.Frame.Height + BUTTON_HEIGHT));
  270. }
  271. }
  272. }
  273. }
  274. }