ASCIICustomButton.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Text;
  5. using Terminal.Gui;
  6. namespace UICatalog.Scenarios;
  7. [ScenarioMetadata ("ASCIICustomButtonTest", "ASCIICustomButton sample")]
  8. [ScenarioCategory ("Controls")]
  9. public class ASCIICustomButtonTest : Scenario
  10. {
  11. private static bool _smallerWindow;
  12. private MenuItem _miSmallerWindow;
  13. private ScrollViewTestWindow _scrollViewTestWindow;
  14. public override void Init ()
  15. {
  16. Application.Init ();
  17. _scrollViewTestWindow = new ScrollViewTestWindow ();
  18. var menu = new MenuBar
  19. {
  20. Menus =
  21. [
  22. new MenuBarItem (
  23. "Window Size",
  24. new []
  25. {
  26. _miSmallerWindow =
  27. new MenuItem (
  28. "Smaller Window",
  29. "",
  30. ChangeWindowSize
  31. )
  32. {
  33. CheckType = MenuItemCheckStyle
  34. .Checked
  35. },
  36. null,
  37. new MenuItem (
  38. "Quit",
  39. "",
  40. () => Application.RequestStop (),
  41. null,
  42. null,
  43. (KeyCode)Application.QuitKey
  44. )
  45. }
  46. )
  47. ]
  48. };
  49. Application.Top.Add (menu, _scrollViewTestWindow);
  50. Application.Run ();
  51. }
  52. public override void Run () { }
  53. private void ChangeWindowSize ()
  54. {
  55. _smallerWindow = (bool)(_miSmallerWindow.Checked = !_miSmallerWindow.Checked);
  56. _scrollViewTestWindow.Dispose ();
  57. Application.Top.Remove (_scrollViewTestWindow);
  58. _scrollViewTestWindow = new ScrollViewTestWindow ();
  59. Application.Top.Add (_scrollViewTestWindow);
  60. }
  61. public class ASCIICustomButton : Button
  62. {
  63. private FrameView _border;
  64. private Label _fill;
  65. public string Description => $"Description of: {Id}";
  66. public void CustomInitialize ()
  67. {
  68. _border = new FrameView { Width = Width, Height = Height };
  69. AutoSize = false;
  70. var fillText = new StringBuilder ();
  71. for (var i = 0; i < Bounds.Height; i++)
  72. {
  73. if (i > 0)
  74. {
  75. fillText.AppendLine ("");
  76. }
  77. for (var j = 0; j < Bounds.Width; j++)
  78. {
  79. fillText.Append ("█");
  80. }
  81. }
  82. _fill = new Label { Visible = false, CanFocus = false, Text = fillText.ToString () };
  83. var title = new Label { X = Pos.Center (), Y = Pos.Center (), Text = Text };
  84. _border.MouseClick += This_MouseClick;
  85. _fill.MouseClick += This_MouseClick;
  86. title.MouseClick += This_MouseClick;
  87. Add (_border, _fill, title);
  88. }
  89. public override bool OnEnter (View view)
  90. {
  91. _border.Visible = false;
  92. _fill.Visible = true;
  93. PointerEnter.Invoke (this);
  94. view = this;
  95. return base.OnEnter (view);
  96. }
  97. public override bool OnLeave (View view)
  98. {
  99. _border.Visible = true;
  100. _fill.Visible = false;
  101. if (view == null)
  102. {
  103. view = this;
  104. }
  105. return base.OnLeave (view);
  106. }
  107. public event Action<ASCIICustomButton> PointerEnter;
  108. private void This_MouseClick (object sender, MouseEventEventArgs obj) { OnMouseEvent (obj.MouseEvent); }
  109. }
  110. public class ScrollViewTestWindow : Window
  111. {
  112. private const int BUTTON_HEIGHT = 3;
  113. private const int BUTTON_WIDTH = 25;
  114. private const int BUTTONS_ON_PAGE = 7;
  115. private readonly List<Button> _buttons;
  116. private readonly ScrollView _scrollView;
  117. private ASCIICustomButton _selected;
  118. public ScrollViewTestWindow ()
  119. {
  120. Title = "ScrollViewTestWindow";
  121. Label titleLabel = null;
  122. if (_smallerWindow)
  123. {
  124. Width = 80;
  125. Height = 25;
  126. _scrollView = new ScrollView
  127. {
  128. X = 3,
  129. Y = 1,
  130. Width = 24,
  131. Height = BUTTONS_ON_PAGE * BUTTON_HEIGHT,
  132. ShowVerticalScrollIndicator = true,
  133. ShowHorizontalScrollIndicator = false
  134. };
  135. }
  136. else
  137. {
  138. Width = Dim.Fill ();
  139. Height = Dim.Fill ();
  140. titleLabel = new Label { X = 0, Y = 0, Text = "DOCUMENTS" };
  141. _scrollView = new ScrollView
  142. {
  143. X = 0,
  144. Y = 1,
  145. Width = 27,
  146. Height = BUTTONS_ON_PAGE * BUTTON_HEIGHT,
  147. ShowVerticalScrollIndicator = true,
  148. ShowHorizontalScrollIndicator = false
  149. };
  150. }
  151. _scrollView.KeyBindings.Clear ();
  152. _buttons = new List<Button> ();
  153. Button prevButton = null;
  154. var count = 20;
  155. for (var j = 0; j < count; j++)
  156. {
  157. Pos yPos = prevButton == null ? 0 : Pos.Bottom (prevButton);
  158. var button = new ASCIICustomButton
  159. {
  160. AutoSize = false,
  161. Id = j.ToString (),
  162. Text = $"section {j}",
  163. Y = yPos,
  164. Width = BUTTON_WIDTH,
  165. Height = BUTTON_HEIGHT
  166. };
  167. button.CustomInitialize ();
  168. button.Accept += Button_Clicked;
  169. button.PointerEnter += Button_PointerEnter;
  170. button.MouseClick += Button_MouseClick;
  171. button.KeyDown += Button_KeyPress;
  172. _scrollView.Add (button);
  173. _buttons.Add (button);
  174. prevButton = button;
  175. }
  176. var closeButton = new ASCIICustomButton
  177. {
  178. AutoSize = false,
  179. Id = "close",
  180. Text = "Close",
  181. Y = Pos.Bottom (prevButton),
  182. Width = BUTTON_WIDTH,
  183. Height = BUTTON_HEIGHT
  184. };
  185. closeButton.CustomInitialize ();
  186. closeButton.Accept += Button_Clicked;
  187. closeButton.PointerEnter += Button_PointerEnter;
  188. closeButton.MouseClick += Button_MouseClick;
  189. closeButton.KeyDown += Button_KeyPress;
  190. _scrollView.Add (closeButton);
  191. _buttons.Add (closeButton);
  192. int pages = _buttons.Count / BUTTONS_ON_PAGE;
  193. if (_buttons.Count % BUTTONS_ON_PAGE > 0)
  194. {
  195. pages++;
  196. }
  197. _scrollView.ContentSize = new (25, pages * BUTTONS_ON_PAGE * BUTTON_HEIGHT);
  198. if (_smallerWindow)
  199. {
  200. Add (_scrollView);
  201. }
  202. else
  203. {
  204. Add (titleLabel, _scrollView);
  205. }
  206. }
  207. private void Button_Clicked (object sender, EventArgs e)
  208. {
  209. MessageBox.Query ("Button clicked.", $"'{_selected.Text}' clicked!", "Ok");
  210. if (_selected.Text == "Close")
  211. {
  212. Application.RequestStop ();
  213. }
  214. }
  215. private void Button_KeyPress (object sender, Key obj)
  216. {
  217. switch (obj.KeyCode)
  218. {
  219. case KeyCode.End:
  220. _scrollView.ContentOffset = new Point (
  221. _scrollView.ContentOffset.X,
  222. -(_scrollView.ContentSize.Height
  223. - _scrollView.Frame.Height
  224. + (_scrollView.ShowHorizontalScrollIndicator ? 1 : 0))
  225. );
  226. obj.Handled = true;
  227. return;
  228. case KeyCode.Home:
  229. _scrollView.ContentOffset = new Point (_scrollView.ContentOffset.X, 0);
  230. obj.Handled = true;
  231. return;
  232. case KeyCode.PageDown:
  233. _scrollView.ContentOffset = new Point (
  234. _scrollView.ContentOffset.X,
  235. Math.Max (
  236. _scrollView.ContentOffset.Y
  237. - _scrollView.Frame.Height,
  238. -(_scrollView.ContentSize.Height
  239. - _scrollView.Frame.Height
  240. + (_scrollView.ShowHorizontalScrollIndicator
  241. ? 1
  242. : 0))
  243. )
  244. );
  245. obj.Handled = true;
  246. return;
  247. case KeyCode.PageUp:
  248. _scrollView.ContentOffset = new Point (
  249. _scrollView.ContentOffset.X,
  250. Math.Min (
  251. _scrollView.ContentOffset.Y
  252. + _scrollView.Frame.Height,
  253. 0
  254. )
  255. );
  256. obj.Handled = true;
  257. return;
  258. }
  259. }
  260. private void Button_MouseClick (object sender, MouseEventEventArgs obj)
  261. {
  262. if (obj.MouseEvent.Flags == MouseFlags.WheeledDown)
  263. {
  264. _scrollView.ContentOffset = new Point (
  265. _scrollView.ContentOffset.X,
  266. _scrollView.ContentOffset.Y - BUTTON_HEIGHT
  267. );
  268. obj.Handled = true;
  269. }
  270. else if (obj.MouseEvent.Flags == MouseFlags.WheeledUp)
  271. {
  272. _scrollView.ContentOffset = new Point (
  273. _scrollView.ContentOffset.X,
  274. Math.Min (_scrollView.ContentOffset.Y + BUTTON_HEIGHT, 0)
  275. );
  276. obj.Handled = true;
  277. }
  278. }
  279. private void Button_PointerEnter (ASCIICustomButton obj)
  280. {
  281. bool? moveDown;
  282. if (obj.Frame.Y > _selected?.Frame.Y)
  283. {
  284. moveDown = true;
  285. }
  286. else if (obj.Frame.Y < _selected?.Frame.Y)
  287. {
  288. moveDown = false;
  289. }
  290. else
  291. {
  292. moveDown = null;
  293. }
  294. int offSet = _selected != null
  295. ? obj.Frame.Y - _selected.Frame.Y + -_scrollView.ContentOffset.Y % BUTTON_HEIGHT
  296. : 0;
  297. _selected = obj;
  298. if (moveDown == true && _selected.Frame.Y + _scrollView.ContentOffset.Y + BUTTON_HEIGHT >= _scrollView.Frame.Height && offSet != BUTTON_HEIGHT)
  299. {
  300. _scrollView.ContentOffset = new Point (
  301. _scrollView.ContentOffset.X,
  302. Math.Min (
  303. _scrollView.ContentOffset.Y - BUTTON_HEIGHT,
  304. -(_selected.Frame.Y
  305. - _scrollView.Frame.Height
  306. + BUTTON_HEIGHT)
  307. )
  308. );
  309. }
  310. else if (moveDown == true && _selected.Frame.Y + _scrollView.ContentOffset.Y >= _scrollView.Frame.Height)
  311. {
  312. _scrollView.ContentOffset = new Point (
  313. _scrollView.ContentOffset.X,
  314. _scrollView.ContentOffset.Y - BUTTON_HEIGHT
  315. );
  316. }
  317. else if (moveDown == true && _selected.Frame.Y + _scrollView.ContentOffset.Y < 0)
  318. {
  319. _scrollView.ContentOffset = new Point (
  320. _scrollView.ContentOffset.X,
  321. -_selected.Frame.Y
  322. );
  323. }
  324. else if (moveDown == false && _selected.Frame.Y < -_scrollView.ContentOffset.Y)
  325. {
  326. _scrollView.ContentOffset = new Point (
  327. _scrollView.ContentOffset.X,
  328. Math.Max (
  329. _scrollView.ContentOffset.Y + BUTTON_HEIGHT,
  330. _selected.Frame.Y
  331. )
  332. );
  333. }
  334. else if (moveDown == false && _selected.Frame.Y + _scrollView.ContentOffset.Y > _scrollView.Frame.Height)
  335. {
  336. _scrollView.ContentOffset = new Point (
  337. _scrollView.ContentOffset.X,
  338. -(_selected.Frame.Y - _scrollView.Frame.Height + BUTTON_HEIGHT)
  339. );
  340. }
  341. }
  342. }
  343. }