Mouse.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. using System.Collections.ObjectModel;
  2. namespace UICatalog.Scenarios;
  3. [ScenarioMetadata ("Mouse", "Demonstrates Mouse Events and States")]
  4. [ScenarioCategory ("Mouse and Keyboard")]
  5. public class Mouse : Scenario
  6. {
  7. public override void Main ()
  8. {
  9. Application.Init ();
  10. Window win = new ()
  11. {
  12. Id = "win",
  13. Title = GetQuitKeyAndName ()
  14. };
  15. Slider<MouseFlags> filterSlider = new ()
  16. {
  17. Title = "_Filter",
  18. X = 0,
  19. Y = 0,
  20. BorderStyle = LineStyle.Single,
  21. Type = SliderType.Multiple,
  22. Orientation = Orientation.Vertical,
  23. UseMinimumSize = true,
  24. MinimumInnerSpacing = 0
  25. };
  26. filterSlider.Options = Enum.GetValues (typeof (MouseFlags))
  27. .Cast<MouseFlags> ()
  28. .Where (value => !value.ToString ().Contains ("None") && !value.ToString ().Contains ("All"))
  29. .Select (
  30. value => new SliderOption<MouseFlags>
  31. {
  32. Legend = value.ToString (),
  33. Data = value
  34. })
  35. .ToList ();
  36. for (var i = 0; i < filterSlider.Options.Count; i++)
  37. {
  38. if (filterSlider.Options [i].Data != MouseFlags.ReportMousePosition)
  39. {
  40. filterSlider.SetOption (i);
  41. }
  42. }
  43. win.Add (filterSlider);
  44. var clearButton = new Button
  45. {
  46. Title = "_Clear Logs",
  47. X = 1,
  48. Y = Pos.Bottom (filterSlider) + 1
  49. };
  50. win.Add (clearButton);
  51. Label ml;
  52. var count = 0;
  53. ml = new () { X = Pos.Right (filterSlider), Y = 0, Text = "Mouse: " };
  54. win.Add (ml);
  55. CheckBox cbWantContinuousPresses = new ()
  56. {
  57. X = Pos.Right (filterSlider),
  58. Y = Pos.Bottom (ml),
  59. Title = "_Want Continuous Button Pressed"
  60. };
  61. win.Add (cbWantContinuousPresses);
  62. CheckBox cbHighlightOnPressed = new ()
  63. {
  64. X = Pos.Right (filterSlider),
  65. Y = Pos.Bottom (cbWantContinuousPresses),
  66. Title = "_Highlight on Pressed"
  67. };
  68. win.Add (cbHighlightOnPressed);
  69. CheckBox cbHighlightOnPressedOutside = new ()
  70. {
  71. X = Pos.Right (filterSlider),
  72. Y = Pos.Bottom (cbHighlightOnPressed),
  73. Title = "_Highlight on PressedOutside"
  74. };
  75. win.Add (cbHighlightOnPressedOutside);
  76. var demo = new MouseEventDemoView
  77. {
  78. Id = "demo",
  79. X = Pos.Right (filterSlider),
  80. Y = Pos.Bottom (cbHighlightOnPressedOutside),
  81. Width = Dim.Fill (),
  82. Height = 15,
  83. Title = "Enter/Leave Demo"
  84. };
  85. demo.Padding!.Initialized += DemoPaddingOnInitialized;
  86. void DemoPaddingOnInitialized (object o, EventArgs eventArgs)
  87. {
  88. demo.Padding!.Add (
  89. new MouseEventDemoView
  90. {
  91. X = 0,
  92. Y = 0,
  93. Width = Dim.Fill (),
  94. Height = Dim.Func (_ => demo.Padding.Thickness.Top),
  95. Title = "inPadding",
  96. Id = "inPadding"
  97. });
  98. demo.Padding.Thickness = demo.Padding.Thickness with { Top = 5 };
  99. }
  100. View sub1 = new MouseEventDemoView
  101. {
  102. X = 0,
  103. Y = 0,
  104. Width = Dim.Percent (20),
  105. Height = Dim.Fill (),
  106. Title = "sub1",
  107. Id = "sub1"
  108. };
  109. demo.Add (sub1);
  110. View sub2 = new MouseEventDemoView
  111. {
  112. X = Pos.Right (sub1) - 4,
  113. Y = Pos.Top (sub1) + 1,
  114. Width = Dim.Percent (20),
  115. Height = Dim.Fill (1),
  116. Title = "sub2",
  117. Id = "sub2"
  118. };
  119. demo.Add (sub2);
  120. win.Add (demo);
  121. cbHighlightOnPressed.CheckedState = demo.HighlightStates.HasFlag (MouseState.Pressed) ? CheckState.Checked : CheckState.UnChecked;
  122. cbHighlightOnPressed.CheckedStateChanging += (_, e) =>
  123. {
  124. if (e.Result == CheckState.Checked)
  125. {
  126. demo.HighlightStates |= MouseState.Pressed;
  127. }
  128. else
  129. {
  130. demo.HighlightStates &= ~MouseState.Pressed;
  131. }
  132. foreach (View subview in demo.SubViews)
  133. {
  134. if (e.Result == CheckState.Checked)
  135. {
  136. subview.HighlightStates |= MouseState.Pressed;
  137. }
  138. else
  139. {
  140. subview.HighlightStates &= ~MouseState.Pressed;
  141. }
  142. }
  143. foreach (View subview in demo.Padding.SubViews)
  144. {
  145. if (e.Result == CheckState.Checked)
  146. {
  147. subview.HighlightStates |= MouseState.Pressed;
  148. }
  149. else
  150. {
  151. subview.HighlightStates &= ~MouseState.Pressed;
  152. }
  153. }
  154. };
  155. cbHighlightOnPressedOutside.CheckedState = demo.HighlightStates.HasFlag (MouseState.PressedOutside) ? CheckState.Checked : CheckState.UnChecked;
  156. cbHighlightOnPressedOutside.CheckedStateChanging += (_, e) =>
  157. {
  158. if (e.Result == CheckState.Checked)
  159. {
  160. demo.HighlightStates |= MouseState.PressedOutside;
  161. }
  162. else
  163. {
  164. demo.HighlightStates &= ~MouseState.PressedOutside;
  165. }
  166. foreach (View subview in demo.SubViews)
  167. {
  168. if (e.Result == CheckState.Checked)
  169. {
  170. subview.HighlightStates |= MouseState.PressedOutside;
  171. }
  172. else
  173. {
  174. subview.HighlightStates &= ~MouseState.PressedOutside;
  175. }
  176. }
  177. foreach (View subview in demo.Padding.SubViews)
  178. {
  179. if (e.Result == CheckState.Checked)
  180. {
  181. subview.HighlightStates |= MouseState.PressedOutside;
  182. }
  183. else
  184. {
  185. subview.HighlightStates &= ~MouseState.PressedOutside;
  186. }
  187. }
  188. };
  189. cbWantContinuousPresses.CheckedStateChanging += (_, _) =>
  190. {
  191. demo.WantContinuousButtonPressed = !demo.WantContinuousButtonPressed;
  192. foreach (View subview in demo.SubViews)
  193. {
  194. subview.WantContinuousButtonPressed = demo.WantContinuousButtonPressed;
  195. }
  196. foreach (View subview in demo.Padding.SubViews)
  197. {
  198. subview.WantContinuousButtonPressed = demo.WantContinuousButtonPressed;
  199. }
  200. };
  201. var label = new Label
  202. {
  203. Text = "_App Events:",
  204. X = Pos.Right (filterSlider),
  205. Y = Pos.Bottom (demo)
  206. };
  207. ObservableCollection<string> appLogList = new ();
  208. var appLog = new ListView
  209. {
  210. X = Pos.Left (label),
  211. Y = Pos.Bottom (label),
  212. Width = 50,
  213. Height = Dim.Fill (),
  214. SchemeName = "Runnable",
  215. Source = new ListWrapper<string> (appLogList)
  216. };
  217. win.Add (label, appLog);
  218. Application.MouseEvent += (_, a) =>
  219. {
  220. int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
  221. if (filterSlider.GetSetOptions ().Contains (i))
  222. {
  223. ml.Text = $"MouseEvent: ({a.Position}) - {a.Flags} {count}";
  224. appLogList.Add ($"({a.Position}) - {a.Flags} {count++}");
  225. appLog.MoveDown ();
  226. }
  227. };
  228. label = new ()
  229. {
  230. Text = "_Window Events:",
  231. X = Pos.Right (appLog) + 1,
  232. Y = Pos.Top (label)
  233. };
  234. ObservableCollection<string> winLogList = [];
  235. var winLog = new ListView
  236. {
  237. X = Pos.Left (label),
  238. Y = Pos.Bottom (label),
  239. Width = Dim.Percent (50),
  240. Height = Dim.Fill (),
  241. SchemeName = "Runnable",
  242. Source = new ListWrapper<string> (winLogList)
  243. };
  244. win.Add (label, winLog);
  245. clearButton.Accepting += (_, _) =>
  246. {
  247. appLogList.Clear ();
  248. appLog.SetSource (appLogList);
  249. winLogList.Clear ();
  250. winLog.SetSource (winLogList);
  251. };
  252. win.MouseEvent += (_, a) =>
  253. {
  254. int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
  255. if (filterSlider.GetSetOptions ().Contains (i))
  256. {
  257. winLogList.Add ($"MouseEvent: ({a.Position}) - {a.Flags} {count++}");
  258. winLog.MoveDown ();
  259. }
  260. };
  261. Application.Run (win);
  262. win.Dispose ();
  263. Application.Shutdown ();
  264. }
  265. public class MouseEventDemoView : View
  266. {
  267. public MouseEventDemoView ()
  268. {
  269. CanFocus = true;
  270. Id = "mouseEventDemoView";
  271. Initialized += OnInitialized;
  272. MouseLeave += (_, _) => { Text = "Leave"; };
  273. MouseEnter += (_, _) => { Text = "Enter"; };
  274. return;
  275. void OnInitialized (object sender, EventArgs e)
  276. {
  277. TextAlignment = Alignment.Center;
  278. VerticalTextAlignment = Alignment.Center;
  279. Padding!.Thickness = new (1, 1, 1, 1);
  280. Padding!.SetScheme (new (new Attribute (Color.Black)));
  281. Padding.Id = $"{Id}.Padding";
  282. Border!.Thickness = new (1);
  283. Border.LineStyle = LineStyle.Rounded;
  284. Border.Id = $"{Id}.Border";
  285. MouseStateChanged += (_, args) =>
  286. {
  287. if (args.Value.HasFlag (MouseState.PressedOutside))
  288. {
  289. Border.LineStyle = LineStyle.Dotted;
  290. }
  291. else
  292. {
  293. Border.LineStyle = LineStyle.Single;
  294. }
  295. SetNeedsDraw ();
  296. };
  297. }
  298. }
  299. /// <inheritdoc/>
  300. protected override bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute)
  301. {
  302. if (role == VisualRole.Normal)
  303. {
  304. if (MouseState.HasFlag (MouseState.Pressed) && HighlightStates.HasFlag (MouseState.Pressed))
  305. {
  306. currentAttribute = currentAttribute with { Background = currentAttribute.Foreground.GetBrighterColor () };
  307. return true;
  308. }
  309. }
  310. return base.OnGettingAttributeForRole (in role, ref currentAttribute);
  311. }
  312. }
  313. }