|
@@ -1,45 +1,49 @@
|
|
#nullable enable
|
|
#nullable enable
|
|
-using System.Text.Json.Serialization;
|
|
|
|
-
|
|
|
|
namespace Terminal.Gui;
|
|
namespace Terminal.Gui;
|
|
|
|
|
|
public static partial class Application // Keyboard handling
|
|
public static partial class Application // Keyboard handling
|
|
{
|
|
{
|
|
|
|
+ private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrrides
|
|
private static Key _nextTabKey = Key.Tab; // Resources/config.json overrrides
|
|
private static Key _nextTabKey = Key.Tab; // Resources/config.json overrrides
|
|
|
|
|
|
- /// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
|
|
|
|
- [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
|
|
- public static Key NextTabKey
|
|
|
|
- {
|
|
|
|
- get => _nextTabKey;
|
|
|
|
- set
|
|
|
|
- {
|
|
|
|
- if (_nextTabKey != value)
|
|
|
|
- {
|
|
|
|
- ReplaceKey (_nextTabKey, value);
|
|
|
|
- _nextTabKey = value;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrrides
|
|
|
|
|
|
private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrrides
|
|
private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrrides
|
|
|
|
|
|
- /// <summary>Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.</summary>
|
|
|
|
- [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
|
|
- public static Key PrevTabKey
|
|
|
|
- {
|
|
|
|
- get => _prevTabKey;
|
|
|
|
- set
|
|
|
|
- {
|
|
|
|
- if (_prevTabKey != value)
|
|
|
|
- {
|
|
|
|
- ReplaceKey (_prevTabKey, value);
|
|
|
|
- _prevTabKey = value;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ private static Key _quitKey = Key.Esc; // Resources/config.json overrrides
|
|
|
|
|
|
- private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrrides
|
|
|
|
|
|
+ static Application () { AddApplicationKeyBindings (); }
|
|
|
|
+
|
|
|
|
+ /// <summary>Gets the key bindings for this view.</summary>
|
|
|
|
+ public static KeyBindings KeyBindings { get; internal set; } = new ();
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Event fired when the user presses a key. Fired by <see cref="OnKeyDown"/>.
|
|
|
|
+ /// <para>
|
|
|
|
+ /// Set <see cref="Key.Handled"/> to <see langword="true"/> to indicate the key was handled and to prevent
|
|
|
|
+ /// additional processing.
|
|
|
|
+ /// </para>
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <remarks>
|
|
|
|
+ /// All drivers support firing the <see cref="KeyDown"/> event. Some drivers (Curses) do not support firing the
|
|
|
|
+ /// <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
|
|
|
|
+ /// <para>Fired after <see cref="KeyDown"/> and before <see cref="KeyUp"/>.</para>
|
|
|
|
+ /// </remarks>
|
|
|
|
+ public static event EventHandler<Key>? KeyDown;
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Event fired when the user releases a key. Fired by <see cref="OnKeyUp"/>.
|
|
|
|
+ /// <para>
|
|
|
|
+ /// Set <see cref="Key.Handled"/> to <see langword="true"/> to indicate the key was handled and to prevent
|
|
|
|
+ /// additional processing.
|
|
|
|
+ /// </para>
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <remarks>
|
|
|
|
+ /// All drivers support firing the <see cref="KeyDown"/> event. Some drivers (Curses) do not support firing the
|
|
|
|
+ /// <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
|
|
|
|
+ /// <para>Fired after <see cref="KeyDown"/>.</para>
|
|
|
|
+ /// </remarks>
|
|
|
|
+ public static event EventHandler<Key>? KeyUp;
|
|
|
|
|
|
/// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
|
|
/// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
|
|
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
@@ -56,71 +60,21 @@ public static partial class Application // Keyboard handling
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrrides
|
|
|
|
-
|
|
|
|
- /// <summary>Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.</summary>
|
|
|
|
- [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
|
|
- public static Key PrevTabGroupKey
|
|
|
|
- {
|
|
|
|
- get => _prevTabGroupKey;
|
|
|
|
- set
|
|
|
|
- {
|
|
|
|
- if (_prevTabGroupKey != value)
|
|
|
|
- {
|
|
|
|
- ReplaceKey (_prevTabGroupKey, value);
|
|
|
|
- _prevTabGroupKey = value;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private static Key _quitKey = Key.Esc; // Resources/config.json overrrides
|
|
|
|
-
|
|
|
|
- /// <summary>Gets or sets the key to quit the application.</summary>
|
|
|
|
|
|
+ /// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
|
|
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
- public static Key QuitKey
|
|
|
|
|
|
+ public static Key NextTabKey
|
|
{
|
|
{
|
|
- get => _quitKey;
|
|
|
|
|
|
+ get => _nextTabKey;
|
|
set
|
|
set
|
|
{
|
|
{
|
|
- if (_quitKey != value)
|
|
|
|
|
|
+ if (_nextTabKey != value)
|
|
{
|
|
{
|
|
- ReplaceKey (_quitKey, value);
|
|
|
|
- _quitKey = value;
|
|
|
|
|
|
+ ReplaceKey (_nextTabKey, value);
|
|
|
|
+ _nextTabKey = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static void ReplaceKey (Key oldKey, Key newKey)
|
|
|
|
- {
|
|
|
|
- if (KeyBindings.Bindings.Count == 0)
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (newKey == Key.Empty)
|
|
|
|
- {
|
|
|
|
- KeyBindings.Remove (oldKey);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- KeyBindings.ReplaceKey (oldKey, newKey);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /// <summary>
|
|
|
|
- /// Event fired when the user presses a key. Fired by <see cref="OnKeyDown"/>.
|
|
|
|
- /// <para>
|
|
|
|
- /// Set <see cref="Key.Handled"/> to <see langword="true"/> to indicate the key was handled and to prevent
|
|
|
|
- /// additional processing.
|
|
|
|
- /// </para>
|
|
|
|
- /// </summary>
|
|
|
|
- /// <remarks>
|
|
|
|
- /// All drivers support firing the <see cref="KeyDown"/> event. Some drivers (Curses) do not support firing the
|
|
|
|
- /// <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
|
|
|
|
- /// <para>Fired after <see cref="KeyDown"/> and before <see cref="KeyUp"/>.</para>
|
|
|
|
- /// </remarks>
|
|
|
|
- public static event EventHandler<Key>? KeyDown;
|
|
|
|
-
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Called by the <see cref="ConsoleDriver"/> when the user presses a key. Fires the <see cref="KeyDown"/> event
|
|
/// Called by the <see cref="ConsoleDriver"/> when the user presses a key. Fires the <see cref="KeyDown"/> event
|
|
/// then calls <see cref="View.NewKeyDownEvent"/> on all top level views. Called after <see cref="OnKeyDown"/> and
|
|
/// then calls <see cref="View.NewKeyDownEvent"/> on all top level views. Called after <see cref="OnKeyDown"/> and
|
|
@@ -217,20 +171,6 @@ public static partial class Application // Keyboard handling
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
|
- /// Event fired when the user releases a key. Fired by <see cref="OnKeyUp"/>.
|
|
|
|
- /// <para>
|
|
|
|
- /// Set <see cref="Key.Handled"/> to <see langword="true"/> to indicate the key was handled and to prevent
|
|
|
|
- /// additional processing.
|
|
|
|
- /// </para>
|
|
|
|
- /// </summary>
|
|
|
|
- /// <remarks>
|
|
|
|
- /// All drivers support firing the <see cref="KeyDown"/> event. Some drivers (Curses) do not support firing the
|
|
|
|
- /// <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
|
|
|
|
- /// <para>Fired after <see cref="KeyDown"/>.</para>
|
|
|
|
- /// </remarks>
|
|
|
|
- public static event EventHandler<Key>? KeyUp;
|
|
|
|
-
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Called by the <see cref="ConsoleDriver"/> when the user releases a key. Fires the <see cref="KeyUp"/> event
|
|
/// Called by the <see cref="ConsoleDriver"/> when the user releases a key. Fires the <see cref="KeyUp"/> event
|
|
/// then calls <see cref="View.NewKeyUpEvent"/> on all top level views. Called after <see cref="OnKeyDown"/>.
|
|
/// then calls <see cref="View.NewKeyUpEvent"/> on all top level views. Called after <see cref="OnKeyDown"/>.
|
|
@@ -268,33 +208,50 @@ public static partial class Application // Keyboard handling
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- /// <summary>Gets the key bindings for this view.</summary>
|
|
|
|
- public static KeyBindings KeyBindings { get; internal set; } = new ();
|
|
|
|
-
|
|
|
|
- /// <summary>
|
|
|
|
- /// Commands for Application.
|
|
|
|
- /// </summary>
|
|
|
|
- private static Dictionary<Command, Func<CommandContext, bool?>>? CommandImplementations { get; set; }
|
|
|
|
|
|
+ /// <summary>Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.</summary>
|
|
|
|
+ [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
|
|
+ public static Key PrevTabGroupKey
|
|
|
|
+ {
|
|
|
|
+ get => _prevTabGroupKey;
|
|
|
|
+ set
|
|
|
|
+ {
|
|
|
|
+ if (_prevTabGroupKey != value)
|
|
|
|
+ {
|
|
|
|
+ ReplaceKey (_prevTabGroupKey, value);
|
|
|
|
+ _prevTabGroupKey = value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- /// <summary>
|
|
|
|
- /// <para>
|
|
|
|
- /// Sets the function that will be invoked for a <see cref="Command"/>.
|
|
|
|
- /// </para>
|
|
|
|
- /// <para>
|
|
|
|
- /// If AddCommand has already been called for <paramref name="command"/> <paramref name="f"/> will
|
|
|
|
- /// replace the old one.
|
|
|
|
- /// </para>
|
|
|
|
- /// </summary>
|
|
|
|
- /// <remarks>
|
|
|
|
- /// <para>
|
|
|
|
- /// This version of AddCommand is for commands that do not require a <see cref="CommandContext"/>.
|
|
|
|
- /// </para>
|
|
|
|
- /// </remarks>
|
|
|
|
- /// <param name="command">The command.</param>
|
|
|
|
- /// <param name="f">The function.</param>
|
|
|
|
- private static void AddCommand (Command command, Func<bool?> f) { CommandImplementations! [command] = ctx => f (); }
|
|
|
|
|
|
+ /// <summary>Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.</summary>
|
|
|
|
+ [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
|
|
+ public static Key PrevTabKey
|
|
|
|
+ {
|
|
|
|
+ get => _prevTabKey;
|
|
|
|
+ set
|
|
|
|
+ {
|
|
|
|
+ if (_prevTabKey != value)
|
|
|
|
+ {
|
|
|
|
+ ReplaceKey (_prevTabKey, value);
|
|
|
|
+ _prevTabKey = value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- static Application () { AddApplicationKeyBindings (); }
|
|
|
|
|
|
+ /// <summary>Gets or sets the key to quit the application.</summary>
|
|
|
|
+ [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
|
|
|
|
+ public static Key QuitKey
|
|
|
|
+ {
|
|
|
|
+ get => _quitKey;
|
|
|
|
+ set
|
|
|
|
+ {
|
|
|
|
+ if (_quitKey != value)
|
|
|
|
+ {
|
|
|
|
+ ReplaceKey (_quitKey, value);
|
|
|
|
+ _quitKey = value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
internal static void AddApplicationKeyBindings ()
|
|
internal static void AddApplicationKeyBindings ()
|
|
{
|
|
{
|
|
@@ -303,7 +260,7 @@ public static partial class Application // Keyboard handling
|
|
// Things this view knows how to do
|
|
// Things this view knows how to do
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.QuitToplevel, // TODO: IRunnable: Rename to Command.Quit to make more generic.
|
|
Command.QuitToplevel, // TODO: IRunnable: Rename to Command.Quit to make more generic.
|
|
- () =>
|
|
|
|
|
|
+ static () =>
|
|
{
|
|
{
|
|
if (ApplicationOverlapped.OverlappedTop is { })
|
|
if (ApplicationOverlapped.OverlappedTop is { })
|
|
{
|
|
{
|
|
@@ -320,7 +277,7 @@ public static partial class Application // Keyboard handling
|
|
|
|
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.Suspend,
|
|
Command.Suspend,
|
|
- () =>
|
|
|
|
|
|
+ static () =>
|
|
{
|
|
{
|
|
Driver?.Suspend ();
|
|
Driver?.Suspend ();
|
|
|
|
|
|
@@ -330,40 +287,22 @@ public static partial class Application // Keyboard handling
|
|
|
|
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.NextView,
|
|
Command.NextView,
|
|
- () =>
|
|
|
|
- {
|
|
|
|
- View? current = Application.Current;
|
|
|
|
- if (current is { })
|
|
|
|
- {
|
|
|
|
- return current.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
|
|
+ static () => Current?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop));
|
|
|
|
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.PreviousView,
|
|
Command.PreviousView,
|
|
- () =>
|
|
|
|
- {
|
|
|
|
- View? current = Application.Current;
|
|
|
|
- if (current is { })
|
|
|
|
- {
|
|
|
|
- return current.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabStop);
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
|
|
+ static () => Current?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabStop));
|
|
|
|
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.NextViewOrTop,
|
|
Command.NextViewOrTop,
|
|
- () =>
|
|
|
|
|
|
+ static () =>
|
|
{
|
|
{
|
|
|
|
+ // TODO: This OverlapppedTop tomfoolery goes away in addressing #2491
|
|
if (ApplicationOverlapped.OverlappedTop is null)
|
|
if (ApplicationOverlapped.OverlappedTop is null)
|
|
{
|
|
{
|
|
- View? current = Application.Current;
|
|
|
|
- if (current is { })
|
|
|
|
|
|
+ if ((View?)Current is { })
|
|
{
|
|
{
|
|
- return current.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
|
|
|
|
|
|
+ return Current.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -379,19 +318,19 @@ public static partial class Application // Keyboard handling
|
|
|
|
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.PreviousViewOrTop,
|
|
Command.PreviousViewOrTop,
|
|
- () =>
|
|
|
|
|
|
+ static () =>
|
|
{
|
|
{
|
|
|
|
+ // TODO: This OverlapppedTop tomfoolery goes away in addressing #2491
|
|
if (ApplicationOverlapped.OverlappedTop is null)
|
|
if (ApplicationOverlapped.OverlappedTop is null)
|
|
{
|
|
{
|
|
- View? current = Application.Current;
|
|
|
|
- if (current is { })
|
|
|
|
|
|
+ if ((View?)Current is { })
|
|
{
|
|
{
|
|
- return current.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
|
|
|
|
|
|
+ return Current.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- ApplicationOverlapped.OverlappedMovePrevious();
|
|
|
|
|
|
+ ApplicationOverlapped.OverlappedMovePrevious ();
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -402,7 +341,7 @@ public static partial class Application // Keyboard handling
|
|
|
|
|
|
AddCommand (
|
|
AddCommand (
|
|
Command.Refresh,
|
|
Command.Refresh,
|
|
- () =>
|
|
|
|
|
|
+ static () =>
|
|
{
|
|
{
|
|
Refresh ();
|
|
Refresh ();
|
|
|
|
|
|
@@ -464,4 +403,44 @@ public static partial class Application // Keyboard handling
|
|
.Distinct ()
|
|
.Distinct ()
|
|
.ToList ();
|
|
.ToList ();
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// <para>
|
|
|
|
+ /// Sets the function that will be invoked for a <see cref="Command"/>.
|
|
|
|
+ /// </para>
|
|
|
|
+ /// <para>
|
|
|
|
+ /// If AddCommand has already been called for <paramref name="command"/> <paramref name="f"/> will
|
|
|
|
+ /// replace the old one.
|
|
|
|
+ /// </para>
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <remarks>
|
|
|
|
+ /// <para>
|
|
|
|
+ /// This version of AddCommand is for commands that do not require a <see cref="CommandContext"/>.
|
|
|
|
+ /// </para>
|
|
|
|
+ /// </remarks>
|
|
|
|
+ /// <param name="command">The command.</param>
|
|
|
|
+ /// <param name="f">The function.</param>
|
|
|
|
+ private static void AddCommand (Command command, Func<bool?> f) { CommandImplementations! [command] = ctx => f (); }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Commands for Application.
|
|
|
|
+ /// </summary>
|
|
|
|
+ private static Dictionary<Command, Func<CommandContext, bool?>>? CommandImplementations { get; set; }
|
|
|
|
+
|
|
|
|
+ private static void ReplaceKey (Key oldKey, Key newKey)
|
|
|
|
+ {
|
|
|
|
+ if (KeyBindings.Bindings.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (newKey == Key.Empty)
|
|
|
|
+ {
|
|
|
|
+ KeyBindings.Remove (oldKey);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ KeyBindings.ReplaceKey (oldKey, newKey);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|