KeyBindings.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Text;
  6. namespace UICatalog.Scenarios;
  7. [ScenarioMetadata ("KeyBindings", "Illustrates the KeyBindings API.")]
  8. [ScenarioCategory ("Mouse and Keyboard")]
  9. public sealed class KeyBindings : Scenario
  10. {
  11. private readonly ObservableCollection<string> _focusedBindings = [];
  12. private ListView _focusedBindingsListView;
  13. public override void Main ()
  14. {
  15. // Init
  16. Application.Init ();
  17. // Setup - Create a top-level application window and configure it.
  18. Window appWindow = new ()
  19. {
  20. Title = GetQuitKeyAndName (),
  21. SuperViewRendersLineCanvas = true,
  22. };
  23. Label label = new ()
  24. {
  25. Title = "_Label:",
  26. };
  27. TextField textField = new ()
  28. {
  29. X = Pos.Right (label),
  30. Y = Pos.Top (label),
  31. Width = 20,
  32. };
  33. appWindow.Add (label, textField);
  34. Button button = new ()
  35. {
  36. X = Pos.Right (textField) + 1,
  37. Y = Pos.Top (label),
  38. Text = "_Button",
  39. };
  40. appWindow.Add (button);
  41. KeyBindingsDemo keyBindingsDemo = new ()
  42. {
  43. X = Pos.Right (button) + 1,
  44. Width = Dim.Auto (DimAutoStyle.Text),
  45. Height = Dim.Auto (DimAutoStyle.Text),
  46. HotKeySpecifier = (Rune)'_',
  47. Title = "_KeyBindingsDemo",
  48. Text = $"""
  49. These keys will cause this view to show a message box:
  50. - Hotkey: k, K, Alt-K, Alt-Shift-K
  51. - Focused: F3
  52. - Application: F4
  53. Pressing Esc or {Application.QuitKey} will cause it to quit the app.
  54. """,
  55. BorderStyle = LineStyle.Dashed
  56. };
  57. appWindow.Add (keyBindingsDemo);
  58. ObservableCollection<string> appBindings = new ();
  59. ListView appBindingsListView = new ()
  60. {
  61. Title = "_Application Bindings",
  62. BorderStyle = LineStyle.Single,
  63. X = -1,
  64. Y = Pos.Bottom (keyBindingsDemo) + 1,
  65. Width = Dim.Auto (),
  66. Height = Dim.Fill () + 1,
  67. CanFocus = true,
  68. Source = new ListWrapper<string> (appBindings),
  69. SuperViewRendersLineCanvas = true
  70. };
  71. appWindow.Add (appBindingsListView);
  72. foreach (Key key in Application.KeyBindings.GetBindings().ToDictionary().Keys)
  73. {
  74. var binding = Application.KeyBindings.Get (key);
  75. appBindings.Add ($"{key} -> {binding.Target?.GetType ().Name} - {binding.Commands [0]}");
  76. }
  77. ObservableCollection<string> hotkeyBindings = new ();
  78. ListView hotkeyBindingsListView = new ()
  79. {
  80. Title = "_Hotkey Bindings",
  81. BorderStyle = LineStyle.Single,
  82. X = Pos.Right (appBindingsListView) - 1,
  83. Y = Pos.Bottom (keyBindingsDemo) + 1,
  84. Width = Dim.Auto (),
  85. Height = Dim.Fill () + 1,
  86. CanFocus = true,
  87. Source = new ListWrapper<string> (hotkeyBindings),
  88. SuperViewRendersLineCanvas = true
  89. };
  90. appWindow.Add (hotkeyBindingsListView);
  91. foreach (var subview in appWindow.SubViews)
  92. {
  93. foreach (KeyValuePair<Key, KeyBinding> binding in subview.HotKeyBindings.GetBindings ())
  94. {
  95. hotkeyBindings.Add ($"{binding.Key} -> {subview.GetType ().Name} - {binding.Value.Commands [0]}");
  96. }
  97. }
  98. _focusedBindingsListView = new ()
  99. {
  100. Title = "_Focused Bindings",
  101. BorderStyle = LineStyle.Single,
  102. X = Pos.Right (hotkeyBindingsListView) - 1,
  103. Y = Pos.Bottom (keyBindingsDemo) + 1,
  104. Width = Dim.Auto (),
  105. Height = Dim.Fill () + 1,
  106. CanFocus = true,
  107. Source = new ListWrapper<string> (_focusedBindings),
  108. SuperViewRendersLineCanvas = true
  109. };
  110. appWindow.Add (_focusedBindingsListView);
  111. Application.Navigation!.FocusedChanged += Application_HasFocusChanged;
  112. // Run - Start the application.
  113. Application.Run (appWindow);
  114. Application.Navigation!.FocusedChanged -= Application_HasFocusChanged;
  115. appWindow.Dispose ();
  116. // Shutdown - Calling Application.Shutdown is required.
  117. Application.Shutdown ();
  118. }
  119. private void Application_HasFocusChanged (object sender, EventArgs e)
  120. {
  121. View focused = Application.Navigation!.GetFocused ();
  122. if (focused == null)
  123. {
  124. return;
  125. }
  126. _focusedBindingsListView.Title = $"_Focused ({focused?.GetType ().Name}) Bindings";
  127. _focusedBindings.Clear ();
  128. foreach (var binding in focused?.KeyBindings!.GetBindings ())
  129. {
  130. _focusedBindings.Add ($"{binding.Key} -> {binding.Value.Commands [0]}");
  131. }
  132. }
  133. }
  134. public class KeyBindingsDemo : View
  135. {
  136. public KeyBindingsDemo ()
  137. {
  138. CanFocus = true;
  139. AddCommand (Command.Save, ctx =>
  140. {
  141. MessageBox.Query (Application.Instance, $"{ctx.Command}", $"Ctx: {ctx}", buttons: "Ok");
  142. return true;
  143. });
  144. AddCommand (Command.New, ctx =>
  145. {
  146. MessageBox.Query (Application.Instance, $"{ctx.Command}", $"Ctx: {ctx}", buttons: "Ok");
  147. return true;
  148. });
  149. AddCommand (Command.HotKey, ctx =>
  150. {
  151. MessageBox.Query (Application.Instance, $"{ctx.Command}", $"Ctx: {ctx}\nCommand: {ctx.Command}", buttons: "Ok");
  152. SetFocus ();
  153. return true;
  154. });
  155. KeyBindings.Add (Key.F2, Command.Save);
  156. KeyBindings.Add (Key.F3, Command.New); // same as specifying KeyBindingScope.Focused
  157. Application.KeyBindings.Add (Key.F4, this, Command.New);
  158. AddCommand (Command.Quit, ctx =>
  159. {
  160. if (ctx is not CommandContext<KeyBinding> keyCommandContext)
  161. {
  162. return false;
  163. }
  164. MessageBox.Query (Application.Instance, $"{keyCommandContext.Binding}", $"Key: {keyCommandContext.Binding.Key}\nCommand: {ctx.Command}", buttons: "Ok");
  165. Application.RequestStop ();
  166. return true;
  167. });
  168. Application.KeyBindings.Add (Key.Q.WithAlt, this, Command.Quit);
  169. }
  170. }