浏览代码

Checkbox and RadioGroup mouse

Tig 10 月之前
父节点
当前提交
f860b175b2

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

@@ -67,7 +67,7 @@ public class Button : View, IDesignable
                     Command.HotKey,
                     () =>
                     {
-                        bool cachedIsDefault = IsDefault; // Supports "Swap Default" in Buttons scenario
+                        bool cachedIsDefault = IsDefault; // Supports "Swap Default" in Buttons scenario where IsDefault changes
 
                         bool? handled = RaiseAcceptEvent ();
 

+ 26 - 1
Terminal.Gui/Views/CheckBox.cs

@@ -39,7 +39,32 @@ public class CheckBox : View
 
     private void CheckBox_MouseClick (object? sender, MouseEventEventArgs e)
     {
-        e.Handled = AdvanceCheckState () == true;
+#if CHECKBOX_SUPPORTS_DOUBLE_CLICK_ACCEPT
+        CheckState savedCheckState = CheckedState;
+#endif
+
+        if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))
+        {
+            e.Handled = AdvanceCheckState () == true;
+        }
+
+#if CHECKBOX_SUPPORTS_DOUBLE_CLICK_ACCEPT
+        if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
+        {
+            if (RaiseAcceptEvent () == true)
+            {
+                e.Handled = false;
+                _checkedState = savedCheckState;
+            }
+
+            // TODO: This needs to be made consistent with how Button.IsDefault works
+            if (SuperView is { })
+            {
+                // TODO: This should pass context
+                SuperView.InvokeCommand (Command.Accept);
+            }
+        }
+#endif
     }
 
     private void Checkbox_TitleChanged (object? sender, EventArgs<string> e)

+ 50 - 30
Terminal.Gui/Views/RadioGroup.cs

@@ -83,21 +83,11 @@ public class RadioGroup : View, IDesignable, IOrientation
                             }
                         }
 
-                        return ChangeSelectedItem (Cursor);
+                        return ChangeSelectedItem (Cursor) is false or null;
                     });
 
-        AddCommand (
-                    Command.Accept,
-                    () =>
-                    {
-                        if (ChangeSelectedItem (Cursor) == true)
-                        {
-                            return true;
-                        }
-
-                        return RaiseAcceptEvent () is false;
-                    }
-                   );
+        // Accept (Enter key) - Raise Accept event - DO NOT advance state
+        AddCommand (Command.Accept, RaiseAcceptEvent);
 
         AddCommand (
                     Command.HotKey,
@@ -122,7 +112,7 @@ public class RadioGroup : View, IDesignable, IOrientation
                             }
 
                             // If a RadioItem.HotKey is pressed we always set the selected item - never SetFocus
-                            if (ChangeSelectedItem (item.Value) == true)
+                            if (ChangeSelectedItem (item.Value) is null or false)
                             {
                                 return true;
                             }
@@ -180,35 +170,65 @@ public class RadioGroup : View, IDesignable, IOrientation
         KeyBindings.Add (Key.End, Command.End);
     }
 
+    /// <summary>
+    ///     Gets or sets whether double clicking on a Radio Item will cause the <see cref="View.Accept"/> event to be raised.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         If <see langword="false"/> and Accept is not handled, the Accept event on the <see cref="View.SuperView"/> will be raised. The default is
+    ///         <see langword="true"/>.
+    ///     </para>
+    /// </remarks>
+    public bool DoubleClickAccepts { get; set; } = true;
+
     private void RadioGroup_MouseClick (object sender, MouseEventEventArgs e)
     {
-        SetFocus ();
+        if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))
+        {
+            int viewportX = e.MouseEvent.Position.X;
+            int viewportY = e.MouseEvent.Position.Y;
 
-        int viewportX = e.MouseEvent.Position.X;
-        int viewportY = e.MouseEvent.Position.Y;
+            int pos = Orientation == Orientation.Horizontal ? viewportX : viewportY;
 
-        int pos = Orientation == Orientation.Horizontal ? viewportX : viewportY;
+            int rCount = Orientation == Orientation.Horizontal
+                             ? _horizontal.Last ().pos + _horizontal.Last ().length
+                             : _radioLabels.Count;
 
-        int rCount = Orientation == Orientation.Horizontal
-                         ? _horizontal.Last ().pos + _horizontal.Last ().length
-                         : _radioLabels.Count;
+            if (pos < rCount)
+            {
+                int c = Orientation == Orientation.Horizontal
+                            ? _horizontal.FindIndex (x => x.pos <= viewportX && x.pos + x.length - 2 >= viewportX)
+                            : viewportY;
 
-        if (pos < rCount)
+                if (c > -1)
+                {
+                    if (ChangeSelectedItem (c) == false)
+                    {
+                        Cursor = c;
+                        e.Handled = true;
+                    }
+                }
+            }
+        }
+
+        if (DoubleClickAccepts && e.MouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
         {
-            int c = Orientation == Orientation.Horizontal
-                        ? _horizontal.FindIndex (x => x.pos <= viewportX && x.pos + x.length - 2 >= viewportX)
-                        : viewportY;
+            int savedSelectedItem = SelectedItem;
 
-            if (c > -1)
+            if (RaiseAcceptEvent () == true)
             {
-                Cursor = SelectedItem = c;
-                SetNeedsDisplay ();
+                e.Handled = false;
+                _selected = savedSelectedItem;
             }
-        }
 
-        e.Handled = true;
+            if (SuperView?.InvokeCommand (Command.Accept) is false or null)
+            {
+                e.Handled = true;
+            }
+        }
     }
 
+
     private List<(int pos, int length)> _horizontal;
     private int _horizontalSpace = 2;
 

+ 2 - 1
UICatalog/Scenarios/Buttons.cs

@@ -231,7 +231,8 @@ public class Buttons : Scenario
             SelectedItem = 2,
             RadioLabels = new [] { "_Start", "_End", "_Center", "_Fill" },
             Title = "_9 RadioGroup",
-            BorderStyle = LineStyle.Dotted
+            BorderStyle = LineStyle.Dotted,
+            CanFocus = false
         };
         main.Add (radioGroup);
 

+ 122 - 78
UnitTests/Views/CheckBoxTests.cs

@@ -93,41 +93,6 @@ public class CheckBoxTests (ITestOutputHelper output)
         Assert.Equal ("Hello", view.TitleTextFormatter.Text);
     }
 
-    [Fact]
-    [SetupFakeDriver]
-    public void AllowCheckStateNone_Get_Set ()
-    {
-        var checkBox = new CheckBox { Text = "Check this out 你" };
-
-        checkBox.HasFocus = true;
-        Assert.True (checkBox.HasFocus);
-        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
-        Assert.True (checkBox.NewKeyDownEvent (Key.Space));
-        Assert.Equal (CheckState.Checked, checkBox.CheckedState);
-        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
-        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
-
-        checkBox.AllowCheckStateNone = true;
-        Assert.True (checkBox.NewKeyDownEvent (Key.Space));
-        Assert.Equal (CheckState.None, checkBox.CheckedState);
-        checkBox.Draw ();
-
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @$"
-{CM.Glyphs.CheckStateNone} Check this out 你",
-                                                      output
-                                                     );
-        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
-        Assert.Equal (CheckState.Checked, checkBox.CheckedState);
-        Assert.True (checkBox.NewKeyDownEvent (Key.Space));
-        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
-        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
-        Assert.Equal (CheckState.None, checkBox.CheckedState);
-
-        checkBox.AllowCheckStateNone = false;
-        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
-    }
-
     [Fact]
     public void Constructors_Defaults ()
     {
@@ -172,8 +137,33 @@ public class CheckBoxTests (ITestOutputHelper output)
         Assert.Equal (new (3, 4, 6, 1), ckb.Frame);
     }
 
+
+
+    [Fact]
+    [SetupFakeDriver]
+    public void AllowCheckStateNone_Get_Set ()
+    {
+        var checkBox = new CheckBox { Text = "Check this out 你" };
+
+        checkBox.HasFocus = true;
+        Assert.True (checkBox.HasFocus);
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+        Assert.True (checkBox.NewKeyDownEvent (Key.Space));
+        Assert.Equal (CheckState.Checked, checkBox.CheckedState);
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+
+        checkBox.AllowCheckStateNone = true;
+        Assert.True (checkBox.NewKeyDownEvent (Key.Space));
+        Assert.Equal (CheckState.None, checkBox.CheckedState);
+        checkBox.Draw ();
+
+        checkBox.AllowCheckStateNone = false;
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+    }
+
     [Fact]
-    public void KeyBindings_Command ()
+    public void Commands_Select ()
     {
         Application.Navigation = new ApplicationNavigation ();
         Application.Top = new Toplevel ();
@@ -219,53 +209,11 @@ public class CheckBoxTests (ITestOutputHelper output)
         Assert.Equal (3, selectCount);
         Assert.Equal (0, acceptCount);
 
-
         ckb.NewKeyDownEvent (Key.Enter);
         Assert.Equal (3, checkedStateChangingCount);
         Assert.Equal (3, selectCount);
         Assert.Equal (1, acceptCount);
 
-        //ckb.Text = "_Test";
-        //Assert.Equal (Key.T, ckb.HotKey);
-        //Assert.True (ckb.NewKeyDownEvent (Key.T));
-        //Assert.Equal (CheckState.Checked, ckb.CheckedState);
-        //Assert.True (checkedStateChangingCount);
-        //Assert.True (ckb.HasFocus);
-
-        //ckb.Text = "T_est";
-        //checkedStateChangingCount = false;
-        //Assert.Equal (Key.E, ckb.HotKey);
-        //Assert.True (ckb.NewKeyDownEvent (Key.E.WithAlt));
-        //Assert.True (checkedStateChangingCount);
-        //Assert.Equal (CheckState.UnChecked, ckb.CheckedState);
-
-        //checkedStateChangingCount = false;
-        //Assert.Equal (Key.E, ckb.HotKey);
-        //Assert.True (ckb.NewKeyDownEvent (Key.E));
-        //Assert.True (checkedStateChangingCount);
-        //Assert.Equal (CheckState.Checked, ckb.CheckedState);
-
-        //checkedStateChangingCount = false;
-        //Assert.False (ckb.NewKeyDownEvent (Key.Space));
-        //Assert.True (checkedStateChangingCount);
-        //Assert.Equal (CheckState.UnChecked, ckb.CheckedState);
-
-
-        //ckb.SetFocus ();
-        //Assert.False (ckb.NewKeyDownEvent (Key.Space));
-        //Assert.True (checkedStateChangingCount);
-        //Assert.Equal (CheckState.UnChecked, ckb.CheckedState);
-
-        //checkedStateChangingCount = false;
-        //Assert.True (ckb.NewKeyDownEvent (Key.Space));
-        //Assert.False (checkedStateChangingCount);
-        //Assert.Equal (CheckState.Checked, ckb.CheckedState);
-
-        //checkedStateChangingCount = false;
-        //Assert.False (ckb.NewKeyDownEvent (Key.Enter));
-        //Assert.False (checkedStateChangingCount);
-        //Assert.Equal (CheckState.Checked, ckb.CheckedState);
-
         Application.Top.Dispose ();
         Application.ResetState (false);
     }
@@ -291,6 +239,102 @@ public class CheckBoxTests (ITestOutputHelper output)
         }
     }
 
+    #region Mouse Tests
+
+    [Fact]
+    [SetupFakeDriver]
+    public void Mouse_Click ()
+    {
+        var checkBox = new CheckBox { Text = "_Checkbox" };
+        Assert.True (checkBox.CanFocus);
+
+        int checkedStateChangingCount = 0;
+        checkBox.CheckedStateChanging += (s, e) => checkedStateChangingCount++;
+
+        int selectCount = 0;
+        checkBox.Select += (s, e) => selectCount++;
+
+        int acceptCount = 0;
+        checkBox.Accept += (s, e) => acceptCount++;
+
+        checkBox.HasFocus = true;
+        Assert.True (checkBox.HasFocus);
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+        Assert.Equal (0, checkedStateChangingCount);
+        Assert.Equal (0, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (CheckState.Checked, checkBox.CheckedState);
+        Assert.Equal (1, checkedStateChangingCount);
+        Assert.Equal (1, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+        Assert.Equal (2, checkedStateChangingCount);
+        Assert.Equal (2, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        checkBox.AllowCheckStateNone = true;
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (CheckState.None, checkBox.CheckedState);
+        Assert.Equal (3, checkedStateChangingCount);
+        Assert.Equal (3, selectCount);
+        Assert.Equal (0, acceptCount);
+    }
+
+
+    [Fact]
+    [SetupFakeDriver]
+    public void Mouse_DoubleClick ()
+    {
+        var checkBox = new CheckBox { Text = "_Checkbox" };
+        Assert.True (checkBox.CanFocus);
+
+        int checkedStateChangingCount = 0;
+        checkBox.CheckedStateChanging += (s, e) => checkedStateChangingCount++;
+
+        int selectCount = 0;
+        checkBox.Select += (s, e) => selectCount++;
+
+        int acceptCount = 0;
+        checkBox.Accept += (s, e) => acceptCount++;
+
+        checkBox.HasFocus = true;
+        Assert.True (checkBox.HasFocus);
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+        Assert.Equal (0, checkedStateChangingCount);
+        Assert.Equal (0, selectCount);
+        Assert.Equal (0, acceptCount);
+
+#if !CHECKBOX_SUPPORTS_DOUBLE_CLICK_ACCEPT
+        Assert.False (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+#else
+
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (CheckState.Checked, checkBox.CheckedState);
+        Assert.Equal (1, checkedStateChangingCount);
+        Assert.Equal (1, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
+        Assert.Equal (2, checkedStateChangingCount);
+        Assert.Equal (2, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        checkBox.AllowCheckStateNone = true;
+        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (CheckState.None, checkBox.CheckedState);
+        Assert.Equal (3, checkedStateChangingCount);
+        Assert.Equal (3, selectCount);
+        Assert.Equal (0, acceptCount);
+#endif
+    }
+
+#endregion Mouse Tests
+
     [Fact]
     [AutoInitShutdown]
     public void TextAlignment_Centered ()

+ 202 - 30
UnitTests/Views/RadioGroupTests.cs

@@ -1,6 +1,8 @@
 using System.ComponentModel;
 using Xunit.Abstractions;
 
+// ReSharper disable AccessToModifiedClosure
+
 namespace Terminal.Gui.ViewsTests;
 
 public class RadioGroupTests (ITestOutputHelper output)
@@ -50,7 +52,7 @@ public class RadioGroupTests (ITestOutputHelper output)
     public void Initialize_SelectedItem_With_Minus_One ()
     {
         var rg = new RadioGroup { RadioLabels = new [] { "Test" }, SelectedItem = -1 };
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
         Application.Top.Add (rg);
         rg.SetFocus ();
 
@@ -80,18 +82,18 @@ public class RadioGroupTests (ITestOutputHelper output)
     {
         Application.Navigation = new ();
         var rg = new RadioGroup { RadioLabels = new [] { "Test", "New Test" } };
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
         Application.Top.Add (rg);
         rg.SetFocus ();
         Assert.Equal (Orientation.Vertical, rg.Orientation);
 
-        int selectedItemChangedCount = 0;
+        var selectedItemChangedCount = 0;
         rg.SelectedItemChanged += (s, e) => selectedItemChangedCount++;
 
-        int selectCount = 0;
+        var selectCount = 0;
         rg.Select += (s, e) => selectCount++;
 
-        int acceptCount = 0;
+        var acceptCount = 0;
         rg.Accept += (s, e) => acceptCount++;
 
         // By default the first item is selected
@@ -172,7 +174,7 @@ public class RadioGroupTests (ITestOutputHelper output)
 
         rg.HotKey = Key.L;
         Assert.Equal (Key.L, rg.HotKey);
-        Assert.True (Application.OnKeyDown (Key.L));
+        Assert.True (Application.OnKeyDown (rg.HotKey));
         Assert.Equal (0, rg.SelectedItem);
         Assert.Equal (0, rg.Cursor);
         Assert.Equal (8, selectedItemChangedCount);
@@ -185,14 +187,14 @@ public class RadioGroupTests (ITestOutputHelper output)
         Assert.Equal (1, rg.Cursor);
 
         //    Selected != Cursor - Select Cursor and raise Select event - DO NOT raise Accept
-        Assert.True (Application.OnKeyDown (Key.L));
+        Assert.True (Application.OnKeyDown (rg.HotKey));
         Assert.Equal (1, rg.SelectedItem);
         Assert.Equal (1, rg.Cursor);
         Assert.Equal (9, selectedItemChangedCount);
         Assert.Equal (9, selectCount);
         Assert.Equal (0, acceptCount);
 
-        Application.ResetState (ignoreDisposed: true);
+        Application.ResetState (true);
     }
 
     [Fact]
@@ -200,7 +202,7 @@ public class RadioGroupTests (ITestOutputHelper output)
     {
         Application.Navigation = new ();
         var rg = new RadioGroup { RadioLabels = new [] { "Test", "New Test" } };
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         // With !HasFocus
         View otherView = new () { Id = "otherView", CanFocus = true };
@@ -208,19 +210,19 @@ public class RadioGroupTests (ITestOutputHelper output)
         Label label = new ()
         {
             Id = "label",
-            Title = "_R",
+            Title = "_R"
         };
 
         Application.Top.Add (label, rg, otherView);
         otherView.SetFocus ();
 
-        int selectedItemChangedCount = 0;
+        var selectedItemChangedCount = 0;
         rg.SelectedItemChanged += (s, e) => selectedItemChangedCount++;
 
-        int selectCount = 0;
+        var selectCount = 0;
         rg.Select += (s, e) => selectCount++;
 
-        int acceptCount = 0;
+        var acceptCount = 0;
         rg.Accept += (s, e) => acceptCount++;
 
         // By default the first item is selected
@@ -237,7 +239,7 @@ public class RadioGroupTests (ITestOutputHelper output)
         //    Selected (0) == Cursor (0) - SetFocus
         rg.HotKey = Key.L;
         Assert.Equal (Key.L, rg.HotKey);
-        Assert.True (Application.OnKeyDown (Key.L));
+        Assert.True (Application.OnKeyDown (rg.HotKey));
         Assert.True (rg.HasFocus);
         Assert.Equal (0, rg.SelectedItem);
         Assert.Equal (0, rg.Cursor);
@@ -253,7 +255,7 @@ public class RadioGroupTests (ITestOutputHelper output)
         otherView.SetFocus ();
 
         //    Selected != Cursor - SetFocus
-        Assert.True (Application.OnKeyDown (Key.L));
+        Assert.True (Application.OnKeyDown (rg.HotKey));
         Assert.True (rg.HasFocus);
         Assert.Equal (0, rg.SelectedItem);
         Assert.Equal (1, rg.Cursor);
@@ -261,7 +263,7 @@ public class RadioGroupTests (ITestOutputHelper output)
         Assert.Equal (0, selectCount);
         Assert.Equal (0, acceptCount);
 
-        Assert.True (Application.OnKeyDown (Key.L));
+        Assert.True (Application.OnKeyDown (rg.HotKey));
         Assert.True (rg.HasFocus);
         Assert.Equal (1, rg.SelectedItem);
         Assert.Equal (1, rg.Cursor);
@@ -269,16 +271,15 @@ public class RadioGroupTests (ITestOutputHelper output)
         Assert.Equal (1, selectCount);
         Assert.Equal (0, acceptCount);
 
-        Application.ResetState (ignoreDisposed: true);
+        Application.ResetState (true);
     }
 
-
     [Fact]
     public void HotKeys_HasFocus_False_Does_Not_SetFocus_Selects ()
     {
         Application.Navigation = new ();
         var rg = new RadioGroup { RadioLabels = new [] { "Item _A", "Item _B" } };
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
 
         // With !HasFocus
         View otherView = new () { Id = "otherView", CanFocus = true };
@@ -286,19 +287,19 @@ public class RadioGroupTests (ITestOutputHelper output)
         Label label = new ()
         {
             Id = "label",
-            Title = "_R",
+            Title = "_R"
         };
 
         Application.Top.Add (label, rg, otherView);
         otherView.SetFocus ();
 
-        int selectedItemChangedCount = 0;
+        var selectedItemChangedCount = 0;
         rg.SelectedItemChanged += (s, e) => selectedItemChangedCount++;
 
-        int selectCount = 0;
+        var selectCount = 0;
         rg.Select += (s, e) => selectCount++;
 
-        int acceptCount = 0;
+        var acceptCount = 0;
         rg.Accept += (s, e) => acceptCount++;
 
         // By default the first item is selected
@@ -322,6 +323,7 @@ public class RadioGroupTests (ITestOutputHelper output)
         Assert.Equal (0, acceptCount);
 
         rg.SetFocus ();
+
         //     Make Selected != Cursor
         Assert.True (Application.OnKeyDown (Key.CursorDown));
         Assert.Equal (0, rg.SelectedItem);
@@ -355,14 +357,14 @@ public class RadioGroupTests (ITestOutputHelper output)
         Assert.Equal (1, selectCount);
         Assert.Equal (0, acceptCount);
 
-
-        Application.ResetState (ignoreDisposed: true);
+        Application.ResetState (true);
     }
+
     [Fact]
     public void HotKeys_HasFocus_True_Selects ()
     {
         var rg = new RadioGroup { RadioLabels = new [] { "_Left", "_Right", "Cen_tered", "_Justified" } };
-        Application.Top = new Toplevel ();
+        Application.Top = new ();
         Application.Top.Add (rg);
         rg.SetFocus ();
 
@@ -413,7 +415,7 @@ public class RadioGroupTests (ITestOutputHelper output)
     }
 
     [Fact]
-    public void HotKey_For_View_SetsFocus ()
+    public void HotKey_SetsFocus ()
     {
         var superView = new View
         {
@@ -438,7 +440,34 @@ public class RadioGroupTests (ITestOutputHelper output)
     }
 
     [Fact]
-    public void HotKey_For_Item_Does_Not_SetFocus ()
+    public void HotKey_No_SelectedItem_Selects_First ()
+    {
+        var superView = new View
+        {
+            CanFocus = true
+        };
+        superView.Add (new View { CanFocus = true });
+
+        var group = new RadioGroup
+        {
+            Title = "Radio_Group",
+            RadioLabels = new [] { "_Left", "_Right", "Cen_tered", "_Justified" }
+        };
+        group.SelectedItem = -1;
+
+        superView.Add (group);
+
+        Assert.False (group.HasFocus);
+        Assert.Equal (-1, group.SelectedItem);
+
+        group.NewKeyDownEvent (Key.G.WithAlt);
+
+        Assert.Equal (0, group.SelectedItem);
+        Assert.True (group.HasFocus);
+    }
+
+    [Fact]
+    public void HotKeys_Does_Not_SetFocus ()
     {
         var superView = new View
         {
@@ -474,7 +503,7 @@ public class RadioGroupTests (ITestOutputHelper output)
     }
 
     [Fact]
-    public void Accept_Command_Does_Not_Fire_Accept ()
+    public void Accept_Command_Fires_Accept ()
     {
         var group = new RadioGroup { RadioLabels = new [] { "_Left", "_Right", "Cen_tered", "_Justified" } };
         var accepted = false;
@@ -482,7 +511,7 @@ public class RadioGroupTests (ITestOutputHelper output)
         group.Accept += OnAccept;
         group.InvokeCommand (Command.Accept);
 
-        Assert.False (accepted);
+        Assert.True (accepted);
 
         return;
 
@@ -581,4 +610,147 @@ public class RadioGroupTests (ITestOutputHelper output)
         Assert.Equal (0, previousSelectedItem);
         Assert.Equal (selectedItem, rg.SelectedItem);
     }
+
+    #region Mouse Tests
+
+    [Fact]
+    [SetupFakeDriver]
+    public void Mouse_Click ()
+    {
+        var radioGroup = new RadioGroup
+        {
+            RadioLabels = ["_1", "__2"]
+        };
+        Assert.True (radioGroup.CanFocus);
+
+        var selectedItemChanged = 0;
+        radioGroup.SelectedItemChanged += (s, e) => selectedItemChanged++;
+
+        var selectCount = 0;
+        radioGroup.Select += (s, e) => selectCount++;
+
+        var acceptCount = 0;
+        radioGroup.Accept += (s, e) => acceptCount++;
+
+        Assert.Equal (Orientation.Vertical, radioGroup.Orientation);
+
+        radioGroup.HasFocus = true;
+        Assert.True (radioGroup.HasFocus);
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (0, selectedItemChanged);
+        Assert.Equal (0, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.False (radioGroup.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (0, selectedItemChanged);
+        Assert.Equal (0, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.True (radioGroup.NewMouseEvent (new () { Position = new (0, 1), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (1, radioGroup.SelectedItem);
+        Assert.Equal (1, selectedItemChanged);
+        Assert.Equal (1, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.True (radioGroup.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (2, selectedItemChanged);
+        Assert.Equal (2, selectCount);
+        Assert.Equal (0, acceptCount);
+    }
+
+    [Fact]
+    [SetupFakeDriver]
+    public void Mouse_DoubleClick ()
+    {
+        var radioGroup = new RadioGroup
+        {
+            RadioLabels = ["_1", "__2"]
+        };
+        Assert.True (radioGroup.CanFocus);
+
+        var selectedItemChanged = 0;
+        radioGroup.SelectedItemChanged += (s, e) => selectedItemChanged++;
+
+        var selectCount = 0;
+        radioGroup.Select += (s, e) => selectCount++;
+
+        var acceptCount = 0;
+        var handleAccept = false;
+
+        radioGroup.Accept += (s, e) =>
+                             {
+                                 acceptCount++;
+                                 e.Handled = handleAccept;
+                             };
+
+        Assert.True (radioGroup.DoubleClickAccepts);
+        Assert.Equal (Orientation.Vertical, radioGroup.Orientation);
+
+        radioGroup.HasFocus = true;
+        Assert.True (radioGroup.HasFocus);
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (0, selectedItemChanged);
+        Assert.Equal (0, selectCount);
+        Assert.Equal (0, acceptCount);
+
+        Assert.True (radioGroup.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (0, selectedItemChanged);
+        Assert.Equal (0, selectCount);
+        Assert.Equal (1, acceptCount);
+
+        Assert.True (radioGroup.NewMouseEvent (new () { Position = new (0, 1), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (1, radioGroup.SelectedItem);
+        Assert.Equal (1, selectedItemChanged);
+        Assert.Equal (1, selectCount);
+        Assert.Equal (1, acceptCount);
+        Assert.True (radioGroup.NewMouseEvent (new () { Position = new (0, 1), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (1, radioGroup.SelectedItem);
+        Assert.Equal (1, selectedItemChanged);
+        Assert.Equal (1, selectCount);
+        Assert.Equal (2, acceptCount);
+
+        View superView = new () { Id = "superView", CanFocus = true };
+        superView.Add (radioGroup);
+        superView.SetFocus ();
+
+        Assert.True (radioGroup.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked }));
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (2, selectedItemChanged);
+        Assert.Equal (2, selectCount);
+        Assert.Equal (2, acceptCount);
+
+        var superViewAcceptCount = 0;
+
+        superView.Accept += (s, a) =>
+                            {
+                                superViewAcceptCount++;
+                                a.Handled = true;
+                            };
+
+        Assert.Equal (0, superViewAcceptCount);
+
+        handleAccept = true;
+        Assert.False (radioGroup.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (2, selectedItemChanged);
+        Assert.Equal (2, selectCount);
+        Assert.Equal (3, acceptCount);
+        Assert.Equal (1, superViewAcceptCount);
+
+        handleAccept = false;
+        Assert.False (radioGroup.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
+        Assert.Equal (0, radioGroup.SelectedItem);
+        Assert.Equal (2, selectedItemChanged);
+        Assert.Equal (2, selectCount);
+        Assert.Equal (4, acceptCount);
+        Assert.Equal (2, superViewAcceptCount);
+
+        radioGroup.DoubleClickAccepts = false;
+        Assert.False (radioGroup.NewMouseEvent (new () { Position = new (0, 1), Flags = MouseFlags.Button1DoubleClicked }));
+    }
+
+    #endregion Mouse Tests
 }