2
0
Tig 9 сар өмнө
parent
commit
39bf84472d

+ 9 - 0
Terminal.Gui/View/View.Command.cs

@@ -301,6 +301,15 @@ public partial class View // Command APIs
         return null;
     }
 
+    /// <summary>
+    /// Invokes the specified command.
+    /// </summary>
+    /// <param name="command">The command to invoke.</param>
+    /// <param name="ctx">Context to pass with the invocation.</param>
+    /// <returns>
+    ///     <see langword="null"/> if no command was found. <see langword="true"/> if the command was invoked, and it
+    ///     handled (or cancelled) the command. <see langword="false"/> if the command was invoked, and it did not handle (or cancel) the command.
+    /// </returns>
     public bool? InvokeCommand (Command command, CommandContext ctx)
     {
         if (CommandImplementations.TryGetValue (command, out Func<CommandContext, bool?>? implementation))

+ 1 - 1
Terminal.Gui/View/View.Mouse.cs

@@ -66,7 +66,7 @@ public partial class View // Mouse APIs
 
             _savedNonHoverColorScheme = cs;
 
-            ColorScheme = ColorScheme.GetHighlightColorScheme ();
+            ColorScheme = ColorScheme?.GetHighlightColorScheme ();
         }
 
         return false;

+ 1 - 1
Terminal.Gui/Views/Button.cs

@@ -142,7 +142,7 @@ public class Button : View, IDesignable
         {
             return;
         }
-        e.Handled = InvokeCommand (Command.HotKey) == true;
+        e.Handled = InvokeCommand (Command.HotKey, ctx: new (Command.HotKey, key: null, data: this)) == true;
     }
 
     private void Button_TitleChanged (object sender, EventArgs<string> e)

+ 1 - 1
Terminal.Gui/Views/FrameView.cs

@@ -25,7 +25,7 @@ public class FrameView : View
     private void FrameView_MouseClick (object sender, MouseEventEventArgs e)
     {
         // base sets focus on HotKey
-        e.Handled = InvokeCommand (Command.HotKey) == true;
+        e.Handled = InvokeCommand (Command.HotKey, ctx: new (Command.HotKey, key: null, data: this)) == true;
     }
 
 

+ 1 - 1
Terminal.Gui/Views/Label.cs

@@ -36,7 +36,7 @@ public class Label : View, IDesignable
     {
         if (!CanFocus)
         {
-            e.Handled = InvokeCommand (Command.HotKey) == true;
+            e.Handled = InvokeCommand (Command.HotKey, ctx: new (Command.HotKey, key: null, data: this)) == true;
         }
     }
 

+ 3 - 3
Terminal.Gui/Views/Menu/Menu.cs

@@ -517,7 +517,7 @@ internal sealed class Menu : View
 
                 if (!item.IsEnabled ())
                 {
-                    DrawHotString (textToDraw, ColorScheme.Disabled, ColorScheme.Disabled);
+                    DrawHotString (textToDraw, ColorScheme!.Disabled, ColorScheme.Disabled);
                 }
                 else if (i == 0 && _host.UseSubMenusSingleFrame && item.Parent!.Parent is { })
                 {
@@ -532,7 +532,7 @@ internal sealed class Menu : View
                     tf.Draw (
                              ViewportToScreen (new Rectangle (1, i, Frame.Width - 3, 1)),
                              i == _currentChild ? GetFocusColor () : GetNormalColor (),
-                             i == _currentChild ? ColorScheme.HotFocus : ColorScheme.HotNormal,
+                             i == _currentChild ? ColorScheme!.HotFocus : ColorScheme!.HotNormal,
                              SuperView?.ViewportToScreen (SuperView.Viewport) ?? Rectangle.Empty
                             );
                 }
@@ -540,7 +540,7 @@ internal sealed class Menu : View
                 {
                     DrawHotString (
                                    textToDraw,
-                                   i == _currentChild ? ColorScheme.HotFocus : ColorScheme.HotNormal,
+                                   i == _currentChild ? ColorScheme!.HotFocus : ColorScheme!.HotNormal,
                                    i == _currentChild ? GetFocusColor () : GetNormalColor ()
                                   );
                 }

+ 116 - 176
Terminal.Gui/Views/Shortcut.cs

@@ -1,5 +1,5 @@
-using System.ComponentModel;
-using System.Diagnostics;
+#nullable enable
+using System.ComponentModel;
 
 namespace Terminal.Gui;
 
@@ -44,7 +44,7 @@ public class Shortcut : View, IOrientation, IDesignable
     /// <summary>
     ///     Creates a new instance of <see cref="Shortcut"/>.
     /// </summary>
-    public Shortcut () : this (Key.Empty, string.Empty, null) { }
+    public Shortcut () : this (Key.Empty, null, null, null) { }
 
     /// <summary>
     ///     Creates a new instance of <see cref="Shortcut"/>, binding it to <paramref name="targetView"/> and
@@ -67,11 +67,12 @@ public class Shortcut : View, IOrientation, IDesignable
     /// </param>
     /// <param name="commandText">The text to display for the command.</param>
     /// <param name="helpText">The help text to display.</param>
-    public Shortcut (View targetView, Command command, string commandText, string helpText = null) : this (
-                                                                                                           targetView?.KeyBindings.GetKeyFromCommands (command),
-                                                                                                           commandText,
-                                                                                                           null,
-                                                                                                           helpText)
+    public Shortcut (View targetView, Command command, string commandText, string helpText)
+        : this (
+                targetView?.KeyBindings.GetKeyFromCommands (command)!,
+                commandText,
+                null,
+                helpText)
     {
         _targetView = targetView;
         _command = command;
@@ -89,9 +90,10 @@ public class Shortcut : View, IOrientation, IDesignable
     /// <param name="commandText">The text to display for the command.</param>
     /// <param name="action"></param>
     /// <param name="helpText">The help text to display.</param>
-    public Shortcut (Key key, string commandText, Action action, string helpText = null)
+    public Shortcut (Key key, string? commandText, Action? action, string? helpText = null)
     {
         Id = "_shortcut";
+
         // Disabled for now due to bs in highlight handling and mouse clicks - HighlightStyle = HighlightStyle.Pressed;
         CanFocus = true;
         Width = GetWidthDimAuto ();
@@ -101,86 +103,81 @@ public class Shortcut : View, IOrientation, IDesignable
         _orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);
         _orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);
 
-        // Accept (Enter key) - 
-        AddCommand (Command.Accept, ctx => DispatchAcceptCommand (ctx));
-
-        // Hotkey - 
-        AddCommand (Command.HotKey, ctx =>
-                                    {
-                                        // The default HotKey handler sets Focus
-                                        SetFocus ();
-
-                                        if (DispatchAcceptCommand (ctx) == true)
-
-                                        {
-                                            return true;
-                                        }
-
-                                        return RaiseSelected (ctx);
-                                    });
-
-        // Select (Space key or click) - 
-        AddCommand (Command.Select, ctx =>
-                                      {
-                                          if (ctx.Data != this)
-                                          {
-                                              ctx.Data = this;
-                                              CommandView.InvokeCommand (Command.Select, ctx);
-                                          }
-
-                                          if (RaiseSelected (ctx) is true)
-                                          {
-                                              return true;
-                                          }
-
-                                          // The default HotKey handler sets Focus
-                                          SetFocus ();
-
-                                          return DispatchAcceptCommand (ctx);
-                                      });
+        // Accept (Enter key) -
+        AddCommand (Command.Accept, DispatchAcceptCommand);
+
+        // Hotkey -
+        AddCommand (
+                    Command.HotKey,
+                    ctx =>
+                    {
+                        if (ctx.Data != this)
+                        {
+                            ctx.Data = this;
+                            CommandView.InvokeCommand (Command.Select, ctx);
+                        }
+
+                        if (RaiseSelected (ctx) is true)
+                        {
+                            return true;
+                        }
+
+                        // The default HotKey handler sets Focus
+                        SetFocus ();
+
+                        return DispatchAcceptCommand (ctx);
+                    });
+
+        // Select (Space key or click) -
+        AddCommand (
+                    Command.Select,
+                    ctx =>
+                    {
+                        if (ctx.Data != this)
+                        {
+                            ctx.Data = this;
+                            CommandView.InvokeCommand (Command.Select, ctx);
+                        }
+
+                        if (RaiseSelected (ctx) is true)
+                        {
+                            return true;
+                        }
+
+                        // The default HotKey handler sets Focus
+                        SetFocus ();
+
+                        return DispatchAcceptCommand (ctx);
+                    });
 
         TitleChanged += Shortcut_TitleChanged; // This needs to be set before CommandView is set
 
         CommandView = new ()
         {
             Width = Dim.Auto (),
-            Height = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: 1)
+            Height = Dim.Auto (DimAutoStyle.Auto, 1)
         };
 
         HelpView.Id = "_helpView";
         HelpView.CanFocus = false;
-        HelpView.Text = helpText;
+        HelpView.Text = helpText ?? string.Empty;
         Add (HelpView);
 
         KeyView.Id = "_keyView";
         KeyView.CanFocus = false;
         Add (KeyView);
 
-        //// If the user clicks anywhere on the Shortcut...
-        MouseClick += Shortcut_MouseClick;
-
-        //// If the user clicks on HelpView or KeyView
-        //HelpView.MouseClick += HelpOrKeyView_MouseClick;
-        //KeyView.MouseClick += HelpOrKeyView_MouseClick;
-
-        HelpView.Selected += HelpAndKeyViewOnSelected;
-        KeyView.Selected += HelpAndKeyViewOnSelected;
-
         LayoutStarted += OnLayoutStarted;
         Initialized += OnInitialized;
 
-        if (key is null)
-        {
-            key = Key.Empty;
-        }
-
+        key ??= Key.Empty;
         Key = key;
-        Title = commandText;
+        Title = commandText ?? string.Empty;
         Action = action;
 
         return;
 
-        void OnInitialized (object sender, EventArgs e)
+        void OnInitialized (object? sender, EventArgs e)
         {
             SuperViewRendersLineCanvas = true;
             Border.Settings &= ~BorderSettings.Title;
@@ -207,22 +204,11 @@ public class Shortcut : View, IOrientation, IDesignable
             return Dim.Auto (
                              DimAutoStyle.Content,
                              Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)),
-                             Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)));
+                             Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)))!;
         }
     }
 
-    private void Shortcut_MouseClick (object sender, MouseEventEventArgs e)
-    {
-        //e.Handled = true;
-    }
-
-    private void HelpAndKeyViewOnSelected (object sender, CommandEventArgs e)
-    {
-        //e.Handled = InvokeCommand (Command.Select) == true;
-    }
-
-    [CanBeNull]
-    private readonly View _targetView; // If set, _command will be invoked
+    private readonly View? _targetView; // If set, _command will be invoked
 
     private readonly Command _command; // Used when _targetView is set
 
@@ -333,7 +319,7 @@ public class Shortcut : View, IOrientation, IDesignable
     }
 
     // When layout starts, we need to adjust the layout of the HelpView and KeyView
-    private void OnLayoutStarted (object sender, LayoutEventArgs e)
+    private void OnLayoutStarted (object? sender, LayoutEventArgs e)
     {
         if (Width is DimAuto widthAuto)
         {
@@ -401,39 +387,11 @@ public class Shortcut : View, IOrientation, IDesignable
             else
             {
                 // Reset to default
-                //SetCommandViewDefaultLayout();
                 SetHelpViewDefaultLayout ();
-
-                //SetKeyViewDefaultLayout ();
             }
         }
     }
 
-    //private void Shortcut_MouseClick (object sender, MouseEventEventArgs e)
-    //{
-    //    // When the Shortcut is clicked, we want to invoke the Command and Set focus
-    //    var view = sender as View;
-
-    //    if (!e.Handled)
-    //    {
-    //        // If the subview (likely CommandView) didn't handle the mouse click, invoke the Select command.
-    //        // e.Handled = CommandView.InvokeCommand (Command.Select) == true;
-    //        e.Handled = InvokeCommand (Command.HotKey) == true;
-    //    }
-
-    //    //if (CanFocus)
-    //    //{
-    //    //    SetFocus ();
-    //    //}
-    //}
-
-    //private void HelpOrKeyView_MouseClick (object sender, MouseEventEventArgs e)
-    //{
-    //    // Always eat
-    //    e.Handled = true;
-    //    InvokeCommand (Command.HotKey);
-    //}
-
     #region IOrientation members
 
     /// <summary>
@@ -456,10 +414,10 @@ public class Shortcut : View, IOrientation, IDesignable
     }
 
     /// <inheritdoc/>
-    public event EventHandler<CancelEventArgs<Orientation>> OrientationChanging;
+    public event EventHandler<CancelEventArgs<Orientation>>? OrientationChanging;
 
     /// <inheritdoc/>
-    public event EventHandler<EventArgs<Orientation>> OrientationChanged;
+    public event EventHandler<EventArgs<Orientation>>? OrientationChanged;
 
     /// <summary>Called when <see cref="Orientation"/> has changed.</summary>
     /// <param name="newOrientation"></param>
@@ -478,6 +436,7 @@ public class Shortcut : View, IOrientation, IDesignable
     /// <summary>
     ///     Gets or sets the View that displays the command text and hotkey.
     /// </summary>
+    /// <exception cref="ArgumentNullException"></exception>
     /// <remarks>
     ///     <para>
     ///         By default, the <see cref="View.Title"/> of the <see cref="CommandView"/> is displayed as the Shortcut's
@@ -522,19 +481,20 @@ public class Shortcut : View, IOrientation, IDesignable
         get => _commandView;
         set
         {
+            ArgumentNullException.ThrowIfNull (value);
+
             if (value == null)
             {
                 throw new ArgumentNullException ();
             }
 
-            if (_commandView is { })
-            {
-                _commandView.Selected -= CommandViewOnSelected;
-                _commandView.Accepted -= CommandViewOnAccepted;
-                Remove (_commandView);
-                _commandView?.Dispose ();
-            }
+            // Clean up old 
+            _commandView.Selected -= CommandViewOnSelected;
+            _commandView.Accepted -= CommandViewOnAccepted;
+            Remove (_commandView);
+            _commandView?.Dispose ();
 
+            // Set new
             _commandView = value;
             _commandView.Id = "_commandView";
 
@@ -543,45 +503,46 @@ public class Shortcut : View, IOrientation, IDesignable
             _commandView.CanFocus = false;
 
             _commandView.HotKeyChanged += (s, e) =>
-            {
-                if (e.NewKey != Key.Empty)
-                {
-                    // Add it 
-                    AddKeyBindingsForHotKey (e.OldKey, e.NewKey);
-                }
-            };
+                                          {
+                                              if (e.NewKey != Key.Empty)
+                                              {
+                                                  // Add it
+                                                  AddKeyBindingsForHotKey (e.OldKey, e.NewKey);
+                                              }
+                                          };
 
             _commandView.HotKeySpecifier = new ('_');
 
             Title = _commandView.Text;
 
             _commandView.Selected += CommandViewOnSelected;
-            void CommandViewOnSelected (object sender, CommandEventArgs e)
-            {
-                if (e.Context.Data != this)
-                {
-                    // Forward command to ourselves
-                    InvokeCommand (Command.Select, new CommandContext (Command.Select, null, null, this));
-                    e.Cancel = true;
-                }
-                else
-                {
-                    e.Cancel = true;
-                }
-            }
 
             _commandView.Accepted += CommandViewOnAccepted;
-            void CommandViewOnAccepted (object sender, HandledEventArgs e)
-            {
-                // Always eat CommandView.Accept
-                e.Handled = true;
-            }
 
             SetCommandViewDefaultLayout ();
             SetHelpViewDefaultLayout ();
             SetKeyViewDefaultLayout ();
             ShowHide ();
             UpdateKeyBindings (Key.Empty);
+
+            return;
+
+            void CommandViewOnAccepted (object? sender, HandledEventArgs e)
+            {
+                // Always eat CommandView.Accept
+                e.Handled = true;
+            }
+
+            void CommandViewOnSelected (object? sender, CommandEventArgs e)
+            {
+                if (e.Context.Data != this)
+                {
+                    // Forward command to ourselves
+                    InvokeCommand (Command.Select, new (Command.Select, null, null, this));
+                }
+
+                e.Cancel = true;
+            }
         }
     }
 
@@ -593,7 +554,7 @@ public class Shortcut : View, IOrientation, IDesignable
         HelpView.HighlightStyle = HighlightStyle.None;
     }
 
-    private void Shortcut_TitleChanged (object sender, EventArgs<string> e)
+    private void Shortcut_TitleChanged (object? sender, EventArgs<string> e)
     {
         // If the Title changes, update the CommandView text.
         // This is a helper to make it easier to set the CommandView text.
@@ -629,14 +590,11 @@ public class Shortcut : View, IOrientation, IDesignable
     /// </summary>
     public override string Text
     {
-        get => HelpView?.Text;
+        get => HelpView.Text;
         set
         {
-            if (HelpView is { })
-            {
-                HelpView.Text = value;
-                ShowHide ();
-            }
+            HelpView.Text = value;
+            ShowHide ();
         }
     }
 
@@ -645,14 +603,11 @@ public class Shortcut : View, IOrientation, IDesignable
     /// </summary>
     public string HelpText
     {
-        get => HelpView?.Text;
+        get => HelpView.Text;
         set
         {
-            if (HelpView is { })
-            {
-                HelpView.Text = value;
-                ShowHide ();
-            }
+            HelpView.Text = value;
+            ShowHide ();
         }
     }
 
@@ -670,10 +625,7 @@ public class Shortcut : View, IOrientation, IDesignable
         get => _key;
         set
         {
-            if (value == null)
-            {
-                throw new ArgumentNullException ();
-            }
+            ArgumentNullException.ThrowIfNull (value);
 
             Key oldKey = _key;
             _key = value;
@@ -752,7 +704,7 @@ public class Shortcut : View, IOrientation, IDesignable
     {
         KeyView.Margin.Thickness = GetMarginThickness ();
         KeyView.X = Pos.Align (Alignment.End, AlignmentModes);
-        KeyView.Y = 0; //Pos.Center ();
+        KeyView.Y = 0;
         KeyView.Width = Dim.Auto (DimAutoStyle.Text, Dim.Func (GetMinimumKeyViewSize));
         KeyView.Height = CommandView?.Visible == true ? Dim.Height (CommandView) : 1;
 
@@ -767,19 +719,8 @@ public class Shortcut : View, IOrientation, IDesignable
 
     private void UpdateKeyBindings (Key oldKey)
     {
-        if (Key != null && Key.IsValid)
+        if (Key.IsValid)
         {
-            //// Disable the command view HotKey bindings
-            //IEnumerable<Key> list = CommandView.KeyBindings.GetKeysFromCommands (Command.HotKey);
-            //foreach (Key cmdViewKey in list)
-            //{
-            //    CommandView.KeyBindings.Remove (cmdViewKey);
-            //    CommandView.KeyBindings.Remove (cmdViewKey.WithShift);
-            //    CommandView.KeyBindings.Remove (cmdViewKey.WithAlt);
-            //    CommandView.KeyBindings.Remove (cmdViewKey.WithShift.WithAlt);
-            //    KeyBindings.Add (cmdViewKey, Command.HotKey);
-            //}
-
             if (KeyBindingScope.FastHasFlags (KeyBindingScope.Application))
             {
                 if (oldKey != Key.Empty)
@@ -851,15 +792,14 @@ public class Shortcut : View, IOrientation, IDesignable
     /// <remarks>
     ///     Note, the <see cref="View.Accepted"/> event is fired first, and if cancelled, the event will not be invoked.
     /// </remarks>
-    [CanBeNull]
-    public Action Action { get; set; }
+    public Action? Action { get; set; }
 
     #endregion Accept Handling
 
     #region Focus
 
     /// <inheritdoc/>
-    public override ColorScheme ColorScheme
+    public override ColorScheme? ColorScheme
     {
         get => base.ColorScheme;
         set
@@ -910,7 +850,7 @@ public class Shortcut : View, IOrientation, IDesignable
     }
 
     /// <inheritdoc/>
-    protected override void OnHasFocusChanged (bool newHasFocus, View previousFocusedView, View view) { SetColors (); }
+    protected override void OnHasFocusChanged (bool newHasFocus, View? previousFocusedView, View? view) { SetColors (); }
 
     #endregion Focus
-}
+}

+ 9 - 4
UICatalog/Scenarios/Shortcuts.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Diagnostics;
@@ -110,19 +111,23 @@ public class Shortcuts : Scenario
                 eventLog.MoveDown ();
 
                 var max = 0;
-                var toAlign = Application.Top.Subviews.Where (v => v is Shortcut { Orientation: Orientation.Vertical, Width: not DimAbsolute });
+                IEnumerable<View> toAlign = Application.Top.Subviews.Where (v => v is Shortcut { Orientation: Orientation.Vertical, Width: not DimAbsolute });
+                IEnumerable<View> enumerable = toAlign as View [] ?? toAlign.ToArray ();
 
                 if (e.NewValue == CheckState.Checked)
                 {
-                    foreach (Shortcut peer in toAlign)
+                    foreach (var view in enumerable)
                     {
+                        var peer = (Shortcut)view;
+
                         // DANGER: KeyView is internal so we can't access it. So we assume this is how it works.
                         max = Math.Max (max, peer.Key.ToString ().GetColumns ());
                     }
                 }
 
-                foreach (Shortcut peer in toAlign)
+                foreach (var view in enumerable)
                 {
+                    var peer = (Shortcut)view;
                     peer.MinimumKeyTextSize = max;
                 }
             }
@@ -145,7 +150,7 @@ public class Shortcuts : Scenario
             Key = Key.K,
             KeyBindingScope = KeyBindingScope.HotKey,
         };
-        Button button = (Button)vShortcut4.CommandView;
+        var button = (Button)vShortcut4.CommandView;
         vShortcut4.Accepted += Button_Clicked;
 
         Application.Top.Add (vShortcut4);

+ 2 - 2
UnitTests/Application/ApplicationTests.cs

@@ -156,7 +156,7 @@ public class ApplicationTests
     }
 
     [Fact]
-    [AutoInitShutdown (VerifyShutdown: true)]
+    [AutoInitShutdown (verifyShutdown: true)]
     public void Begin_Sets_Application_Top_To_Console_Size ()
     {
         Assert.Null (Application.Top);
@@ -521,7 +521,7 @@ public class ApplicationTests
     }
 
     [Fact]
-    [AutoInitShutdown (VerifyShutdown: true)]
+    [AutoInitShutdown (verifyShutdown: true)]
     public void Internal_Properties_Correct ()
     {
         Assert.True (Application.IsInitialized);

+ 3 - 3
UnitTests/TestHelpers.cs

@@ -42,7 +42,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
     ///     <see cref="ConsoleDriver"/> == <see cref="FakeDriver"/> and <paramref name="autoInit"/> is true.
     /// </param>
     /// <param name="configLocation">Determines what config file locations <see cref="ConfigurationManager"/> will load from.</param>
-    /// <param name="VerifyShutdown">If true and <see cref="Application.IsInitialized"/> is true, the test will fail.</param>
+    /// <param name="verifyShutdown">If true and <see cref="Application.IsInitialized"/> is true, the test will fail.</param>
     public AutoInitShutdownAttribute (
         bool autoInit = true,
         Type consoleDriverType = null,
@@ -50,7 +50,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
         bool fakeClipboardAlwaysThrowsNotSupportedException = false,
         bool fakeClipboardIsSupportedAlwaysTrue = false,
         ConfigLocations configLocation = ConfigLocations.None,
-        bool VerifyShutdown = false
+        bool verifyShutdown = false
     )
     {
         AutoInit = autoInit;
@@ -62,7 +62,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
             fakeClipboardAlwaysThrowsNotSupportedException;
         FakeDriver.FakeBehaviors.FakeClipboardIsSupportedAlwaysFalse = fakeClipboardIsSupportedAlwaysTrue;
         Locations = configLocation;
-        _verifyShutdown = VerifyShutdown;
+        _verifyShutdown = verifyShutdown;
     }
 
     private bool _verifyShutdown;

+ 178 - 74
UnitTests/Views/ShortcutTests.cs

@@ -1,4 +1,4 @@
-using JetBrains.Annotations;
+using JetBrains.Annotations;
 
 namespace Terminal.Gui.ViewsTests;
 
@@ -14,7 +14,6 @@ public class ShortcutTests
         Assert.True (shortcut.CanFocus);
         Assert.IsType<DimAuto> (shortcut.Width);
         Assert.IsType<DimAuto> (shortcut.Height);
-
     }
 
     [Fact]
@@ -39,7 +38,7 @@ public class ShortcutTests
 
         //  0123456789
         // "   0  A "
-        shortcut = new Shortcut ()
+        shortcut = new ()
         {
             Key = Key.A,
             HelpText = "0"
@@ -61,7 +60,7 @@ public class ShortcutTests
 
         //  0123456789
         // " C  0  A "
-        shortcut = new Shortcut ()
+        shortcut = new ()
         {
             Title = "C",
             Key = Key.A,
@@ -81,8 +80,8 @@ public class ShortcutTests
 
         Assert.Equal (1, shortcut.KeyView.Viewport.Width);
         Assert.Equal (1, shortcut.KeyView.Viewport.Height);
-
     }
+
     [Theory]
     [InlineData ("", "", KeyCode.Null, 2)]
     [InlineData ("C", "", KeyCode.Null, 3)]
@@ -217,7 +216,6 @@ public class ShortcutTests
         Assert.Equal (Key.Empty, shortcut.Key);
     }
 
-
     [Fact]
     public void Key_Set_Binds_Key_To_CommandView_Accept ()
     {
@@ -231,7 +229,7 @@ public class ShortcutTests
     [Fact]
     public void Key_Changing_Removes_Previous_Binding ()
     {
-        Shortcut shortcut = new Shortcut ();
+        var shortcut = new Shortcut ();
 
         shortcut.Key = Key.A;
         Assert.Contains (Key.A, shortcut.KeyBindings.Bindings.Keys);
@@ -263,7 +261,7 @@ public class ShortcutTests
     [Fact]
     public void KeyBindingScope_Changing_Adjusts_KeyBindings ()
     {
-        Shortcut shortcut = new Shortcut ();
+        var shortcut = new Shortcut ();
 
         shortcut.Key = Key.A;
         Assert.Contains (Key.A, shortcut.KeyBindings.Bindings.Keys);
@@ -411,7 +409,7 @@ public class ShortcutTests
     [InlineData (9, 0)]
     public void MouseClick_Raises_Accepted (int x, int expectedAccepted)
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var shortcut = new Shortcut
         {
@@ -436,10 +434,9 @@ public class ShortcutTests
         Assert.Equal (expectedAccepted, accepted);
 
         Application.Top.Dispose ();
-        Application.ResetState (ignoreDisposed: true);
+        Application.ResetState (true);
     }
 
-
     [Theory]
 
     //  0123456789
@@ -456,19 +453,15 @@ public class ShortcutTests
     [InlineData (8, 0, 1, 1, 1)]
     [InlineData (9, 0, 0, 0, 0)]
 
-    //[InlineData (1, 1, 1)]
-    //[InlineData (2, 1, 0)]
-    //[InlineData (3, 1, 0)]
-    //[InlineData (4, 1, 0)]
-    //[InlineData (5, 1, 0)]
-    //[InlineData (6, 1, 0)]
-    //[InlineData (7, 1, 0)]
-    //[InlineData (8, 1, 0)]
-    //[InlineData (9, 0, 0)]
-    public void MouseClick_Default_CommandView_Raises_Accepted_Select_Correctly (int mouseX, int expectedCommandViewAccept, int expectedCommandViewSelect, 
-                                                                               int expectedShortcutAccept, int expectedShortcutSelect)
+    public void MouseClick_Default_CommandView_Raises_Accepted_Selected_Correctly (
+        int mouseX,
+        int expectedCommandViewAccepted,
+        int expectedCommandViewSelected,
+        int expectedShortcutAccepted,
+        int expectedShortcutSelected
+    )
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var shortcut = new Shortcut
         {
@@ -478,31 +471,18 @@ public class ShortcutTests
         };
 
         var commandViewAcceptCount = 0;
-        shortcut.CommandView.Accepted += (s, e) =>
-        {
-            commandViewAcceptCount++;
-        };
+        shortcut.CommandView.Accepted += (s, e) => { commandViewAcceptCount++; };
         var commandViewSelectCount = 0;
-        shortcut.CommandView.Selected += (s, e) =>
-        {
-            commandViewSelectCount++;
-        };
+        shortcut.CommandView.Selected += (s, e) => { commandViewSelectCount++; };
 
         var shortcutAcceptCount = 0;
-        shortcut.Accepted += (s, e) =>
-        {
-            shortcutAcceptCount++;
-        };
+        shortcut.Accepted += (s, e) => { shortcutAcceptCount++; };
         var shortcutSelectCount = 0;
-        shortcut.Selected += (s, e) =>
-        {
-            shortcutSelectCount++;
-        };
-
+        shortcut.Selected += (s, e) => { shortcutSelectCount++; };
 
         Application.Top.Add (shortcut);
         Application.Top.SetRelativeLayout (new (100, 100));
-        Application.Top.LayoutSubviews();
+        Application.Top.LayoutSubviews ();
 
         Application.OnMouseEvent (
                                   new ()
@@ -511,10 +491,10 @@ public class ShortcutTests
                                       Flags = MouseFlags.Button1Clicked
                                   });
 
-        Assert.Equal (expectedShortcutAccept, shortcutAcceptCount);
-        Assert.Equal (expectedShortcutSelect, shortcutSelectCount);
-        Assert.Equal (expectedCommandViewAccept, commandViewAcceptCount);
-        Assert.Equal (expectedCommandViewSelect, commandViewSelectCount);
+        Assert.Equal (expectedShortcutAccepted, shortcutAcceptCount);
+        Assert.Equal (expectedShortcutSelected, shortcutSelectCount);
+        Assert.Equal (expectedCommandViewAccepted, commandViewAcceptCount);
+        Assert.Equal (expectedCommandViewSelected, commandViewSelectCount);
 
         Application.Top.Dispose ();
         Application.ResetState (true);
@@ -535,10 +515,9 @@ public class ShortcutTests
     [InlineData (7, 1, 0)]
     [InlineData (8, 1, 0)]
     [InlineData (9, 0, 0)]
-    public void MouseClick_Button_CommandView_Raises_Shortcut_Accepted
-        (int mouseX, int expectedAccept, int expectedButtonAccept)
+    public void MouseClick_Button_CommandView_Raises_Shortcut_Accepted (int mouseX, int expectedAccept, int expectedButtonAccept)
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var shortcut = new Shortcut
         {
@@ -554,18 +533,87 @@ public class ShortcutTests
             CanFocus = false
         };
         var buttonAccepted = 0;
-        shortcut.CommandView.Accepted += (s, e) =>
+        shortcut.CommandView.Accepted += (s, e) => { buttonAccepted++; };
+        Application.Top.Add (shortcut);
+        Application.Top.SetRelativeLayout (new (100, 100));
+        Application.Top.LayoutSubviews ();
+
+        var accepted = 0;
+        shortcut.Accepted += (s, e) => { accepted++; };
+
+        Application.OnMouseEvent (
+                                  new ()
+                                  {
+                                      ScreenPosition = new (mouseX, 0),
+                                      Flags = MouseFlags.Button1Clicked
+                                  });
+
+        Assert.Equal (expectedAccept, accepted);
+        Assert.Equal (expectedButtonAccept, buttonAccepted);
+
+        Application.Top.Dispose ();
+        Application.ResetState (true);
+    }
+
+    [Theory]
+
+    //  01234567890
+    // " ☑C  0  A "
+    [InlineData (-1, 0, 0)]
+    [InlineData (0, 1, 0)]
+    [InlineData (1, 1, 0)]
+    [InlineData (2, 1, 0)]
+    [InlineData (3, 1, 0)]
+    [InlineData (4, 1, 0)]
+    [InlineData (5, 1, 0)]
+    [InlineData (6, 1, 0)]
+    [InlineData (7, 1, 0)]
+    [InlineData (8, 1, 0)]
+    [InlineData (9, 1, 0)]
+    [InlineData (10, 1, 0)]
+    public void MouseClick_CheckBox_CommandView_Raises_Shortcut_Accepted_Selected_Correctly (int mouseX, int expectedAccepted, int expectedCheckboxAccepted)
+    {
+        Application.Top = new ();
+
+        var shortcut = new Shortcut
+        {
+            Key = Key.A,
+            Text = "0"
+        };
+
+        shortcut.CommandView = new CheckBox
         {
-            buttonAccepted++;
+            Title = "C",
+            CanFocus = false
         };
+        var checkboxAccepted = 0;
+        shortcut.CommandView.Accepted += (s, e) => { checkboxAccepted++; };
+
+        var checkboxSelected = 0;
+        shortcut.CommandView.Selected += (s, e) =>
+                                         {
+                                             if (e.Cancel)
+                                             {
+                                                 return;
+                                             }
+                                             checkboxSelected++;
+                                         };
+
         Application.Top.Add (shortcut);
         Application.Top.SetRelativeLayout (new (100, 100));
         Application.Top.LayoutSubviews ();
 
+        var selected = 0;
+        shortcut.Selected += (s, e) =>
+        {
+            selected++;
+        };
+
         var accepted = 0;
         shortcut.Accepted += (s, e) =>
                              {
                                  accepted++;
+                                 e.Handled = true;
                              };
 
         Application.OnMouseEvent (
@@ -575,30 +623,31 @@ public class ShortcutTests
                                       Flags = MouseFlags.Button1Clicked
                                   });
 
-        Assert.Equal (expectedAccept, accepted);
-        Assert.Equal (expectedButtonAccept, buttonAccepted);
+        Assert.Equal (expectedAccepted, accepted);
+        Assert.Equal (expectedAccepted, selected);
+        Assert.Equal (expectedCheckboxAccepted, checkboxAccepted);
+        Assert.Equal (expectedCheckboxAccepted, checkboxSelected);
 
         Application.Top.Dispose ();
         Application.ResetState (true);
     }
 
     [Theory]
-    [InlineData (true, KeyCode.A, 1)]
-    [InlineData (true, KeyCode.C, 1)]
-    [InlineData (true, KeyCode.C | KeyCode.AltMask, 1)]
-    [InlineData (true, KeyCode.Enter, 1)]
-    [InlineData (true, KeyCode.Space, 1)]
-    [InlineData (true, KeyCode.F1, 0)]
-    [InlineData (false, KeyCode.A, 1)]
-    [InlineData (false, KeyCode.C, 1)]
-    [InlineData (false, KeyCode.C | KeyCode.AltMask, 1)]
-    [InlineData (false, KeyCode.Enter, 0)]
-    [InlineData (false, KeyCode.Space, 0)]
-    [InlineData (false, KeyCode.F1, 0)]
-    [AutoInitShutdown]
-    public void KeyDown_Invokes_Accept (bool canFocus, KeyCode key, int expectedAccept)
+    [InlineData (true, KeyCode.A, 1, 1)]
+    [InlineData (true, KeyCode.C, 1, 1)]
+    [InlineData (true, KeyCode.C | KeyCode.AltMask, 1, 1)]
+    [InlineData (true, KeyCode.Enter, 1, 0)]
+    [InlineData (true, KeyCode.Space, 1, 1)]
+    [InlineData (true, KeyCode.F1, 0, 0)]
+    [InlineData (false, KeyCode.A, 1, 1)]
+    [InlineData (false, KeyCode.C, 1, 1)]
+    [InlineData (false, KeyCode.C | KeyCode.AltMask, 1, 1)]
+    [InlineData (false, KeyCode.Enter, 0, 0)]
+    [InlineData (false, KeyCode.Space, 0, 0)]
+    [InlineData (false, KeyCode.F1, 0, 0)]
+    public void KeyDown_Raises_Accepted_Selected (bool canFocus, KeyCode key, int expectedAccept, int expectedSelect)
     {
-        var current = new Toplevel ();
+        Application.Top = new ();
 
         var shortcut = new Shortcut
         {
@@ -607,21 +656,77 @@ public class ShortcutTests
             Title = "_C",
             CanFocus = canFocus
         };
-        current.Add (shortcut);
+        Application.Top.Add (shortcut);
+        shortcut.SetFocus ();
 
-        Application.Begin (current);
         Assert.Equal (canFocus, shortcut.HasFocus);
 
         var accepted = 0;
         shortcut.Accepted += (s, e) => accepted++;
 
+        var selected = 0;
+        shortcut.Selected += (s, e) => selected++;
+
         Application.OnKeyDown (key);
 
         Assert.Equal (expectedAccept, accepted);
+        Assert.Equal (expectedSelect, selected);
 
-        current.Dispose ();
+        Application.Top.Dispose ();
+        Application.ResetState (true);
     }
 
+
+    [Theory]
+    [InlineData (true, KeyCode.A, 1, 1)]
+    [InlineData (true, KeyCode.C, 1, 1)]
+    [InlineData (true, KeyCode.C | KeyCode.AltMask, 1, 1)]
+    [InlineData (true, KeyCode.Enter, 1, 0)]
+    [InlineData (true, KeyCode.Space, 1, 1)]
+    [InlineData (true, KeyCode.F1, 0, 0)]
+    [InlineData (false, KeyCode.A, 1, 1)]
+    [InlineData (false, KeyCode.C, 1, 1)]
+    [InlineData (false, KeyCode.C | KeyCode.AltMask, 1, 1)]
+    [InlineData (false, KeyCode.Enter, 0, 0)]
+    [InlineData (false, KeyCode.Space, 0, 0)]
+    [InlineData (false, KeyCode.F1, 0, 0)]
+    public void KeyDown_CheckBox_Raises_Accepted_Selected (bool canFocus, KeyCode key, int expectedAccept, int expectedSelect)
+    {
+        Application.Top = new ();
+
+        var shortcut = new Shortcut
+        {
+            Key = Key.A,
+            Text = "0",
+            CommandView = new CheckBox ()
+            {
+                Title = "_C"
+            },
+            CanFocus = canFocus
+        };
+        Application.Top.Add (shortcut);
+        shortcut.SetFocus ();
+
+        Assert.Equal (canFocus, shortcut.HasFocus);
+
+        var accepted = 0;
+        shortcut.Accepted += (s, e) =>
+                             {
+                                 accepted++;
+                                 e.Handled = true;
+                             };
+
+        var selected = 0;
+        shortcut.Selected += (s, e) => selected++;
+
+        Application.OnKeyDown (key);
+
+        Assert.Equal (expectedAccept, accepted);
+        Assert.Equal (expectedSelect, selected);
+
+        Application.Top.Dispose ();
+        Application.ResetState (true);
+    }
     [Theory]
     [InlineData (KeyCode.A, 1)]
     [InlineData (KeyCode.C, 1)]
@@ -631,7 +736,7 @@ public class ShortcutTests
     [InlineData (KeyCode.F1, 0)]
     public void KeyDown_App_Scope_Invokes_Accept (KeyCode key, int expectedAccept)
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var shortcut = new Shortcut
         {
@@ -709,7 +814,7 @@ public class ShortcutTests
     [InlineData (false, KeyCode.F1, 0)]
     public void KeyDown_App_Scope_Invokes_Action (bool canFocus, KeyCode key, int expectedAction)
     {
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         var shortcut = new Shortcut
         {
@@ -753,7 +858,7 @@ public class ShortcutTests
     {
         Application.Top = new ();
         Application.Navigation = new ();
-        Shortcut shortcut = new Shortcut ();
+        var shortcut = new Shortcut ();
 
         Application.Top.ColorScheme = null;
 
@@ -766,5 +871,4 @@ public class ShortcutTests
         Application.Top.Dispose ();
         Application.ResetState ();
     }
-
 }