mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-30 17:57:57 +01:00
Prepping to combine keybinding classes
This commit is contained in:
@@ -92,7 +92,7 @@ public static partial class Application // Initialization (Init/Shutdown)
|
||||
}
|
||||
}
|
||||
|
||||
AddApplicationKeyBindings ();
|
||||
AddKeyBindings ();
|
||||
|
||||
// Start the process of configuration management.
|
||||
// Note that we end up calling LoadConfigurationFromAllSources
|
||||
|
||||
@@ -45,7 +45,7 @@ public static partial class Application // Keyboard handling
|
||||
|
||||
// Invoke any Application-scoped KeyBindings.
|
||||
// The first view that handles the key will stop the loop.
|
||||
foreach (KeyValuePair<Key, ApplicationKeyBinding> binding in KeyBindings.Bindings.Where (b => b.Key == key.KeyCode))
|
||||
foreach (KeyValuePair<Key, ApplicationKeyBinding> binding in KeyBindings.GetBindings (key))
|
||||
{
|
||||
if (binding.Value.Target is { })
|
||||
{
|
||||
@@ -155,12 +155,12 @@ public static partial class Application // Keyboard handling
|
||||
|
||||
#region Application-scoped KeyBindings
|
||||
|
||||
static Application () { AddApplicationKeyBindings (); }
|
||||
static Application () { AddKeyBindings (); }
|
||||
|
||||
/// <summary>Gets the Application-scoped key bindings.</summary>
|
||||
public static ApplicationKeyBindings KeyBindings { get; internal set; } = new ();
|
||||
|
||||
internal static void AddApplicationKeyBindings ()
|
||||
internal static void AddKeyBindings ()
|
||||
{
|
||||
CommandImplementations = new ();
|
||||
|
||||
@@ -231,29 +231,30 @@ public static partial class Application // Keyboard handling
|
||||
return false;
|
||||
});
|
||||
|
||||
KeyBindings.Clear ();
|
||||
|
||||
// Resources/config.json overrides
|
||||
QuitKey = Key.Esc;
|
||||
NextTabKey = Key.Tab;
|
||||
PrevTabKey = Key.Tab.WithShift;
|
||||
NextTabGroupKey = Key.F6;
|
||||
PrevTabGroupKey = Key.F6.WithShift;
|
||||
QuitKey = Key.Esc;
|
||||
ArrangeKey = Key.F5.WithCtrl;
|
||||
|
||||
// Need to clear after setting the above to ensure actually clear
|
||||
// because set_QuitKey etc.. may call Add
|
||||
KeyBindings.Clear ();
|
||||
|
||||
KeyBindings.Add (QuitKey, Command.Quit);
|
||||
KeyBindings.Add (NextTabKey, Command.NextTabStop);
|
||||
KeyBindings.Add (PrevTabKey, Command.PreviousTabStop);
|
||||
KeyBindings.Add (NextTabGroupKey, Command.NextTabGroup);
|
||||
KeyBindings.Add (PrevTabGroupKey, Command.PreviousTabGroup);
|
||||
KeyBindings.Add (ArrangeKey, Command.Edit);
|
||||
|
||||
KeyBindings.Add (Key.CursorRight, Command.NextTabStop);
|
||||
KeyBindings.Add (Key.CursorDown, Command.NextTabStop);
|
||||
KeyBindings.Add (Key.CursorLeft, Command.PreviousTabStop);
|
||||
KeyBindings.Add (Key.CursorUp, Command.PreviousTabStop);
|
||||
KeyBindings.Add (NextTabKey, Command.NextTabStop);
|
||||
KeyBindings.Add (PrevTabKey, Command.PreviousTabStop);
|
||||
|
||||
KeyBindings.Add (NextTabGroupKey, Command.NextTabGroup);
|
||||
KeyBindings.Add (PrevTabGroupKey, Command.PreviousTabGroup);
|
||||
|
||||
KeyBindings.Add (ArrangeKey, Command.Edit);
|
||||
|
||||
// TODO: Refresh Key should be configurable
|
||||
KeyBindings.Add (Key.F5, Command.Refresh);
|
||||
@@ -265,46 +266,32 @@ public static partial class Application // Keyboard handling
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="ApplicationKeyBinding"/>s.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is an internal method used by the <see cref="View"/> class to add Application key bindings.
|
||||
/// </remarks>
|
||||
/// <returns>The list of Views that have Application-scoped key bindings.</returns>
|
||||
internal static List<ApplicationKeyBinding> GetViewKeyBindings ()
|
||||
{
|
||||
// Get the list of views that do not have Application-scoped key bindings
|
||||
return KeyBindings.Bindings
|
||||
.Where (kv => kv.Value.Target is {})
|
||||
.Select (kv => kv.Value)
|
||||
.Distinct ()
|
||||
.ToList ();
|
||||
}
|
||||
|
||||
private static void ReplaceKey (Key oldKey, Key newKey)
|
||||
{
|
||||
if (KeyBindings.Bindings.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
KeyBindings.ReplaceKey (oldKey, newKey);
|
||||
|
||||
if (newKey == Key.Empty)
|
||||
{
|
||||
KeyBindings.Remove (oldKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KeyBindings.TryGet (oldKey, out ApplicationKeyBinding binding))
|
||||
{
|
||||
KeyBindings.Remove (oldKey);
|
||||
KeyBindings.Add (newKey, binding);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBindings.Add (newKey, binding);
|
||||
}
|
||||
}
|
||||
//return;
|
||||
//if (KeyBindings.Bindings.Count == 0)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
//if (newKey == Key.Empty)
|
||||
//{
|
||||
// KeyBindings.Remove (oldKey);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// if (KeyBindings.TryGet (oldKey, out ApplicationKeyBinding binding))
|
||||
// {
|
||||
// KeyBindings.Remove (oldKey);
|
||||
// KeyBindings.Add (newKey, binding);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// KeyBindings.Add (newKey, binding);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -214,7 +214,8 @@ public static partial class Application
|
||||
|
||||
ClearScreenNextIteration = false;
|
||||
|
||||
AddApplicationKeyBindings ();
|
||||
KeyBindings.Clear ();
|
||||
AddKeyBindings ();
|
||||
|
||||
// Reset synchronization context to allow the user to run async/await,
|
||||
// as the main loop has been ended, the synchronization context from
|
||||
|
||||
@@ -82,9 +82,7 @@ public class ApplicationKeyBindings
|
||||
Add (key, binding);
|
||||
}
|
||||
|
||||
// TODO: This should not be public!
|
||||
/// <summary>The collection of <see cref="ApplicationKeyBinding"/> objects.</summary>
|
||||
public Dictionary<Key, ApplicationKeyBinding> Bindings { get; } = new (new KeyEqualityComparer ());
|
||||
private Dictionary<Key, ApplicationKeyBinding> Bindings { get; } = new (new KeyEqualityComparer ());
|
||||
|
||||
/// <summary>
|
||||
/// Gets the keys that are bound.
|
||||
@@ -95,6 +93,16 @@ public class ApplicationKeyBindings
|
||||
return Bindings.Keys;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bindings bound to <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<KeyValuePair<Key, ApplicationKeyBinding>> GetBindings (Key key)
|
||||
{
|
||||
return Bindings.Where (b => b.Key == key.KeyCode);
|
||||
}
|
||||
|
||||
/// <summary>Removes all <see cref="ApplicationKeyBinding"/> objects from the collection.</summary>
|
||||
public void Clear () { Bindings.Clear (); }
|
||||
|
||||
@@ -193,25 +201,33 @@ public class ApplicationKeyBindings
|
||||
throw new InvalidOperationException ($"Key {key} is not bound.");
|
||||
}
|
||||
|
||||
/// <summary>Replaces a key combination already bound to a set of <see cref="Command"/>s.</summary>
|
||||
/// <remarks></remarks>
|
||||
/// <summary>Replaces a key combination bound to a set of <see cref="Command"/>s.</summary>
|
||||
/// <remarks>If <paramref name="oldKey"/> is not bound, this method has the same effect as <see cref="Add(Terminal.Gui.Key,Terminal.Gui.ApplicationKeyBinding)"/>.</remarks>
|
||||
/// <param name="oldKey">The key to be replaced.</param>
|
||||
/// <param name="newKey">The new key to be used. If <see cref="Key.Empty"/> no action will be taken.</param>
|
||||
/// <param name="newKey">The new key to be used. If <see cref="Key.Empty"/> this method has the same effect as <see cref="Remove"/>.</param>
|
||||
public void ReplaceKey (Key oldKey, Key newKey)
|
||||
{
|
||||
if (!TryGet (oldKey, out ApplicationKeyBinding _))
|
||||
{
|
||||
throw new InvalidOperationException ($"Key {oldKey} is not bound.");
|
||||
}
|
||||
|
||||
if (!newKey.IsValid)
|
||||
{
|
||||
throw new InvalidOperationException ($"Key {newKey} is is not valid.");
|
||||
}
|
||||
|
||||
ApplicationKeyBinding binding = Bindings [oldKey];
|
||||
Remove (oldKey);
|
||||
Add (newKey, binding);
|
||||
if (newKey == Key.Empty)
|
||||
{
|
||||
Remove (oldKey);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (TryGet (oldKey, out ApplicationKeyBinding binding))
|
||||
{
|
||||
Remove (oldKey);
|
||||
Add (newKey, binding);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add (newKey, binding);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the commands bound with the specified Key.</summary>
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed class ContextMenu : IDisposable
|
||||
_menuBar?.Dispose ();
|
||||
_menuBar = null;
|
||||
IsShow = false;
|
||||
`
|
||||
|
||||
if (_container is { })
|
||||
{
|
||||
_container.Closing -= Container_Closing;
|
||||
|
||||
@@ -317,9 +317,6 @@ public class ApplicationTests
|
||||
Assert.Empty (Application.TopLevels);
|
||||
Assert.Empty (Application._cachedViewsUnderMouse);
|
||||
|
||||
// Keyboard
|
||||
Assert.Empty (Application.GetViewKeyBindings ());
|
||||
|
||||
// Mouse
|
||||
Assert.Null (Application._lastMousePosition);
|
||||
|
||||
@@ -555,7 +552,7 @@ public class ApplicationTests
|
||||
|
||||
Assert.Equal (Key.Q.WithCtrl, Application.QuitKey);
|
||||
|
||||
Assert.Contains (Key.Q.WithCtrl, Application.KeyBindings.Bindings);
|
||||
Assert.NotEmpty (Application.KeyBindings.GetBindings (Key.Q.WithCtrl));
|
||||
|
||||
Application.Shutdown ();
|
||||
Locations = ConfigLocations.Default;
|
||||
|
||||
@@ -317,11 +317,11 @@ public class ShortcutTests
|
||||
|
||||
shortcut.BindKeyToApplication = true;
|
||||
Assert.DoesNotContain (Key.A, shortcut.KeyBindings.Bindings.Keys);
|
||||
Assert.Contains (Key.A, Application.KeyBindings.Bindings.Keys);
|
||||
Assert.NotEmpty (Application.KeyBindings.GetBindings(Key.A));
|
||||
|
||||
shortcut.BindKeyToApplication = false;
|
||||
Assert.Contains (Key.A, shortcut.KeyBindings.Bindings.Keys);
|
||||
Assert.DoesNotContain (Key.A, Application.KeyBindings.Bindings.Keys);
|
||||
Assert.Empty (Application.KeyBindings.GetBindings (Key.A));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
||||
Reference in New Issue
Block a user