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