Explorar el Código

Prepping to combine keybinding classes

Tig hace 7 meses
padre
commit
7360683152

+ 1 - 1
Terminal.Gui/Application/Application.Initialization.cs

@@ -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

+ 37 - 50
Terminal.Gui/Application/Application.Keyboard.cs

@@ -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,30 +231,31 @@ 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;
 
-        KeyBindings.Add (QuitKey, Command.Quit);
+        // Need to clear after setting the above to ensure actually clear
+        // because set_QuitKey etc.. may call Add
+        KeyBindings.Clear ();
 
-        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 (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);
+
         // 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;
-        }
-
-        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);
-            }
-        }
+        KeyBindings.ReplaceKey (oldKey, newKey);
+
+        //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);
+        //    }
+        //}
     }
 
 

+ 2 - 1
Terminal.Gui/Application/Application.cs

@@ -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

+ 29 - 13
Terminal.Gui/Input/Keyboard/ApplicationKeyBindings.cs

@@ -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 _))
+        if (!newKey.IsValid)
         {
-            throw new InvalidOperationException ($"Key {oldKey} is not bound.");
+            throw new InvalidOperationException ($"Key {newKey} is is not valid.");
         }
 
-        if (!newKey.IsValid)
+        if (newKey == Key.Empty)
         {
-            throw new InvalidOperationException ($"Key {newKey} is is not valid.");
+            Remove (oldKey);
+            return;
         }
 
-        ApplicationKeyBinding binding = Bindings [oldKey];
-        Remove (oldKey);
-        Add (newKey, binding);
+
+        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>

+ 1 - 1
Terminal.Gui/Views/Menu/ContextMenu.cs

@@ -109,7 +109,7 @@ public sealed class ContextMenu : IDisposable
         _menuBar?.Dispose ();
         _menuBar = null;
         IsShow = false;
-        `
+
         if (_container is { })
         {
             _container.Closing -= Container_Closing;

+ 1 - 4
UnitTests/Application/ApplicationTests.cs

@@ -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;

+ 2 - 2
UnitTests/Views/ShortcutTests.cs

@@ -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]