ASCIICustomButton.cs 9.3 KB

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