From 7d4f4e4735cc16c842c3b980201c9e9ffdb396b1 Mon Sep 17 00:00:00 2001 From: Tig Date: Fri, 6 Dec 2024 10:31:49 -0700 Subject: [PATCH] Tweaks --- Terminal.Gui/Input/Keyboard/KeyBindings.cs | 17 ++++++------ Terminal.Gui/View/View.Command.cs | 5 +++- Terminal.Gui/View/View.Mouse.cs | 5 ++++ Terminal.Gui/Views/CharMap/CharMap.cs | 8 +++++- Terminal.Gui/Views/CheckBox.cs | 2 ++ UnitTests/Input/Keyboard/KeyBindingTests.cs | 10 +++++++ .../KeyBindingsTests.cs} | 26 ++++++++++++++----- UnitTests/Input/{ => Keyboard}/KeyTests.cs | 0 UnitTests/Views/CheckBoxTests.cs | 17 +++++++++--- UnitTests/Views/TimeFieldTests.cs | 4 +-- 10 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 UnitTests/Input/Keyboard/KeyBindingTests.cs rename UnitTests/Input/{KeyBindingTests.cs => Keyboard/KeyBindingsTests.cs} (95%) rename UnitTests/Input/{ => Keyboard}/KeyTests.cs (100%) diff --git a/Terminal.Gui/Input/Keyboard/KeyBindings.cs b/Terminal.Gui/Input/Keyboard/KeyBindings.cs index e0cebe7cf..a3ad84235 100644 --- a/Terminal.Gui/Input/Keyboard/KeyBindings.cs +++ b/Terminal.Gui/Input/Keyboard/KeyBindings.cs @@ -346,16 +346,17 @@ public class KeyBindings /// /// /// The key bound to the command to be replaced. - /// The set of commands to replace the old ones with. - public void ReplaceCommands (Key key, params Command [] commands) + /// The set of commands to replace the old ones with. + public void ReplaceCommands (Key key, params Command [] newCommands) { if (TryGet (key, out KeyBinding binding)) { - binding.Commands = commands; + Remove (key); + Add (key, binding.Scope, newCommands); } else { - Add (key, commands); + Add (key, newCommands); } } @@ -418,10 +419,10 @@ public class KeyBindings { if (!key.IsValid) { - //if (BoundView is null) - //{ - // throw new InvalidOperationException ("KeyBindings must be bound to a View to use this method."); - //} + //if (BoundView is null) + //{ + // throw new InvalidOperationException ("KeyBindings must be bound to a View to use this method."); + //} binding = new (Array.Empty (), KeyBindingScope.Disabled, null); return false; diff --git a/Terminal.Gui/View/View.Command.cs b/Terminal.Gui/View/View.Command.cs index d0c493783..5a8498df0 100644 --- a/Terminal.Gui/View/View.Command.cs +++ b/Terminal.Gui/View/View.Command.cs @@ -102,7 +102,10 @@ public partial class View // Command APIs } } - return SuperView?.InvokeCommand (Command.Accept, new ([Command.Accept], 0, null, this)) == true; + if (SuperView is { }) + { + return SuperView?.InvokeCommand (Command.Accept, new ([Command.Accept], 0, null, this)) is true; + } } return Accepting is null ? null : args.Cancel; diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index cb9b1522e..1f52b41f6 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -13,7 +13,12 @@ public partial class View // Mouse APIs { MouseBindings = new (); + // TODO: Should the default really work with any button or just button1? MouseBindings.Add (MouseFlags.Button1Clicked, Command.Select); + MouseBindings.Add (MouseFlags.Button2Clicked, Command.Select); + MouseBindings.Add (MouseFlags.Button3Clicked, Command.Select); + MouseBindings.Add (MouseFlags.Button4Clicked, Command.Select); + MouseBindings.Add (MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl, Command.Select); } diff --git a/Terminal.Gui/Views/CharMap/CharMap.cs b/Terminal.Gui/Views/CharMap/CharMap.cs index 2da64ec22..9f706bd51 100644 --- a/Terminal.Gui/Views/CharMap/CharMap.cs +++ b/Terminal.Gui/Views/CharMap/CharMap.cs @@ -59,7 +59,8 @@ public class CharMap : View, IDesignable KeyBindings.Add (ContextMenu.DefaultKey, Command.Context); MouseBindings.Add (MouseFlags.Button1DoubleClicked, Command.Accept); - MouseBindings.Add (MouseFlags.Button3Clicked, Command.Context); + MouseBindings.ReplaceCommands(MouseFlags.Button3Clicked, Command.Context); + MouseBindings.ReplaceCommands (MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl, Command.Context); MouseBindings.Add (MouseFlags.WheeledDown, Command.ScrollDown); MouseBindings.Add (MouseFlags.WheeledUp, Command.ScrollUp); MouseBindings.Add (MouseFlags.WheeledLeft, Command.ScrollLeft); @@ -561,6 +562,11 @@ public class CharMap : View, IDesignable [RequiresDynamicCode ("AOT")] private void ShowDetails () { + if (!Application.Initialized) + { + // Some unit tests invoke Accept without Init + return; + } UcdApiClient? client = new (); var decResponse = string.Empty; var getCodePointError = string.Empty; diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs index fcdc9beb8..6b7c7ad19 100644 --- a/Terminal.Gui/Views/CheckBox.cs +++ b/Terminal.Gui/Views/CheckBox.cs @@ -36,6 +36,8 @@ public class CheckBox : View // Accept (Enter key) - Raise Accept event - DO NOT advance state AddCommand (Command.Accept, RaiseAccepting); + MouseBindings.Add (MouseFlags.Button1DoubleClicked, Command.Accept); + TitleChanged += Checkbox_TitleChanged; HighlightStyle = DefaultHighlightStyle; diff --git a/UnitTests/Input/Keyboard/KeyBindingTests.cs b/UnitTests/Input/Keyboard/KeyBindingTests.cs new file mode 100644 index 000000000..9d011e407 --- /dev/null +++ b/UnitTests/Input/Keyboard/KeyBindingTests.cs @@ -0,0 +1,10 @@ +using Terminal.Gui.EnumExtensions; +using Xunit.Abstractions; + +namespace Terminal.Gui.InputTests; + +public class KeyBindingTests () +{ + // TODO: Add tests for KeyBinding + +} diff --git a/UnitTests/Input/KeyBindingTests.cs b/UnitTests/Input/Keyboard/KeyBindingsTests.cs similarity index 95% rename from UnitTests/Input/KeyBindingTests.cs rename to UnitTests/Input/Keyboard/KeyBindingsTests.cs index edade4239..f9a7d68ec 100644 --- a/UnitTests/Input/KeyBindingTests.cs +++ b/UnitTests/Input/Keyboard/KeyBindingsTests.cs @@ -1,13 +1,11 @@ using Terminal.Gui.EnumExtensions; using Xunit.Abstractions; +using static Unix.Terminal.Delegates; namespace Terminal.Gui.InputTests; -public class KeyBindingTests +public class KeyBindingsTests () { - public KeyBindingTests (ITestOutputHelper output) { _output = output; } - private readonly ITestOutputHelper _output; - [Fact] public void Add_Invalid_Key_Throws () { @@ -72,7 +70,7 @@ public class KeyBindingTests } // Add should not allow duplicates - [Fact] + [Fact] public void Add_With_Throws_If_Exists () { var keyBindings = new KeyBindings (new View ()); @@ -282,7 +280,7 @@ public class KeyBindingTests [InlineData (KeyBindingScope.Application)] public void Scope_Add_Adds (KeyBindingScope scope) { - var keyBindings = new KeyBindings (scope.FastHasFlags(KeyBindingScope.Application) ? null : new ()); + var keyBindings = new KeyBindings (scope.FastHasFlags (KeyBindingScope.Application) ? null : new ()); Command [] commands = { Command.Right, Command.Left }; var key = new Key (Key.A); @@ -356,7 +354,7 @@ public class KeyBindingTests keyBindings.Add (Key.Q.WithCtrl, KeyBindingScope.Application, Command.HotKey); var key = new Key (Key.Q.WithCtrl); bool result = keyBindings.TryGet (key, out KeyBinding _); - Assert.True (result);; + Assert.True (result); ; result = keyBindings.Bindings.TryGetValue (key, out KeyBinding _); Assert.True (result); @@ -379,4 +377,18 @@ public class KeyBindingTests Assert.True (result); Assert.Contains (Command.HotKey, bindings.Commands); } + + [Fact] + public void ReplaceCommands_Replaces () + { + var keyBindings = new KeyBindings (); + keyBindings.Add (Key.A, KeyBindingScope.Application, Command.Accept); + + keyBindings.ReplaceCommands (Key.A, Command.Refresh); + + bool result = keyBindings.TryGet (Key.A, out KeyBinding bindings); + Assert.True (result); + Assert.Contains (Command.Refresh, bindings.Commands); + + } } diff --git a/UnitTests/Input/KeyTests.cs b/UnitTests/Input/Keyboard/KeyTests.cs similarity index 100% rename from UnitTests/Input/KeyTests.cs rename to UnitTests/Input/Keyboard/KeyTests.cs diff --git a/UnitTests/Views/CheckBoxTests.cs b/UnitTests/Views/CheckBoxTests.cs index 1579a1c2b..a64c2e791 100644 --- a/UnitTests/Views/CheckBoxTests.cs +++ b/UnitTests/Views/CheckBoxTests.cs @@ -252,7 +252,7 @@ public class CheckBoxTests (ITestOutputHelper output) [Fact] [SetupFakeDriver] - public void Mouse_Click () + public void Mouse_Click_Selects () { var checkBox = new CheckBox { Text = "_Checkbox" }; Assert.True (checkBox.CanFocus); @@ -296,7 +296,7 @@ public class CheckBoxTests (ITestOutputHelper output) [Fact] [SetupFakeDriver] - public void Mouse_DoubleClick () + public void Mouse_DoubleClick_Accepts () { var checkBox = new CheckBox { Text = "_Checkbox" }; Assert.True (checkBox.CanFocus); @@ -308,7 +308,11 @@ public class CheckBoxTests (ITestOutputHelper output) checkBox.Selecting += (s, e) => selectCount++; int acceptCount = 0; - checkBox.Accepting += (s, e) => acceptCount++; + checkBox.Accepting += (s, e) => + { + acceptCount++; + e.Cancel = true; + }; checkBox.HasFocus = true; Assert.True (checkBox.HasFocus); @@ -319,9 +323,14 @@ public class CheckBoxTests (ITestOutputHelper output) Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked })); + Assert.Equal (CheckState.UnChecked, checkBox.CheckedState); + Assert.Equal (0, checkedStateChangingCount); + Assert.Equal (0, selectCount); + Assert.Equal (1, acceptCount); + } -#endregion Mouse Tests + #endregion Mouse Tests [Fact] [AutoInitShutdown] diff --git a/UnitTests/Views/TimeFieldTests.cs b/UnitTests/Views/TimeFieldTests.cs index 1964472d2..1d901fcdc 100644 --- a/UnitTests/Views/TimeFieldTests.cs +++ b/UnitTests/Views/TimeFieldTests.cs @@ -147,8 +147,8 @@ public class TimeFieldTests Assert.True (tf.NewKeyDownEvent (Key.End)); Assert.Equal (8, tf.CursorPosition); Assert.True (tf.NewKeyDownEvent (Key.A.WithCtrl)); - Assert.Equal (9, tf.CursorPosition); - Assert.Equal (tf.SelectedLength, tf.Text.Length); + Assert.Equal (1, tf.CursorPosition); + Assert.Equal (9, tf.Text.Length); Assert.True (tf.NewKeyDownEvent (Key.E.WithCtrl)); Assert.Equal (8, tf.CursorPosition); Assert.True (tf.NewKeyDownEvent (Key.CursorLeft));