Browse Source

Nuked OnInvokingKeyBindings from StatusBar

Tig 1 year ago
parent
commit
abb11f0778
2 changed files with 70 additions and 95 deletions
  1. 11 95
      Terminal.Gui/Views/StatusBar.cs
  2. 59 0
      Terminal.Gui/Views/StatusItem.cs

+ 11 - 95
Terminal.Gui/Views/StatusBar.cs

@@ -1,63 +1,5 @@
 namespace Terminal.Gui;
 
-/// <summary>
-///     <see cref="StatusItem"/> objects are contained by <see cref="StatusBar"/> <see cref="View"/>s. Each
-///     <see cref="StatusItem"/> has a title, a shortcut (hotkey), and an <see cref="Command"/> that will be invoked when
-///     the <see cref="StatusItem.Shortcut"/> is pressed. The <see cref="StatusItem.Shortcut"/> will be a global hotkey for
-///     the application in the current context of the screen. The color of the <see cref="StatusItem.Title"/> will be
-///     changed after each ~. A <see cref="StatusItem.Title"/> set to `~F1~ Help` will render as *F1* using
-///     <see cref="ColorScheme.HotNormal"/> and *Help* as <see cref="ColorScheme.HotNormal"/>.
-/// </summary>
-public class StatusItem
-{
-    /// <summary>Initializes a new <see cref="StatusItem"/>.</summary>
-    /// <param name="shortcut">Shortcut to activate the <see cref="StatusItem"/>.</param>
-    /// <param name="title">Title for the <see cref="StatusItem"/>.</param>
-    /// <param name="action">Action to invoke when the <see cref="StatusItem"/> is activated.</param>
-    /// <param name="canExecute">Function to determine if the action can currently be executed.</param>
-    public StatusItem (Key shortcut, string title, Action action, Func<bool> canExecute = null)
-    {
-        Title = title ?? "";
-        Shortcut = shortcut;
-        Action = action;
-        CanExecute = canExecute;
-    }
-
-    /// <summary>Gets or sets the action to be invoked when the statusbar item is triggered</summary>
-    /// <value>Action to invoke.</value>
-    public Action Action { get; set; }
-
-    /// <summary>
-    ///     Gets or sets the action to be invoked to determine if the <see cref="StatusItem"/> can be triggered. If
-    ///     <see cref="CanExecute"/> returns <see langword="true"/> the status item will be enabled. Otherwise, it will be
-    ///     disabled.
-    /// </summary>
-    /// <value>Function to determine if the action is can be executed or not.</value>
-    public Func<bool> CanExecute { get; set; }
-
-    /// <summary>Gets or sets arbitrary data for the status item.</summary>
-    /// <remarks>This property is not used internally.</remarks>
-    public object Data { get; set; }
-
-    /// <summary>Gets the global shortcut to invoke the action on the menu.</summary>
-    public Key Shortcut { get; set; }
-
-    /// <summary>Gets or sets the title.</summary>
-    /// <value>The title.</value>
-    /// <remarks>
-    ///     The colour of the <see cref="StatusItem.Title"/> will be changed after each ~. A
-    ///     <see cref="StatusItem.Title"/> set to `~F1~ Help` will render as *F1* using <see cref="ColorScheme.HotNormal"/> and
-    ///     *Help* as <see cref="ColorScheme.HotNormal"/>.
-    /// </remarks>
-    public string Title { get; set; }
-
-    /// <summary>
-    ///     Returns <see langword="true"/> if the status item is enabled. This method is a wrapper around
-    ///     <see cref="CanExecute"/>.
-    /// </summary>
-    public bool IsEnabled () { return CanExecute?.Invoke () ?? true; }
-}
-
 /// <summary>
 ///     A status bar is a <see cref="View"/> that snaps to the bottom of a <see cref="Toplevel"/> displaying set of
 ///     <see cref="StatusItem"/>s. The <see cref="StatusBar"/> should be context sensitive. This means, if the main menu
@@ -69,8 +11,7 @@ public class StatusBar : View
 {
     private static Rune _shortcutDelimiter = (Rune)'=';
 
-    private StatusItem [] _items = { };
-    private StatusItem _itemToInvoke;
+    private StatusItem [] _items = [];
 
     /// <summary>Initializes a new instance of the <see cref="StatusBar"/> class.</summary>
     public StatusBar () : this (new StatusItem [] { }) { }
@@ -91,10 +32,11 @@ public class StatusBar : View
         CanFocus = false;
         ColorScheme = Colors.ColorSchemes ["Menu"];
         X = 0;
-        Y = Pos.AnchorEnd (1);
+        Y = Pos.AnchorEnd ();
         Width = Dim.Fill ();
         Height = 1; // BUGBUG: Views should avoid setting Height as doing so implies Frame.Size == GetContentSize ().
-        AddCommand (Command.Accept, InvokeItem);
+
+        AddCommand (Command.Accept, ctx => InvokeItem ((StatusItem)ctx.KeyBinding?.Context));
     }
 
     /// <summary>The items that compose the <see cref="StatusBar"/></summary>
@@ -110,9 +52,10 @@ public class StatusBar : View
 
             _items = value;
 
-            foreach (StatusItem item in _items)
+            foreach (StatusItem item in _items.Where (i => i.Shortcut != Key.Empty))
             {
-                KeyBindings.Add (item.Shortcut, KeyBindingScope.HotKey, Command.Accept);
+                KeyBinding keyBinding = new (new [] { Command.Accept }, KeyBindingScope.HotKey, item);
+                KeyBindings.Add (item.Shortcut, keyBinding);
             }
         }
     }
@@ -142,7 +85,7 @@ public class StatusBar : View
     }
 
     ///<inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent me)
+    protected internal override bool OnMouseEvent (MouseEvent me)
     {
         if (me.Flags != MouseFlags.Button1Clicked)
         {
@@ -215,33 +158,6 @@ public class StatusBar : View
         }
     }
 
-    /// <inheritdoc/>
-    public override bool? OnInvokingKeyBindings (Key keyEvent)
-    {
-        // TODO: Use CommandContext
-        // This is a bit of a hack. We want to handle the key bindings for status bar but
-        // InvokeKeyBindings doesn't pass any context so we can't tell which item it is for.
-        // So before we call the base class we set SelectedItem appropriately.
-        Key key = new (keyEvent);
-
-        if (KeyBindings.TryGet (key, out _))
-        {
-            // Search RadioLabels 
-            foreach (StatusItem item in Items)
-            {
-                if (item.Shortcut == key)
-                {
-                    _itemToInvoke = item;
-                    //keyEvent.Scope = KeyBindingScope.HotKey;
-
-                    break;
-                }
-            }
-        }
-
-        return base.OnInvokingKeyBindings (keyEvent);
-    }
-
     /// <summary>Removes a <see cref="StatusItem"/> at specified index of <see cref="Items"/>.</summary>
     /// <param name="index">The zero-based index of the item to remove.</param>
     /// <returns>The <see cref="StatusItem"/> removed.</returns>
@@ -288,11 +204,11 @@ public class StatusBar : View
         return len;
     }
 
-    private bool? InvokeItem ()
+    private bool? InvokeItem (StatusItem itemToInvoke)
     {
-        if (_itemToInvoke is { Action: { } })
+        if (itemToInvoke is { Action: { } })
         {
-            _itemToInvoke.Action.Invoke ();
+            itemToInvoke.Action.Invoke ();
 
             return true;
         }

+ 59 - 0
Terminal.Gui/Views/StatusItem.cs

@@ -0,0 +1,59 @@
+namespace Terminal.Gui;
+
+/// <summary>
+///     <see cref="StatusItem"/> objects are contained by <see cref="StatusBar"/> <see cref="View"/>s. Each
+///     <see cref="StatusItem"/> has a title, a shortcut (hotkey), and an <see cref="Command"/> that will be invoked when
+///     the <see cref="StatusItem.Shortcut"/> is pressed. The <see cref="StatusItem.Shortcut"/> will be a global hotkey for
+///     the application in the current context of the screen. The color of the <see cref="StatusItem.Title"/> will be
+///     changed after each ~. A <see cref="StatusItem.Title"/> set to `~F1~ Help` will render as *F1* using
+///     <see cref="ColorScheme.HotNormal"/> and *Help* as <see cref="ColorScheme.HotNormal"/>.
+/// </summary>
+public class StatusItem
+{
+    /// <summary>Initializes a new <see cref="StatusItem"/>.</summary>
+    /// <param name="shortcut">Shortcut to activate the <see cref="StatusItem"/>.</param>
+    /// <param name="title">Title for the <see cref="StatusItem"/>.</param>
+    /// <param name="action">Action to invoke when the <see cref="StatusItem"/> is activated.</param>
+    /// <param name="canExecute">Function to determine if the action can currently be executed.</param>
+    public StatusItem (Key shortcut, string title, Action action, Func<bool> canExecute = null)
+    {
+        Title = title ?? "";
+        Shortcut = shortcut;
+        Action = action;
+        CanExecute = canExecute;
+    }
+
+    /// <summary>Gets or sets the action to be invoked when the <see cref="StatusItem"/> is triggered</summary>
+    /// <value>Action to invoke.</value>
+    public Action Action { get; set; }
+
+    /// <summary>
+    ///     Gets or sets the action to be invoked to determine if the <see cref="StatusItem"/> can be triggered. If
+    ///     <see cref="CanExecute"/> returns <see langword="true"/> the status item will be enabled. Otherwise, it will be
+    ///     disabled.
+    /// </summary>
+    /// <value>Function to determine if the action is can be executed or not.</value>
+    public Func<bool> CanExecute { get; set; }
+
+    /// <summary>Gets or sets arbitrary data for the status item.</summary>
+    /// <remarks>This property is not used internally.</remarks>
+    public object Data { get; set; }
+
+    /// <summary>Gets the global shortcut to invoke the action on the menu.</summary>
+    public Key Shortcut { get; set; }
+
+    /// <summary>Gets or sets the title.</summary>
+    /// <value>The title.</value>
+    /// <remarks>
+    ///     The colour of the <see cref="StatusItem.Title"/> will be changed after each ~. A
+    ///     <see cref="StatusItem.Title"/> set to `~F1~ Help` will render as *F1* using <see cref="ColorScheme.HotNormal"/> and
+    ///     *Help* as <see cref="ColorScheme.HotNormal"/>.
+    /// </remarks>
+    public string Title { get; set; }
+
+    /// <summary>
+    ///     Returns <see langword="true"/> if the status item is enabled. This method is a wrapper around
+    ///     <see cref="CanExecute"/>.
+    /// </summary>
+    public bool IsEnabled () { return CanExecute?.Invoke () ?? true; }
+}