Explorar o código

Merge pull request #3372 from tig/v2_3370_continuous_button

Fixes #3370. Adds visual highlight for press and hold (for `Button`, `Checkbox`, `RadioGroup`, and `Border`)
Tig hai 1 ano
pai
achega
f1bc42aaa5
Modificáronse 66 ficheiros con 2260 adicións e 1552 borrados
  1. 42 44
      Terminal.Gui/Application.cs
  2. 2 2
      Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs
  3. 7 1
      Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
  4. 3 3
      Terminal.Gui/ConsoleDrivers/NetDriver.cs
  5. 26 15
      Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
  6. 22 0
      Terminal.Gui/Drawing/Color.cs
  7. 1 0
      Terminal.Gui/Terminal.Gui.csproj
  8. 10 1
      Terminal.Gui/View/Adornment/Adornment.cs
  9. 59 1
      Terminal.Gui/View/Adornment/Border.cs
  10. 6 1
      Terminal.Gui/View/Adornment/Padding.cs
  11. 4 1
      Terminal.Gui/View/ViewAdornments.cs
  12. 9 2
      Terminal.Gui/View/ViewDrawing.cs
  13. 485 52
      Terminal.Gui/View/ViewMouse.cs
  14. 19 2
      Terminal.Gui/View/ViewSubViews.cs
  15. 35 1
      Terminal.Gui/Views/Button.cs
  16. 1 0
      Terminal.Gui/Views/CheckBox.cs
  17. 55 45
      Terminal.Gui/Views/ColorPicker.cs
  18. 2 2
      Terminal.Gui/Views/ComboBox.cs
  19. 11 5
      Terminal.Gui/Views/DatePicker.cs
  20. 16 16
      Terminal.Gui/Views/Menu/Menu.cs
  21. 4 4
      Terminal.Gui/Views/Menu/MenuBar.cs
  22. 59 60
      Terminal.Gui/Views/MessageBox.cs
  23. 35 40
      Terminal.Gui/Views/RadioGroup.cs
  24. 2 2
      Terminal.Gui/Views/ScrollBarView.cs
  25. 8 2
      Terminal.Gui/Views/ScrollView.cs
  26. 1 1
      Terminal.Gui/Views/TabView.cs
  27. 1 1
      Terminal.Gui/Views/Toplevel.cs
  28. 1 1
      UICatalog/Scenarios/ASCIICustomButton.cs
  29. 1 1
      UICatalog/Scenarios/Adornments.cs
  30. 3 3
      UICatalog/Scenarios/BasicColors.cs
  31. 172 64
      UICatalog/Scenarios/Buttons.cs
  32. 0 3
      UICatalog/Scenarios/CharacterMap.cs
  33. 1 1
      UICatalog/Scenarios/ContextMenus.cs
  34. 95 21
      UICatalog/Scenarios/Mouse.cs
  35. 12 6
      UICatalog/Scenarios/ProgressBarStyles.cs
  36. 1 1
      UICatalog/Scenarios/Scrolling.cs
  37. 32 2
      UICatalog/Scenarios/TrueColors.cs
  38. 35 118
      UnitTests/Application/ApplicationTests.cs
  39. 17 38
      UnitTests/Application/MouseTests.cs
  40. 2 10
      UnitTests/Input/EscSeqUtilsTests.cs
  41. 3 3
      UnitTests/Input/ResponderTests.cs
  42. 82 0
      UnitTests/TestHelpers.cs
  43. 1 1
      UnitTests/Text/AutocompleteTests.cs
  44. 495 6
      UnitTests/View/MouseTests.cs
  45. 4 4
      UnitTests/View/NavigationTests.cs
  46. 3 3
      UnitTests/View/ViewTests.cs
  47. 5 85
      UnitTests/Views/AllViewsTests.cs
  48. 88 142
      UnitTests/Views/ButtonTests.cs
  49. 3 3
      UnitTests/Views/CheckBoxTests.cs
  50. 2 2
      UnitTests/Views/ColorPickerTests.cs
  51. 27 27
      UnitTests/Views/ComboBoxTests.cs
  52. 19 51
      UnitTests/Views/ContextMenuTests.cs
  53. 1 1
      UnitTests/Views/LabelTests.cs
  54. 10 15
      UnitTests/Views/ListViewTests.cs
  55. 43 59
      UnitTests/Views/MenuBarTests.cs
  56. 13 76
      UnitTests/Views/OverlappedTests.cs
  57. 2 10
      UnitTests/Views/ScrollBarViewTests.cs
  58. 1 1
      UnitTests/Views/StatusBarTests.cs
  59. 10 28
      UnitTests/Views/TabViewTests.cs
  60. 7 7
      UnitTests/Views/TableViewTests.cs
  61. 13 13
      UnitTests/Views/TextFieldTests.cs
  62. 1 1
      UnitTests/Views/TextValidateFieldTests.cs
  63. 17 17
      UnitTests/Views/TextViewTests.cs
  64. 105 416
      UnitTests/Views/ToplevelTests.cs
  65. 4 4
      UnitTests/Views/TreeTableSourceTests.cs
  66. 4 4
      UnitTests/Views/TreeViewTests.cs

+ 42 - 44
Terminal.Gui/Application.cs

@@ -318,7 +318,7 @@ public static partial class Application
     private static void Driver_SizeChanged (object sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
     private static void Driver_KeyDown (object sender, Key e) { OnKeyDown (e); }
     private static void Driver_KeyUp (object sender, Key e) { OnKeyUp (e); }
-    private static void Driver_MouseEvent (object sender, MouseEventEventArgs e) { OnMouseEvent (e); }
+    private static void Driver_MouseEvent (object sender, MouseEvent e) { OnMouseEvent (e); }
 
     /// <summary>Gets of list of <see cref="ConsoleDriver"/> types that are available.</summary>
     /// <returns></returns>
@@ -1441,12 +1441,12 @@ public static partial class Application
     ///     </para>
     ///     <para>The <see cref="MouseEvent.View"/> will contain the <see cref="View"/> that contains the mouse coordinates.</para>
     /// </remarks>
-    public static event EventHandler<MouseEventEventArgs> MouseEvent;
+    public static event EventHandler<MouseEvent> MouseEvent;
 
     /// <summary>Called when a mouse event occurs. Raises the <see cref="MouseEvent"/> event.</summary>
     /// <remarks>This method can be used to simulate a mouse event, e.g. in unit tests.</remarks>
     /// <param name="a">The mouse event with coordinates relative to the screen.</param>
-    internal static void OnMouseEvent (MouseEventEventArgs a)
+    internal static void OnMouseEvent (MouseEvent mouseEvent)
     {
         if (IsMouseDisabled)
         {
@@ -1454,25 +1454,16 @@ public static partial class Application
         }
 
         // TODO: In PR #3273, FindDeepestView will return adornments. Update logic below to fix adornment mouse handling
-        var view = View.FindDeepestView (Current, a.MouseEvent.X, a.MouseEvent.Y);
-
-        if (view is { WantContinuousButtonPressed: true })
-        {
-            WantContinuousButtonPressedView = view;
-        }
-        else
-        {
-            WantContinuousButtonPressedView = null;
-        }
+        var view = View.FindDeepestView (Current, mouseEvent.X, mouseEvent.Y);
 
         if (view is { })
         {
-            a.MouseEvent.View = view;
+            mouseEvent.View = view;
         }
 
-        MouseEvent?.Invoke (null, new (a.MouseEvent));
+        MouseEvent?.Invoke (null, mouseEvent);
 
-        if (a.MouseEvent.Handled)
+        if (mouseEvent.Handled)
         {
             return;
         }
@@ -1481,45 +1472,52 @@ public static partial class Application
         {
             // If the mouse is grabbed, send the event to the view that grabbed it.
             // The coordinates are relative to the Bounds of the view that grabbed the mouse.
-            Point frameLoc = MouseGrabView.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
+            Point boundsLoc = MouseGrabView.ScreenToBounds (mouseEvent.X, mouseEvent.Y);
 
             var viewRelativeMouseEvent = new MouseEvent
             {
-                X = frameLoc.X,
-                Y = frameLoc.Y,
-                Flags = a.MouseEvent.Flags,
-                ScreenPosition = new (a.MouseEvent.X, a.MouseEvent.Y),
-                View = view
+                X = boundsLoc.X,
+                Y = boundsLoc.Y,
+                Flags = mouseEvent.Flags,
+                ScreenPosition = new (mouseEvent.X, mouseEvent.Y),
+                View = MouseGrabView
             };
 
             if (MouseGrabView.Bounds.Contains (viewRelativeMouseEvent.X, viewRelativeMouseEvent.Y) is false)
             {
-                // The mouse has moved outside the bounds of the view that
-                // grabbed the mouse, so we tell the view that last got 
-                // OnMouseEnter the mouse is leaving
-                // BUGBUG: That sentence makes no sense. Either I'm missing something or this logic is flawed.
-                _mouseEnteredView?.OnMouseLeave (a.MouseEvent);
+                // The mouse has moved outside the bounds of the view that grabbed the mouse
+                _mouseEnteredView?.NewMouseLeaveEvent (mouseEvent);
             }
 
             //System.Diagnostics.Debug.WriteLine ($"{nme.Flags};{nme.X};{nme.Y};{mouseGrabView}");
-            if (MouseGrabView?.OnMouseEvent (viewRelativeMouseEvent) == true)
+            if (MouseGrabView?.NewMouseEvent (viewRelativeMouseEvent) == true)
             {
                 return;
             }
         }
 
+        if (view is { WantContinuousButtonPressed: true })
+        {
+            WantContinuousButtonPressedView = view;
+        }
+        else
+        {
+            WantContinuousButtonPressedView = null;
+        }
+
+
         if (view is not Adornment)
         {
             if ((view is null || view == OverlappedTop)
                 && Current is { Modal: false }
                 && OverlappedTop != null
-                && a.MouseEvent.Flags != MouseFlags.ReportMousePosition
-                && a.MouseEvent.Flags != 0)
+                && mouseEvent.Flags != MouseFlags.ReportMousePosition
+                && mouseEvent.Flags != 0)
             {
                 // This occurs when there are multiple overlapped "tops"
                 // E.g. "Mdi" - in the Background Worker Scenario
-                View? top = FindDeepestTop (Top, a.MouseEvent.X, a.MouseEvent.Y);
-                view = View.FindDeepestView (top, a.MouseEvent.X, a.MouseEvent.Y);
+                View? top = FindDeepestTop (Top, mouseEvent.X, mouseEvent.Y);
+                view = View.FindDeepestView (top, mouseEvent.X, mouseEvent.Y);
 
                 if (view is { } && view != OverlappedTop && top != Current)
                 {
@@ -1537,27 +1535,27 @@ public static partial class Application
 
         if (view is Adornment adornment)
         {
-            Point frameLoc = adornment.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
+            Point frameLoc = adornment.ScreenToFrame (mouseEvent.X, mouseEvent.Y);
 
             me = new ()
             {
                 X = frameLoc.X,
                 Y = frameLoc.Y,
-                Flags = a.MouseEvent.Flags,
-                ScreenPosition = new (a.MouseEvent.X, a.MouseEvent.Y),
+                Flags = mouseEvent.Flags,
+                ScreenPosition = new (mouseEvent.X, mouseEvent.Y),
                 View = view
             };
         }
-        else if (view.BoundsToScreen (view.Bounds).Contains (a.MouseEvent.X, a.MouseEvent.Y))
+        else if (view.BoundsToScreen (view.Bounds).Contains (mouseEvent.X, mouseEvent.Y))
         {
-            Point boundsPoint = view.ScreenToBounds (a.MouseEvent.X, a.MouseEvent.Y);
+            Point boundsPoint = view.ScreenToBounds (mouseEvent.X, mouseEvent.Y);
 
             me = new ()
             {
                 X = boundsPoint.X,
                 Y = boundsPoint.Y,
-                Flags = a.MouseEvent.Flags,
-                ScreenPosition = new (a.MouseEvent.X, a.MouseEvent.Y),
+                Flags = mouseEvent.Flags,
+                ScreenPosition = new (mouseEvent.X, mouseEvent.Y),
                 View = view
             };
         }
@@ -1570,16 +1568,16 @@ public static partial class Application
         if (_mouseEnteredView is null)
         {
             _mouseEnteredView = view;
-            view.OnMouseEnter (me);
+            view.NewMouseEnterEvent (me);
         }
         else if (_mouseEnteredView != view)
         {
-            _mouseEnteredView.OnMouseLeave (me);
-            view.OnMouseEnter (me);
+            _mouseEnteredView.NewMouseLeaveEvent (me);
+            view.NewMouseEnterEvent (me);
             _mouseEnteredView = view;
         }
 
-        if (!view.WantMousePositionReports && a.MouseEvent.Flags == MouseFlags.ReportMousePosition)
+        if (!view.WantMousePositionReports && mouseEvent.Flags == MouseFlags.ReportMousePosition)
         {
             return;
         }
@@ -1588,7 +1586,7 @@ public static partial class Application
 
         //Debug.WriteLine ($"OnMouseEvent: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags}");
 
-        if (view.OnMouseEvent (me))
+        if (view.NewMouseEvent (me) == false)
         {
             // Should we bubble up the event, if it is not handled?
             //return;

+ 2 - 2
Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs

@@ -538,11 +538,11 @@ public abstract class ConsoleDriver
     public void OnKeyUp (Key a) { KeyUp?.Invoke (this, a); }
 
     /// <summary>Event fired when a mouse event occurs.</summary>
-    public event EventHandler<MouseEventEventArgs> MouseEvent;
+    public event EventHandler<MouseEvent> MouseEvent;
 
     /// <summary>Called when a mouse event occurs. Fires the <see cref="MouseEvent"/> event.</summary>
     /// <param name="a"></param>
-    public void OnMouseEvent (MouseEventEventArgs a) { MouseEvent?.Invoke (this, a); }
+    public void OnMouseEvent (MouseEvent a) { MouseEvent?.Invoke (this, a); }
 
     /// <summary>Simulates a key press.</summary>
     /// <param name="keyChar">The key character.</param>

+ 7 - 1
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -2,6 +2,7 @@
 // Driver.cs: Curses-based Driver
 //
 
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 using Terminal.Gui.ConsoleDrivers;
 using Unix.Terminal;
@@ -798,6 +799,9 @@ internal class CursesDriver : ConsoleDriver
                    || flag.HasFlag (MouseFlags.Button4DoubleClicked);
         }
 
+        Debug.WriteLine ($"CursesDriver: ({pos.X},{pos.Y}) - {mouseFlag}");
+
+
         if ((WasButtonReleased (mouseFlag) && IsButtonNotPressed (_lastMouseFlags)) || (IsButtonClickedOrDoubleClicked (mouseFlag) && _lastMouseFlags == 0))
         {
             return;
@@ -806,7 +810,9 @@ internal class CursesDriver : ConsoleDriver
         _lastMouseFlags = mouseFlag;
 
         var me = new MouseEvent { Flags = mouseFlag, X = pos.X, Y = pos.Y };
-        OnMouseEvent (new MouseEventEventArgs (me));
+        Debug.WriteLine ($"CursesDriver: ({me.X},{me.Y}) - {me.Flags}");
+
+        OnMouseEvent (me);
     }
 
     #region Color Handling

+ 3 - 3
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -1137,8 +1137,8 @@ internal class NetDriver : ConsoleDriver
                 break;
             case EventType.Mouse:
                 MouseEvent me = ToDriverMouse (inputEvent.MouseEvent);
-                //Debug.WriteLine ($"NetDriver: ({me.X},{me.Y}) - {me.Flags}");
-                OnMouseEvent (new MouseEventEventArgs (me));
+                Debug.WriteLine ($"NetDriver: ({me.X},{me.Y}) - {me.Flags}");
+                OnMouseEvent (me);
 
                 break;
             case EventType.WindowSize:
@@ -1379,7 +1379,7 @@ internal class NetDriver : ConsoleDriver
 
     private MouseEvent ToDriverMouse (NetEvents.MouseEvent me)
     {
-       // System.Diagnostics.Debug.WriteLine ($"X: {me.Position.X}; Y: {me.Position.Y}; ButtonState: {me.ButtonState}");
+       //System.Diagnostics.Debug.WriteLine ($"X: {me.Position.X}; Y: {me.Position.Y}; ButtonState: {me.ButtonState}");
 
         MouseFlags mouseFlag = 0;
 

+ 26 - 15
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1419,18 +1419,16 @@ internal class WindowsDriver : ConsoleDriver
                     break;
                 }
 
-                OnMouseEvent (new MouseEventEventArgs (me));
+                OnMouseEvent (me);
 
                 if (_processButtonClick)
                 {
-                    OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = me.X,
-                                                               Y = me.Y,
-                                                               Flags = ProcessButtonClick (inputEvent.MouseEvent)
-                                                           }));
+                    OnMouseEvent (new ()
+                    {
+                        X = me.X,
+                        Y = me.Y,
+                        Flags = ProcessButtonClick (inputEvent.MouseEvent)
+                    });
                 }
 
                 break;
@@ -1730,10 +1728,16 @@ internal class WindowsDriver : ConsoleDriver
 
     private async Task ProcessContinuousButtonPressedAsync (MouseFlags mouseFlag)
     {
+        // When a user presses-and-holds, start generating pressed events every `startDelay`
+        // After `iterationsUntilFast` iterations, speed them up to `fastDelay` ms
+        const int startDelay = 500;
+        const int iterationsUntilFast = 4;
+        const int fastDelay = 50;
+
+        int iterations = 0;
+        int delay = startDelay;
         while (_isButtonPressed)
         {
-            await Task.Delay (100);
-
             var me = new MouseEvent
             {
                 X = _pointMove.X,
@@ -1741,16 +1745,21 @@ internal class WindowsDriver : ConsoleDriver
                 Flags = mouseFlag
             };
 
-            View view = Application.WantContinuousButtonPressedView;
-
-            if (view is null)
+            if (Application.WantContinuousButtonPressedView is null)
             {
                 break;
             }
 
+            if (iterations++ >= iterationsUntilFast)
+            {
+                delay = fastDelay;
+            }
+            await Task.Delay (delay);
+
+            //Debug.WriteLine($"ProcessContinuousButtonPressedAsync: {view}");
             if (_isButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0)
             {
-                Application.Invoke (() => OnMouseEvent (new MouseEventEventArgs (me)));
+                Application.Invoke (() => OnMouseEvent (me));
             }
         }
     }
@@ -1919,6 +1928,8 @@ internal class WindowsDriver : ConsoleDriver
             {
                 _point = null;
             }
+            _processButtonClick = true;
+
         }
         else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved
                  && !_isOneFingerDoubleClicked

+ 22 - 0
Terminal.Gui/Drawing/Color.cs

@@ -6,6 +6,7 @@ using System.Numerics;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Text.Json.Serialization;
+using ColorHelper;
 
 namespace Terminal.Gui;
 
@@ -237,6 +238,27 @@ public readonly partial record struct Color : ISpanParsable<Color>, IUtf8SpanPar
     [SkipLocalsInit]
     private static float CalculateColorDistance (in Vector4 color1, in Vector4 color2) { return Vector4.Distance (color1, color2); }
 
+    /// <summary>
+    /// Gets a color that is the same hue as the current color, but with a different lightness.
+    /// </summary>
+    /// <returns></returns>
+    public Color GetHighlightColor ()
+    {
+        // TODO: This is a temporary implementation; just enough to show how it could work. 
+        var hsl = ColorHelper.ColorConverter.RgbToHsl(new RGB (R, G, B));
+
+        var amount = .7;
+        if (hsl.L <= 5)
+        {
+            return DarkGray;
+        }
+        hsl.L = (byte)(hsl.L * amount);
+
+        var rgb = ColorHelper.ColorConverter.HslToRgb (hsl);
+        return new (rgb.R, rgb.G, rgb.B);
+
+    }
+
     #region Legacy Color Names
 
     /// <summary>The black color.</summary>

+ 1 - 0
Terminal.Gui/Terminal.Gui.csproj

@@ -44,6 +44,7 @@
   <!-- Dependencies -->
   <!-- =================================================================== -->
   <ItemGroup>
+    <PackageReference Include="ColorHelper" Version="1.8.1" />
     <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
     <!-- Enable Nuget Source Link for github -->
     <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />

+ 10 - 1
Terminal.Gui/View/Adornment/Adornment.cs

@@ -201,6 +201,10 @@ public class Adornment : View
     /// <returns><see langword="true"/> if the specified Parent's SuperView-relative coordinates are within the Adornment's Thickness. </returns>
     public override bool Contains (int x, int y)
     {
+        if (Parent is null)
+        {
+            return false;
+        }
         Rectangle frame = Frame;
         frame.Offset (Parent.Frame.Location);
 
@@ -208,7 +212,7 @@ public class Adornment : View
     }
 
     /// <inheritdoc/>
-    protected internal override bool OnMouseEnter (MouseEvent mouseEvent)
+    protected internal override bool? OnMouseEnter (MouseEvent mouseEvent)
     {
         // Invert Normal
         if (Diagnostics.HasFlag (ViewDiagnosticFlags.MouseEnter) && ColorScheme != null)
@@ -239,6 +243,11 @@ public class Adornment : View
     /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
+        if (Parent is null)
+        {
+            return false;
+        }
+
         var args = new MouseEventEventArgs (mouseEvent);
 
         if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))

+ 59 - 1
Terminal.Gui/View/Adornment/Border.cs

@@ -56,6 +56,9 @@ public class Border : Adornment
         Parent = parent;
         Application.GrabbingMouse += Application_GrabbingMouse;
         Application.UnGrabbingMouse += Application_UnGrabbingMouse;
+
+        HighlightStyle |= HighlightStyle.Pressed;
+        Highlight += Border_Highlight;
     }
 
 #if SUBVIEW_BASED_BORDER
@@ -70,6 +73,14 @@ public class Border : Adornment
     /// <inheritdoc/>
     public override void BeginInit ()
     {
+#if HOVER
+        // TOOD: Hack - make Arragnement overidable
+        if ((Parent?.Arrangement & ViewArrangement.Movable) != 0)
+        {
+            HighlightStyle |= HighlightStyle.Hover;
+        }   
+#endif
+
         base.BeginInit ();
 
 #if SUBVIEW_BASED_BORDER
@@ -97,7 +108,7 @@ public class Border : Adornment
             LayoutStarted += OnLayoutStarted;
     }
 #endif
-}
+    }
 
 #if SUBVIEW_BASED_BORDER
     private void OnLayoutStarted (object sender, LayoutEventArgs e)
@@ -187,6 +198,51 @@ public class Border : Adornment
 
     #region Mouse Support
 
+    private Color? _savedForeColor;
+
+    private void Border_Highlight (object sender, HighlightEventArgs e)
+    {
+        if (!Parent.Arrangement.HasFlag (ViewArrangement.Movable))
+        {
+            return;
+        }
+
+        if (e.HighlightStyle.HasFlag (HighlightStyle.Pressed))
+        {
+            if (!_savedForeColor.HasValue)
+            {
+                _savedForeColor = ColorScheme.Normal.Foreground;
+            }
+
+            ColorScheme cs = new ColorScheme (ColorScheme)
+            {
+                Normal = new Attribute (ColorScheme.Normal.Foreground.GetHighlightColor (), ColorScheme.Normal.Background)
+            };
+            ColorScheme = cs;
+        }
+#if HOVER
+        else if (e.HighlightStyle.HasFlag (HighlightStyle.Hover))
+        {
+            if (!_savedHighlightLineStyle.HasValue)
+            {
+                _savedHighlightLineStyle = Parent?.BorderStyle ?? LineStyle;
+            }
+            LineStyle = LineStyle.Double;
+        }
+#endif
+
+        if (e.HighlightStyle == HighlightStyle.None && _savedForeColor.HasValue)
+        {
+            ColorScheme cs = new ColorScheme (ColorScheme)
+            {
+                Normal = new Attribute (_savedForeColor.Value, ColorScheme.Normal.Background)
+            };
+            ColorScheme = cs;
+        }
+        Parent?.SetNeedsDisplay ();
+        e.Cancel = true;
+    }
+
     private Point? _dragPosition;
     private Point _startGrabPoint;
 
@@ -222,6 +278,7 @@ public class Border : Adornment
                 _startGrabPoint = new (mouseEvent.X + Frame.X, mouseEvent.Y + Frame.Y);
                 _dragPosition = new (mouseEvent.X, mouseEvent.Y);
                 Application.GrabMouse (this);
+                SetHighlight (HighlightStyle);
             }
 
             return true;
@@ -265,6 +322,7 @@ public class Border : Adornment
         {
             _dragPosition = null;
             Application.UngrabMouse ();
+            SetHighlight (HighlightStyle.None);
 
             return true;
         }

+ 6 - 1
Terminal.Gui/View/Adornment/Padding.cs

@@ -52,13 +52,18 @@ public class Padding : Adornment
     /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
+        if (Parent is null)
+        {
+            return false;
+        }
+
         if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked))
         {
             if (Parent.CanFocus && !Parent.HasFocus)
             {
                 Parent.SetFocus ();
                 Parent.SetNeedsDisplay ();
-                return true;
+                return mouseEvent.Handled = true;
             }
         }
 

+ 4 - 1
Terminal.Gui/View/ViewAdornments.cs

@@ -99,7 +99,10 @@ public partial class View
 
             if (value != LineStyle.None)
             {
-                Border.Thickness = new (1);
+                if (Border.Thickness == Thickness.Empty)
+                {
+                    Border.Thickness = new (1);
+                }
             }
             else
             {

+ 9 - 2
Terminal.Gui/View/ViewDrawing.cs

@@ -524,12 +524,12 @@ public partial class View
             _needsDisplayRect = new (x, y, w, h);
         }
 
-        SuperView?.SetSubViewNeedsDisplay ();
-
         Margin?.SetNeedsDisplay ();
         Border?.SetNeedsDisplay ();
         Padding?.SetNeedsDisplay ();
 
+        SuperView?.SetSubViewNeedsDisplay ();
+
         foreach (View subview in Subviews)
         {
             if (subview.Frame.IntersectsWith (region))
@@ -550,6 +550,13 @@ public partial class View
         if (SuperView is { SubViewNeedsDisplay: false })
         {
             SuperView.SetSubViewNeedsDisplay ();
+
+            return;
+        }
+
+        if (this is Adornment adornment)
+        {
+            adornment.Parent?.SetSubViewNeedsDisplay ();
         }
     }
 

+ 485 - 52
Terminal.Gui/View/ViewMouse.cs

@@ -1,51 +1,160 @@
-namespace Terminal.Gui;
+using System.ComponentModel;
+
+namespace Terminal.Gui;
+
+/// <summary>
+/// Describes the highlight style of a view.
+/// </summary>
+[Flags]
+public enum HighlightStyle
+{
+    /// <summary>
+    /// No highlight.
+    /// </summary>
+    None = 0,
+
+#if HOVER
+    /// <summary>
+    /// The mouse is hovering over the view.
+    /// </summary>
+    Hover = 1,
+#endif
+
+    /// <summary>
+    /// The mouse is pressed within the <see cref="View.Bounds"/>.
+    /// </summary>
+    Pressed = 2,
+
+    /// <summary>
+    /// The mouse is pressed but moved outside the <see cref="View.Bounds"/>.
+    /// </summary>
+    PressedOutside = 4
+}
+
+/// <summary>
+/// Event arguments for the <see cref="View.Highlight"/> event.
+/// </summary>
+public class HighlightEventArgs : CancelEventArgs
+{
+    public HighlightEventArgs (HighlightStyle style)
+    {
+        HighlightStyle = style;
+    }
+
+    /// <summary>
+    /// The highlight style.
+    /// </summary>
+    public HighlightStyle HighlightStyle { get; }
+}
 
 public partial class View
 {
-    /// <summary>Gets or sets a value indicating whether this <see cref="View"/> want continuous button pressed event.</summary>
+    /// <summary>
+    ///     Gets or sets whether the <see cref="View"/> will be highlighted visually while the mouse button is
+    ///     pressed.
+    /// </summary>
+    public HighlightStyle HighlightStyle { get; set; }
+
+    /// <summary>Gets or sets whether the <see cref="View"/> wants continuous button pressed events.</summary>
     public virtual bool WantContinuousButtonPressed { get; set; }
 
-    /// <summary>Gets or sets a value indicating whether this <see cref="View"/> wants mouse position reports.</summary>
-    /// <value><see langword="true"/> if want mouse position reports; otherwise, <see langword="false"/>.</value>
+    /// <summary>Gets or sets whether the <see cref="View"/> wants mouse position reports.</summary>
+    /// <value><see langword="true"/> if mouse position reports are wanted; otherwise, <see langword="false"/>.</value>
     public virtual bool WantMousePositionReports { get; set; }
 
-    /// <summary>Event fired when a mouse event occurs.</summary>
+    /// <summary>
+    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse enters <see cref="Bounds"/>. The view will
+    ///     then receive mouse events until <see cref="NewMouseLeaveEvent"/> is called indicating the mouse has left
+    ///     the view.
+    /// </summary>
     /// <remarks>
-    /// <para>
-    /// The coordinates are relative to <see cref="View.Bounds"/>.
-    /// </para>
+    ///     <para>
+    ///         A view must be both enabled and visible to receive mouse events.
+    ///     </para>
+    ///     <para>
+    ///         This method calls <see cref="OnMouseEnter"/> to fire the event.
+    ///     </para>
+    ///     <para>
+    ///         See <see cref="SetHighlight"/> for more information.
+    ///     </para>
     /// </remarks>
-    public event EventHandler<MouseEventEventArgs> MouseEvent;
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/> if the event was handled, <see langword="false"/> otherwise.</returns>
+    internal bool? NewMouseEnterEvent (MouseEvent mouseEvent)
+    {
+        if (!Enabled)
+        {
+            return true;
+        }
 
-    /// <summary>Event fired when a mouse click occurs.</summary>
+        if (!CanBeVisible (this))
+        {
+            return false;
+        }
+
+        if (OnMouseEnter (mouseEvent) == true)
+        {
+            return true;
+        }
+
+#if HOVER
+        if (HighlightStyle.HasFlag(HighlightStyle.Hover))
+        {
+            if (SetHighlight (HighlightStyle.Hover))
+            {
+                return true;
+            }
+        }
+#endif
+        return false;
+    }
+
+    /// <summary>
+    ///     Called by <see cref="NewMouseEvent"/> when the mouse enters <see cref="Bounds"/>. The view will
+    ///     then receive mouse events until <see cref="OnMouseLeave"/> is called indicating the mouse has left
+    ///     the view.
+    /// </summary>
     /// <remarks>
     /// <para>
-    /// Fired when the mouse is either clicked or double-clicked. Check
-    /// <see cref="MouseEvent.Flags"/> to see which button was clicked.
+    /// Override this method or subscribe to <see cref="MouseEnter"/> to change the default enter behavior.
     /// </para>
     /// <para>
-    /// The coordinates are relative to <see cref="View.Bounds"/>.
+    ///     The coordinates are relative to <see cref="View.Bounds"/>.
     /// </para>
     /// </remarks>
-    public event EventHandler<MouseEventEventArgs> MouseClick;
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    protected internal virtual bool? OnMouseEnter (MouseEvent mouseEvent)
+    {
+
+        var args = new MouseEventEventArgs (mouseEvent);
+        MouseEnter?.Invoke (this, args);
+
+        return args.Handled;
+    }
 
     /// <summary>Event fired when the mouse moves into the View's <see cref="Bounds"/>.</summary>
     public event EventHandler<MouseEventEventArgs> MouseEnter;
 
-    /// <summary>Event fired when the mouse leaves the View's <see cref="Bounds"/>.</summary>
-    public event EventHandler<MouseEventEventArgs> MouseLeave;
 
-    // TODO: OnMouseEnter should not be public virtual, but protected.
     /// <summary>
-    ///     Called when the mouse enters the View's <see cref="Bounds"/>. The view will now receive mouse events until the mouse leaves
-    ///     the view. At which time, <see cref="OnMouseLeave(Gui.MouseEvent)"/> will be called.
+    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse leaves <see cref="Bounds"/>. The view will
+    ///     then no longer receive mouse events.
     /// </summary>
     /// <remarks>
-    /// The coordinates are relative to <see cref="View.Bounds"/>.
+    ///     <para>
+    ///         A view must be both enabled and visible to receive mouse events.
+    ///     </para>
+    ///     <para>
+    ///         This method calls <see cref="OnMouseLeave"/> to fire the event.
+    ///     </para>
+    ///     <para>
+    ///         See <see cref="SetHighlight"/> for more information.
+    ///     </para>
     /// </remarks>
     /// <param name="mouseEvent"></param>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    protected internal virtual bool OnMouseEnter (MouseEvent mouseEvent)
+    /// <returns><see langword="true"/> if the event was handled, <see langword="false"/> otherwise.</returns>
+    internal bool? NewMouseLeaveEvent (MouseEvent mouseEvent)
     {
         if (!Enabled)
         {
@@ -57,19 +166,30 @@ public partial class View
             return false;
         }
 
-        var args = new MouseEventEventArgs (mouseEvent);
-        MouseEnter?.Invoke (this, args);
+        if (OnMouseLeave (mouseEvent) == true)      
+        {
+            return true;
+        }
+#if HOVER
+        if (HighlightStyle.HasFlag (HighlightStyle.Hover))
+        {
+            SetHighlight (HighlightStyle.None);
+        }
+#endif
 
-        return args.Handled;
+        return false;
     }
-
-    // TODO: OnMouseLeave should not be public virtual, but protected.
     /// <summary>
-    ///     Called when the mouse has moved out of the View's <see cref="Bounds"/>. The view will no longer receive mouse events (until the
-    ///     mouse moves within the view again and <see cref="OnMouseEnter(Gui.MouseEvent)"/> is called).
+    ///     Called by <see cref="NewMouseEvent"/> when a mouse leaves <see cref="Bounds"/>. The view will
+    ///     no longer receive mouse events.
     /// </summary>
     /// <remarks>
-    /// The coordinates are relative to <see cref="View.Bounds"/>.
+    /// <para>
+    /// Override this method or subscribe to <see cref="MouseEnter"/> to change the default leave behavior.
+    /// </para>
+    /// <para>
+    ///     The coordinates are relative to <see cref="View.Bounds"/>.
+    /// </para>
     /// </remarks>
     /// <param name="mouseEvent"></param>
     /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
@@ -91,20 +211,37 @@ public partial class View
         return args.Handled;
     }
 
-    // TODO: OnMouseEvent should not be public virtual, but protected.
-    /// <summary>Called when a mouse event occurs within the view's <see cref="Bounds"/>.</summary>
+    /// <summary>Event fired when the mouse leaves the View's <see cref="Bounds"/>.</summary>
+    public event EventHandler<MouseEventEventArgs> MouseLeave;
+
+    /// <summary>
+    ///     Processes a <see cref="MouseEvent"/>. This method is called by <see cref="Application.OnMouseEvent"/> when a mouse
+    ///     event occurs.
+    /// </summary>
     /// <remarks>
-    /// <para>
-    /// The coordinates are relative to <see cref="View.Bounds"/>.
-    /// </para>
+    ///     <para>
+    ///         A view must be both enabled and visible to receive mouse events.
+    ///     </para>
+    ///     <para>
+    ///         This method calls <see cref="OnMouseEvent"/> to process the event. If the event is not handled, and one of the
+    ///         mouse buttons was clicked, it calls <see cref="OnMouseClick"/> to process the click.
+    ///     </para>
+    ///     <para>
+    ///         See <see cref="SetHighlight"/> and <see cref="DisableHighlight"/> for more information.
+    ///     </para>
+    ///     <para>
+    ///         If <see cref="WantContinuousButtonPressed"/> is <see langword="true"/>, the <see cref="OnMouseClick"/> event
+    ///         will be invoked repeatedly while the button is pressed.
+    ///     </para>
     /// </remarks>
     /// <param name="mouseEvent"></param>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    protected internal virtual bool OnMouseEvent (MouseEvent mouseEvent)
+    /// <returns><see langword="true"/> if the event was handled, <see langword="false"/> otherwise.</returns>
+    public bool? NewMouseEvent (MouseEvent mouseEvent)
     {
         if (!Enabled)
         {
-            return true;
+            // A disabled view should not eat mouse events
+            return false;
         }
 
         if (!CanBeVisible (this))
@@ -112,45 +249,328 @@ public partial class View
             return false;
         }
 
-        var args = new MouseEventEventArgs (mouseEvent);
+        if (OnMouseEvent (mouseEvent))
+        {
+            // Technically mouseEvent.Handled should already be true if implementers of OnMouseEvent
+            // follow the rules. But we'll update it just in case.
+            return mouseEvent.Handled = true;
+        }
+
+        if (HighlightStyle != Gui.HighlightStyle.None || WantContinuousButtonPressed)
+        {
+            if (HandlePressed (mouseEvent))
+            {
+                return mouseEvent.Handled;
+            }
+
+            if (HandleReleased (mouseEvent))
+            {
+                return mouseEvent.Handled;
+            }
+
+            if (HandleClicked (mouseEvent))
+            {
+                return mouseEvent.Handled;
+            }
+        }
 
-        // Clicked support for all buttons and single and double click
         if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)
             || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked)
             || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked))
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button2DoubleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button3DoubleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button4DoubleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button1TripleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button2TripleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button3TripleClicked)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button4TripleClicked)
+           )
         {
-            return OnMouseClick (args);
+            // If it's a click, and we didn't handle it, then we'll call OnMouseClick
+            // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and
+            // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked
+            return OnMouseClick (new (mouseEvent));
         }
 
-        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button2DoubleClicked)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button3DoubleClicked)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button4DoubleClicked))
+        return false;
+    }
+
+    /// <summary>
+    ///     For cases where the view is grabbed and the mouse is clicked, this method handles the released event (typically
+    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         Marked internal just to support unit tests
+    ///     </para>
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    private bool HandlePressed (MouseEvent mouseEvent)
+    {
+        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed))
         {
-            return OnMouseClick (args);
+            // The first time we get pressed event, grab the mouse and set focus
+            if (Application.MouseGrabView != this)
+            {
+                Application.GrabMouse (this);
+
+                if (CanFocus)
+                {
+                    // Set the focus, but don't invoke Accept
+                    SetFocus ();
+                }
+            }
+
+            if (Bounds.Contains (mouseEvent.X, mouseEvent.Y))
+            {
+                if (SetHighlight (HighlightStyle.HasFlag (HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None) == true)
+                {
+                    return true;
+                }
+            }
+            else
+            {
+                if (SetHighlight (HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None) == true)
+
+                {
+                    return true;
+                }
+            }
+
+            if (WantContinuousButtonPressed && Application.MouseGrabView == this)
+            {
+                // If this is not the first pressed event, click
+                return OnMouseClick (new (mouseEvent));
+            }
+
+            return mouseEvent.Handled = true;
         }
 
+        return false;
+    }
+
+    /// <summary>
+    ///     For cases where the view is grabbed and the mouse is clicked, this method handles the released event (typically
+    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
+    /// </summary>
+    /// <remarks>
+    ///     Marked internal just to support unit tests
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    internal bool HandleReleased (MouseEvent mouseEvent)
+    {
+        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button2Released)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button3Released)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button4Released))
+        {
+            if (Application.MouseGrabView == this)
+            {
+                SetHighlight (HighlightStyle.None);
+            }
+
+            return mouseEvent.Handled = true;
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    ///     For cases where the view is grabbed and the mouse is clicked, this method handles the click event (typically
+    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
+    /// </summary>
+    /// <remarks>
+    ///     Marked internal just to support unit tests
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    internal bool HandleClicked (MouseEvent mouseEvent)
+    {
+        if (Application.MouseGrabView == this
+            && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)
+                || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked)
+                || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)
+                || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked)))
+        {
+            // We're grabbed. Clicked event comes after the last Release. This is our signal to ungrab
+            Application.UngrabMouse ();
+
+            if (SetHighlight (HighlightStyle.None))
+            {
+                return true;
+            }
+
+            // If mouse is still in bounds, click
+            if (!WantContinuousButtonPressed && Bounds.Contains (mouseEvent.X, mouseEvent.Y))
+            {
+                return OnMouseClick (new (mouseEvent));
+            }
+
+            return mouseEvent.Handled = true;
+        }
+
+        return false;
+    }
+
+    [CanBeNull]
+    private ColorScheme _savedHighlightColorScheme;
+
+    /// <summary>
+    ///     Enables the highlight for the view when the mouse is pressed. Called from OnMouseEvent.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         Set <see cref="HighlightStyle"/> to have the view highlighted based on the mouse.
+    ///     </para>
+    ///     <para>
+    ///         Calls <see cref="OnHighlight"/> which fires the <see cref="Highlight"/> event.
+    ///     </para>
+    ///     <para>
+    ///         Marked internal just to support unit tests
+    ///     </para>
+    /// </remarks>
+    /// <returns><see langword="true"/>, if the Highlight event was handled, <see langword="false"/> otherwise.</returns>
+
+    internal bool SetHighlight (HighlightStyle style)
+    {
+        // TODO: Make the highlight colors configurable
+
+        // Enable override via virtual method and/or event
+        if (OnHighlight (style) == true)
+        {
+            return true;
+        }
+#if HOVER
+        if (style.HasFlag (HighlightStyle.Hover))
+        {
+            if (_savedHighlightColorScheme is null && ColorScheme is { })
+            {
+                _savedHighlightColorScheme ??= ColorScheme;
+
+                var cs = new ColorScheme (ColorScheme)
+                {
+                    Normal = GetFocusColor (),
+                    HotNormal = ColorScheme.HotFocus
+                };
+                ColorScheme = cs;
+            }
+
+            return true;
+        }
+#endif 
+        if (style.HasFlag (HighlightStyle.Pressed) || style.HasFlag (HighlightStyle.PressedOutside))
+        {
+            if (_savedHighlightColorScheme is null && ColorScheme is { })
+            {
+                _savedHighlightColorScheme ??= ColorScheme;
+
+                if (CanFocus)
+                {
+                    var cs = new ColorScheme (ColorScheme)
+                    {
+                        // Highlight the foreground focus color
+                        Focus = new (ColorScheme.Focus.Foreground.GetHighlightColor (), ColorScheme.Focus.Background.GetHighlightColor ()),
+                    };
+                    ColorScheme = cs;
+                }
+                else
+                {
+                    var cs = new ColorScheme (ColorScheme)
+                    {
+                        // Invert Focus color foreground/background. We can do this because we know the view is not going to be focused.
+                        Normal = new (ColorScheme.Focus.Background, ColorScheme.Normal.Foreground)
+                    };
+                    ColorScheme = cs;
+                }
+
+                return true;
+            }
+        }
+
+
+        if (style == HighlightStyle.None)
+        {
+            // Unhighlight
+            if (_savedHighlightColorScheme is { })
+            {
+                ColorScheme = _savedHighlightColorScheme;
+                _savedHighlightColorScheme = null;
+            }
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    ///     Fired when the view is highlighted. Set <see cref="CancelEventArgs.Cancel"/> to <see langword="true"/>
+    ///     to implement a custom highlight scheme or prevent the view from being highlighted.
+    /// </summary>
+    public event EventHandler<HighlightEventArgs> Highlight;
+
+    /// <summary>
+    ///     Called when the view is to be highlighted.
+    /// </summary>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    protected virtual bool? OnHighlight (HighlightStyle highlight)
+    {
+        HighlightEventArgs args = new (highlight);
+        Highlight?.Invoke (this, args);
+
+        return args.Cancel;
+    }
+
+    /// <summary>Called when a mouse event occurs within the view's <see cref="Bounds"/>.</summary>
+    /// <remarks>
+    ///     <para>
+    ///         The coordinates are relative to <see cref="View.Bounds"/>.
+    ///     </para>
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    protected internal virtual bool OnMouseEvent (MouseEvent mouseEvent)
+    {
+        var args = new MouseEventEventArgs (mouseEvent);
+
         MouseEvent?.Invoke (this, args);
 
-        return args.Handled == true;
+        return args.Handled;
     }
 
+    /// <summary>Event fired when a mouse event occurs.</summary>
+    /// <remarks>
+    ///     <para>
+    ///         The coordinates are relative to <see cref="View.Bounds"/>.
+    ///     </para>
+    /// </remarks>
+    public event EventHandler<MouseEventEventArgs> MouseEvent;
+
     /// <summary>Invokes the MouseClick event.</summary>
     /// <remarks>
-    /// <para>
-    /// Called when the mouse is either clicked or double-clicked. Check
-    /// <see cref="MouseEvent.Flags"/> to see which button was clicked.
-    /// </para>
+    ///     <para>
+    ///         Called when the mouse is either clicked or double-clicked. Check
+    ///         <see cref="MouseEvent.Flags"/> to see which button was clicked.
+    ///     </para>
     /// </remarks>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
     protected bool OnMouseClick (MouseEventEventArgs args)
     {
         if (!Enabled)
         {
+            // QUESTION: Is this right? Should a disabled view eat mouse clicks?
+            args.Handled = true;
+
             return true;
         }
 
         MouseClick?.Invoke (this, args);
+
         if (args.Handled)
         {
             return true;
@@ -158,9 +578,22 @@ public partial class View
 
         if (!HasFocus && CanFocus)
         {
+            args.Handled = true;
             SetFocus ();
         }
 
         return args.Handled;
     }
+
+    /// <summary>Event fired when a mouse click occurs.</summary>
+    /// <remarks>
+    ///     <para>
+    ///         Fired when the mouse is either clicked or double-clicked. Check
+    ///         <see cref="MouseEvent.Flags"/> to see which button was clicked.
+    ///     </para>
+    ///     <para>
+    ///         The coordinates are relative to <see cref="View.Bounds"/>.
+    ///     </para>
+    /// </remarks>
+    public event EventHandler<MouseEventEventArgs> MouseClick;
 }

+ 19 - 2
Terminal.Gui/View/ViewSubViews.cs

@@ -31,8 +31,14 @@ public partial class View
 
     /// <summary>Adds a subview (child) to this view.</summary>
     /// <remarks>
+    /// <para>
     ///     The Views that have been added to this view can be retrieved via the <see cref="Subviews"/> property. See also
     ///     <seealso cref="Remove(View)"/> <seealso cref="RemoveAll"/>
+    /// </para>
+    /// <para>
+    ///     Subviews will be disposed when this View is disposed. In other-words, calling this method causes
+    ///     the lifecycle of the subviews to be transferred to this View.
+    /// </para>
     /// </remarks>
     public virtual void Add (View view)
     {
@@ -92,8 +98,14 @@ public partial class View
     /// <summary>Adds the specified views (children) to the view.</summary>
     /// <param name="views">Array of one or more views (can be optional parameter).</param>
     /// <remarks>
+    /// <para>
     ///     The Views that have been added to this view can be retrieved via the <see cref="Subviews"/> property. See also
-    ///     <seealso cref="Remove(View)"/> <seealso cref="RemoveAll"/>
+    ///     <seealso cref="Remove(View)"/> and <seealso cref="RemoveAll"/>.
+    /// </para>
+    /// <para>
+    ///     Subviews will be disposed when this View is disposed. In other-words, calling this method causes
+    ///     the lifecycle of the subviews to be transferred to this View.
+    /// </para>
     /// </remarks>
     public void Add (params View [] views)
     {
@@ -185,7 +197,12 @@ public partial class View
     }
 
     /// <summary>Removes a subview added via <see cref="Add(View)"/> or <see cref="Add(View[])"/> from this View.</summary>
-    /// <remarks></remarks>
+    /// <remarks>
+    /// <para>
+    ///     Normally Subviews will be disposed when this View is disposed. Removing a Subview causes ownership of the Subview's
+    ///     lifecycle to be transferred to the caller; the caller muse call <see cref="Dispose"/>.
+    /// </para>
+    /// </remarks>
     public virtual void Remove (View view)
     {
         if (view is null || _subviews is null)

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

@@ -20,6 +20,10 @@ namespace Terminal.Gui;
 ///         no other <see cref="View"/> processes the key, the <see cref="Button"/>'s <see cref="View.Accept"/> event will
 ///         be fired.
 ///     </para>
+///     <para>
+///         Set <see cref="View.WantContinuousButtonPressed"/> to <see langword="true"/> to have the <see cref="View.Accept"/> event
+///         invoked repeatedly while the button is pressed.
+///     </para>
 /// </remarks>
 public class Button : View
 {
@@ -29,6 +33,9 @@ public class Button : View
     private readonly Rune _rightDefault;
     private bool _isDefault;
 
+    /// <inheritdoc />
+    private bool _wantContinuousButtonPressed;
+
     /// <summary>Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Computed"/> layout.</summary>
     /// <remarks>The width of the <see cref="Button"/> is computed based on the text length. The height will always be 1.</remarks>
     public Button ()
@@ -46,7 +53,10 @@ public class Button : View
 
         CanFocus = true;
         AutoSize = true;
-
+        HighlightStyle |= HighlightStyle.Pressed;
+#if HOVER
+        HighlightStyle |= HighlightStyle.Hover;
+#endif
         // Override default behavior of View
         AddCommand (Command.HotKey, () =>
                                      {
@@ -61,6 +71,30 @@ public class Button : View
         MouseClick += Button_MouseClick;
     }
 
+    /// <inheritdoc />
+    public override bool WantContinuousButtonPressed
+    {
+        get => _wantContinuousButtonPressed;
+        set
+        {
+            if (value == _wantContinuousButtonPressed)
+            {
+                return;
+            }
+
+            _wantContinuousButtonPressed = value;
+
+            if (_wantContinuousButtonPressed)
+            {
+                HighlightStyle |= HighlightStyle.PressedOutside;
+            }
+            else
+            {
+                HighlightStyle &= ~HighlightStyle.PressedOutside;
+            }
+        }
+    }
+
     private void Button_MouseClick (object sender, MouseEventEventArgs e)
     {
         e.Handled = InvokeCommand (Command.HotKey) == true;

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

@@ -35,6 +35,7 @@ public class CheckBox : View
 
         TitleChanged += Checkbox_TitleChanged;
 
+        HighlightStyle = Gui.HighlightStyle.PressedOutside | Gui.HighlightStyle.Pressed;
         MouseClick += CheckBox_MouseClick;
     }
 

+ 55 - 45
Terminal.Gui/Views/ColorPicker.cs

@@ -29,6 +29,49 @@ public class ColorPicker : View
     /// <summary>Initializes a new instance of <see cref="ColorPicker"/>.</summary>
     public ColorPicker () { SetInitialProperties (); }
 
+    private void SetInitialProperties ()
+    {
+        HighlightStyle = Gui.HighlightStyle.PressedOutside | Gui.HighlightStyle.Pressed;
+
+        CanFocus = true;
+        AddCommands ();
+        AddKeyBindings ();
+
+        LayoutStarted += (o, a) =>
+                         {
+                             Thickness thickness = GetAdornmentsThickness ();
+                             Width = _cols * BoxWidth + thickness.Vertical;
+                             Height = _rows * BoxHeight + thickness.Horizontal;
+                         };
+//        MouseEvent += ColorPicker_MouseEvent;
+        MouseClick += ColorPicker_MouseClick;
+    }
+
+    // TODO: Decouple Cursor from SelectedColor so that mouse press-and-hold can show the color under the cursor.
+    //private void ColorPicker_MouseEvent (object sender, MouseEventEventArgs me)
+    //{
+    //    if (me.MouseEvent.X > Bounds.Width || me.MouseEvent.Y > Bounds.Height)
+    //    {
+    //        me.Handled = true;
+
+    //        return;
+    //    }
+
+    //    me.Handled = true;
+
+    //    return;
+    //}
+
+    private void ColorPicker_MouseClick (object sender, MouseEventEventArgs me)
+    {
+        if (CanFocus)
+        {
+            Cursor = new Point (me.MouseEvent.X / _boxWidth, me.MouseEvent.Y / _boxHeight);
+            SetFocus ();
+            me.Handled = true;
+        }
+    }
+
     /// <summary>Height of a color box</summary>
     public int BoxHeight
     {
@@ -88,37 +131,6 @@ public class ColorPicker : View
     /// <summary>Fired when a color is picked.</summary>
     public event EventHandler<ColorEventArgs> ColorChanged;
 
-    ///<inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent me)
-    {
-        if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) || !CanFocus)
-        {
-            return false;
-        }
-
-        SetFocus ();
-
-        if (me.X > Bounds.Width || me.Y > Bounds.Height)
-        {
-            return true;
-        }
-
-        Cursor = new Point (me.X / _boxWidth, me.Y / _boxHeight);
-
-        return true;
-    }
-
-    /// <summary>Moves the selected item index to the next row.</summary>
-    /// <returns></returns>
-    public virtual bool MoveDown ()
-    {
-        if (Cursor.Y < _rows - 1)
-        {
-            SelectedColor += _cols;
-        }
-
-        return true;
-    }
 
     /// <summary>Moves the selected item index to the previous column.</summary>
     /// <returns></returns>
@@ -156,6 +168,18 @@ public class ColorPicker : View
         return true;
     }
 
+    /// <summary>Moves the selected item index to the next row.</summary>
+    /// <returns></returns>
+    public virtual bool MoveDown ()
+    {
+        if (Cursor.Y < _rows - 1)
+        {
+            SelectedColor += _cols;
+        }
+
+        return true;
+    }
+
     ///<inheritdoc/>
     public override void OnDrawContent (Rectangle contentArea)
     {
@@ -265,18 +289,4 @@ public class ColorPicker : View
             AddRune (p.Key.X, p.Key.Y, p.Value);
         }
     }
-
-    private void SetInitialProperties ()
-    {
-        CanFocus = true;
-        AddCommands ();
-        AddKeyBindings ();
-
-        LayoutStarted += (o, a) =>
-                         {
-                             Thickness thickness = GetAdornmentsThickness ();
-                             Width = _cols * BoxWidth + thickness.Vertical;
-                             Height = _rows * BoxHeight + thickness.Horizontal;
-                         };
-    }
 }

+ 2 - 2
Terminal.Gui/Views/ComboBox.cs

@@ -264,7 +264,7 @@ public class ComboBox : View
                 FocusSelectedItem ();
             }
 
-            return true;
+            return me.Handled = true;
         }
 
         if (me.Flags == MouseFlags.Button1Pressed)
@@ -274,7 +274,7 @@ public class ComboBox : View
                 _search.SetFocus ();
             }
 
-            return true;
+            return me.Handled = true;
         }
 
         return false;

+ 11 - 5
Terminal.Gui/Views/DatePicker.cs

@@ -215,11 +215,14 @@ public class DatePicker : View
         _previousMonthButton = new Button
         {
             AutoSize = false,
-            X = Pos.Center () - 4,
+            X = Pos.Center () - 2,
             Y = Pos.Bottom (_calendar) - 1,
             Height = 1,
-            Width = CalculateCalendarWidth () / 2,
-            Text = GetBackButtonText ()
+            Width = 2,
+            Text = GetBackButtonText (),
+            WantContinuousButtonPressed = true,
+            NoPadding = true,
+            NoDecorations = true
         };
 
         _previousMonthButton.Accept += (sender, e) =>
@@ -235,8 +238,11 @@ public class DatePicker : View
             X = Pos.Right (_previousMonthButton) + 2,
             Y = Pos.Bottom (_calendar) - 1,
             Height = 1,
-            Width = CalculateCalendarWidth () / 2,
-            Text = GetBackButtonText ()
+            Width = 2,
+            Text = GetForwardButtonText(),
+            WantContinuousButtonPressed = true,
+            NoPadding = true,
+            NoDecorations = true
         };
 
         _nextMonthButton.Accept += (sender, e) =>

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

@@ -712,9 +712,9 @@ internal sealed class Menu : View
         }
     }
 
-    private void Application_RootMouseEvent (object sender, MouseEventEventArgs a)
+    private void Application_RootMouseEvent (object sender, MouseEvent a)
     {
-        if (a.MouseEvent.View is { } and (MenuBar or not Menu))
+        if (a.View is { } and (MenuBar or not Menu))
         {
             return;
         }
@@ -724,21 +724,21 @@ internal sealed class Menu : View
             throw new InvalidOperationException ("This shouldn't running on a invisible menu!");
         }
 
-        View view = a.MouseEvent.View ?? this;
+        View view = a.View ?? this;
 
-        Point boundsPoint = view.ScreenToBounds (a.MouseEvent.X, a.MouseEvent.Y);
+        Point boundsPoint = view.ScreenToBounds (a.X, a.Y);
         var me = new MouseEvent
         {
             X = boundsPoint.X,
             Y = boundsPoint.Y,
-            Flags = a.MouseEvent.Flags,
-            ScreenPosition = new (a.MouseEvent.X, a.MouseEvent.Y),
+            Flags = a.Flags,
+            ScreenPosition = new (a.X, a.Y),
             View = view
         };
 
-        if (view.OnMouseEvent (me) || a.MouseEvent.Flags == MouseFlags.Button1Pressed || a.MouseEvent.Flags == MouseFlags.Button1Released)
+        if (view.NewMouseEvent (me) == true || a.Flags == MouseFlags.Button1Pressed || a.Flags == MouseFlags.Button1Released)
         {
-            a.MouseEvent.Handled = true;
+            a.Handled = true;
         }
     }
 
@@ -1189,12 +1189,12 @@ internal sealed class Menu : View
 
             if (me.Y < 0)
             {
-                return true;
+                return me.Handled = true;
             }
 
             if (me.Y >= _barItems.Children.Length)
             {
-                return true;
+                return me.Handled = true;
             }
 
             MenuItem item = _barItems.Children [me.Y];
@@ -1206,13 +1206,13 @@ internal sealed class Menu : View
 
             if (disabled)
             {
-                return true;
+                return me.Handled = true;
             }
 
             _currentChild = me.Y;
             RunSelected ();
 
-            return true;
+            return me.Handled = true;
         }
 
         if (me.Flags != MouseFlags.Button1Pressed
@@ -1229,14 +1229,14 @@ internal sealed class Menu : View
 
             if (me.Y < 0 || me.Y >= _barItems.Children.Length)
             {
-                return true;
+                return me.Handled = true;
             }
 
             MenuItem item = _barItems.Children [me.Y];
 
             if (item is null)
             {
-                return true;
+                return me.Handled = true;
             }
 
             if (item?.IsEnabled () != true)
@@ -1254,12 +1254,12 @@ internal sealed class Menu : View
                 SetNeedsDisplay ();
                 SetParentSetNeedsDisplay ();
 
-                return true;
+                return me.Handled = true;
             }
 
             _host.OnMenuOpened ();
 
-            return true;
+            return me.Handled = true;
         }
     }
 

+ 4 - 4
Terminal.Gui/Views/Menu/MenuBar.cs

@@ -1715,7 +1715,7 @@ public class MenuBar : View
                         {
                             if (!CloseMenu (true, false))
                             {
-                                return true;
+                                return me.Handled = true;
                             }
 
                             Activate (i);
@@ -1733,7 +1733,7 @@ public class MenuBar : View
                         }
                     }
 
-                    return true;
+                    return me.Handled = true;
                 }
 
                 if (i == Menus.Length - 1 && me.Flags == MouseFlags.Button1Clicked)
@@ -1742,7 +1742,7 @@ public class MenuBar : View
                     {
                         CloseAllMenus ();
 
-                        return true;
+                        return me.Handled = true;
                     }
                 }
 
@@ -1804,7 +1804,7 @@ public class MenuBar : View
                         nme = new () { X = me.X + current.Frame.X, Y = 0, Flags = me.Flags, View = v };
                     }
 
-                    v.OnMouseEvent (nme);
+                    v.NewMouseEvent (nme);
 
                     return false;
                 }

+ 59 - 60
Terminal.Gui/Views/MessageBox.cs

@@ -386,66 +386,6 @@ public static class MessageBox
         messageLabel.TextFormatter.MultiLine = !wrapMessage;
         d.Add (messageLabel);
 
-        d.Loaded += (s, e) =>
-                    {
-                        if (width != 0 || height != 0)
-                        {
-                            return;
-                        }
-
-                        // TODO: replace with Dim.Fit when implemented
-                        Rectangle maxBounds = d.SuperView?.Bounds ?? Application.Top.Bounds;
-
-                        Thickness adornmentsThickness = d.GetAdornmentsThickness ();
-
-                        if (wrapMessage)
-                        {
-                            messageLabel.TextFormatter.Size = new (
-                                                                   maxBounds.Size.Width
-                                                                   - adornmentsThickness.Horizontal,
-                                                                   maxBounds.Size.Height
-                                                                   - adornmentsThickness.Vertical
-                                                                  );
-                        }
-
-                        string msg = messageLabel.TextFormatter.Format ();
-                        Size messageSize = messageLabel.TextFormatter.FormatAndGetSize ();
-
-                        // Ensure the width fits the text + buttons
-                        int newWidth = Math.Max (
-                                                 width,
-                                                 Math.Max (
-                                                           messageSize.Width + adornmentsThickness.Horizontal,
-                                                           d.GetButtonsWidth () + d.Buttons.Length + adornmentsThickness.Horizontal
-                                                          )
-                                                );
-
-                        if (newWidth > d.Frame.Width)
-                        {
-                            d.Width = newWidth;
-                        }
-
-                        // Ensure height fits the text + vspace + buttons
-                        if (messageSize.Height == 0)
-                        {
-                            d.Height = Math.Max (height, 3 + adornmentsThickness.Vertical);
-                        }
-                        else
-                        {
-                            string lastLine = messageLabel.TextFormatter.GetLines () [^1];
-
-                            // INTENT: Instead of the check against \n or \r\n, how about just Environment.NewLine?
-                            d.Height = Math.Max (
-                                                 height,
-                                                 messageSize.Height
-                                                 + (lastLine.EndsWith ("\r\n") || lastLine.EndsWith ('\n') ? 1 : 2)
-                                                 + adornmentsThickness.Vertical
-                                                );
-                        }
-
-                        d.SetRelativeLayout (d.SuperView?.Frame ?? Application.Top.Frame);
-                    };
-
         // Setup actions
         Clicked = -1;
 
@@ -466,10 +406,69 @@ public static class MessageBox
             }
         }
 
+        d.Loaded += Dialog_Loaded;
+
         // Run the modal; do not shutdown the mainloop driver when done
         Application.Run (d);
         d.Dispose ();
 
         return Clicked;
+
+        void Dialog_Loaded (object s, EventArgs e)
+        {
+            if (width != 0 || height != 0)
+            {
+                return;
+            }
+
+            // TODO: replace with Dim.Fit when implemented
+            Rectangle maxBounds = d.SuperView?.Bounds ?? Application.Top.Bounds;
+
+            Thickness adornmentsThickness = d.GetAdornmentsThickness ();
+
+            if (wrapMessage)
+            {
+                messageLabel.TextFormatter.Size = new (
+                                                       maxBounds.Size.Width
+                                                       - adornmentsThickness.Horizontal,
+                                                       maxBounds.Size.Height
+                                                       - adornmentsThickness.Vertical);
+            }
+
+            string msg = messageLabel.TextFormatter.Format ();
+            Size messageSize = messageLabel.TextFormatter.FormatAndGetSize ();
+
+            // Ensure the width fits the text + buttons
+            int newWidth = Math.Max (
+                                     width,
+                                     Math.Max (
+                                               messageSize.Width + adornmentsThickness.Horizontal,
+                                               d.GetButtonsWidth () + d.Buttons.Length + adornmentsThickness.Horizontal));
+
+            if (newWidth > d.Frame.Width)
+            {
+                d.Width = newWidth;
+            }
+
+            // Ensure height fits the text + vspace + buttons
+            if (messageSize.Height == 0)
+            {
+                d.Height = Math.Max (height, 3 + adornmentsThickness.Vertical);
+            }
+            else
+            {
+                string lastLine = messageLabel.TextFormatter.GetLines () [^1];
+
+                // INTENT: Instead of the check against \n or \r\n, how about just Environment.NewLine?
+                d.Height = Math.Max (
+                                     height,
+                                     messageSize.Height
+                                     + (lastLine.EndsWith ("\r\n") || lastLine.EndsWith ('\n') ? 1 : 2)
+                                     + adornmentsThickness.Vertical);
+            }
+
+            d.SetRelativeLayout (d.SuperView?.Frame ?? Application.Top.Frame);
+            d.LayoutSubviews ();
+        }
     }
 }

+ 35 - 40
Terminal.Gui/Views/RadioGroup.cs

@@ -76,6 +76,41 @@ public class RadioGroup : View
         KeyBindings.Add (Key.Space, Command.Accept);
 
         LayoutStarted += RadioGroup_LayoutStarted;
+
+        HighlightStyle = Gui.HighlightStyle.PressedOutside | Gui.HighlightStyle.Pressed;
+
+        MouseClick += RadioGroup_MouseClick;
+    }
+
+    // TODO: Fix InvertColorsOnPress - only highlight the selected item
+
+    private void RadioGroup_MouseClick (object sender, MouseEventEventArgs e)
+    {
+        SetFocus ();
+
+        int boundsX = e.MouseEvent.X;
+        int boundsY = e.MouseEvent.Y;
+
+        int pos = _orientation == Orientation.Horizontal ? boundsX : boundsY;
+
+        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 <= boundsX && x.pos + x.length - 2 >= boundsX)
+                        : boundsY;
+
+            if (c > -1)
+            {
+                _cursor = SelectedItem = c;
+                SetNeedsDisplay ();
+            }
+        }
+
+        e.Handled = true;
     }
 
     /// <summary>
@@ -160,46 +195,6 @@ public class RadioGroup : View
         }
     }
 
-    /// <inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent me)
-    {
-        if (!me.Flags.HasFlag (MouseFlags.Button1Clicked))
-        {
-            return false;
-        }
-
-        if (!CanFocus)
-        {
-            return false;
-        }
-
-        SetFocus ();
-
-        int boundsX = me.X;
-        int boundsY = me.Y;
-
-        int pos = _orientation == Orientation.Horizontal ? boundsX : boundsY;
-
-        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 <= boundsX && x.pos + x.length - 2 >= boundsX)
-                        : boundsY;
-
-            if (c > -1)
-            {
-                _cursor = SelectedItem = c;
-                SetNeedsDisplay ();
-            }
-        }
-
-        return true;
-    }
-
     /// <inheritdoc/>
     public override void OnDrawContent (Rectangle contentArea)
     {

+ 2 - 2
Terminal.Gui/Views/ScrollBarView.cs

@@ -325,7 +325,7 @@ public class ScrollBarView : View
                 || mouseEvent.Flags == MouseFlags.WheeledRight
                 || mouseEvent.Flags == MouseFlags.WheeledLeft))
         {
-            return Host.OnMouseEvent (mouseEvent);
+            return Host.NewMouseEvent (mouseEvent) == true;
         }
 
         if (mouseEvent.Flags == MouseFlags.Button1Pressed && location == 0)
@@ -800,7 +800,7 @@ public class ScrollBarView : View
             || me.MouseEvent.Flags == MouseFlags.WheeledRight
             || me.MouseEvent.Flags == MouseFlags.WheeledLeft)
         {
-            OnMouseEvent (me.MouseEvent);
+            NewMouseEvent (me.MouseEvent);
         }
         else if (me.MouseEvent.Flags == MouseFlags.Button1Clicked)
         {

+ 8 - 2
Terminal.Gui/Views/ScrollView.cs

@@ -410,6 +410,12 @@ public class ScrollView : View
     /// <inheritdoc/>
     protected internal override bool OnMouseEvent  (MouseEvent me)
     {
+        if (!Enabled)
+        {
+            // A disabled view should not eat mouse events
+            return false;
+        }
+
         if (me.Flags == MouseFlags.WheeledDown && ShowVerticalScrollIndicator)
         {
             ScrollDown (1);
@@ -428,11 +434,11 @@ public class ScrollView : View
         }
         else if (me.X == _vertical.Frame.X && ShowVerticalScrollIndicator)
         {
-            _vertical.OnMouseEvent (me);
+            _vertical.NewMouseEvent (me);
         }
         else if (me.Y == _horizontal.Frame.Y && ShowHorizontalScrollIndicator)
         {
-            _horizontal.OnMouseEvent (me);
+            _horizontal.NewMouseEvent (me);
         }
         else if (IsOverridden (me.View, "OnMouseEvent"))
         {

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

@@ -533,7 +533,7 @@ public class TabView : View
         return Style.ShowTopLine ? 3 : 2;
     }
 
-    private void Tab_MouseClick (object sender, MouseEventEventArgs e) { e.Handled = _tabsBar.OnMouseEvent (e.MouseEvent); }
+    private void Tab_MouseClick (object sender, MouseEventEventArgs e) { e.Handled = _tabsBar.NewMouseEvent (e.MouseEvent) == true; }
 
     private void UnSetCurrentTabs ()
     {

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

@@ -444,7 +444,7 @@ public partial class Toplevel : View
     ///     perform tasks when the <see cref="Toplevel"/> has been laid out and focus has been set. changes.
     ///     <para>
     ///         A Ready event handler is a good place to finalize initialization after calling
-    ///         <see cref="Application.Run(Func{Exception, bool})"/> on this <see cref="Toplevel"/>.
+    ///         <see cref="Application.Run(Toplevel, Func{Exception, bool}, ConsoleDriver)"/> on this <see cref="Toplevel"/>.
     ///     </para>
     /// </summary>
     public event EventHandler Ready;

+ 1 - 1
UICatalog/Scenarios/ASCIICustomButton.cs

@@ -134,7 +134,7 @@ public class ASCIICustomButtonTest : Scenario
         }
 
         public event Action<ASCIICustomButton> PointerEnter;
-        private void This_MouseClick (object sender, MouseEventEventArgs obj) { OnMouseEvent (obj.MouseEvent); }
+        private void This_MouseClick (object sender, MouseEventEventArgs obj) { NewMouseEvent (obj.MouseEvent); }
     }
 
     public class ScrollViewTestWindow : Window

+ 1 - 1
UICatalog/Scenarios/Adornments.cs

@@ -85,7 +85,7 @@ public class Adornments : Scenario
         view.X = 36;
         view.Y = 0;
         view.Width = Dim.Percent (60);
-        view.Height = Dim.Percent (80);
+        view.Height = Dim.Percent (80); 
 
         editor.Initialized += (s, e) => { editor.ViewToEdit = view; };
 

+ 3 - 3
UICatalog/Scenarios/BasicColors.cs

@@ -85,10 +85,10 @@ public class BasicColors : Scenario
 
         Application.MouseEvent += (s, e) =>
                                   {
-                                      if (e.MouseEvent.View != null)
+                                      if (e.View != null)
                                       {
-                                          Color fore = e.MouseEvent.View.GetNormalColor ().Foreground;
-                                          Color back = e.MouseEvent.View.GetNormalColor ().Background;
+                                          Color fore = e.View.GetNormalColor ().Foreground;
+                                          Color back = e.View.GetNormalColor ().Background;
 
                                           lblForeground.Text =
                                               $"#{fore.R:X2}{fore.G:X2}{fore.B:X2} {fore.GetClosestNamedColor ()} ";

+ 172 - 64
UICatalog/Scenarios/Buttons.cs

@@ -9,21 +9,25 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Layout")]
 public class Buttons : Scenario
 {
-    public override void Setup ()
+    public override void Main ()
     {
+        Window main = new ()
+        {
+            Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+        };
         // Add a label & text field so we can demo IsDefault
         var editLabel = new Label { X = 0, Y = 0, TabStop = true, Text = "TextField (to demo IsDefault):" };
-        Win.Add (editLabel);
+        main.Add (editLabel);
 
         // Add a TextField using Absolute layout. 
         var edit = new TextField { X = 31, Width = 15, HotKey = Key.Y.WithAlt };
-        Win.Add (edit);
+        main.Add (edit);
 
         // This is the default button (IsDefault = true); if user presses ENTER in the TextField
         // the scenario will quit
         var defaultButton = new Button { X = Pos.Center (), Y = Pos.AnchorEnd (1), IsDefault = true, Text = "_Quit" };
         defaultButton.Accept += (s, e) => Application.RequestStop ();
-        Win.Add (defaultButton);
+        main.Add (defaultButton);
 
         var swapButton = new Button { X = 50, Text = "S_wap Default (Absolute Layout)" };
 
@@ -32,7 +36,7 @@ public class Buttons : Scenario
                                   defaultButton.IsDefault = !defaultButton.IsDefault;
                                   swapButton.IsDefault = !swapButton.IsDefault;
                               };
-        Win.Add (swapButton);
+        main.Add (swapButton);
 
         static void DoMessage (Button button, string txt)
         {
@@ -44,7 +48,7 @@ public class Buttons : Scenario
         }
 
         var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (editLabel) + 1, Text = "Color Buttons:" };
-        Win.Add (colorButtonsLabel);
+        main.Add (colorButtonsLabel);
 
         View prev = colorButtonsLabel;
 
@@ -57,13 +61,11 @@ public class Buttons : Scenario
             {
                 ColorScheme = colorScheme.Value,
                 X = Pos.Right (prev) + 2,
-
-                //X = x,
                 Y = Pos.Y (colorButtonsLabel),
                 Text = $"_{colorScheme.Key}"
             };
             DoMessage (colorButton, colorButton.Text);
-            Win.Add (colorButton);
+            main.Add (colorButton);
             prev = colorButton;
 
             // BUGBUG: AutoSize is true and the X doesn't change
@@ -72,7 +74,7 @@ public class Buttons : Scenario
 
         Button button;
 
-        Win.Add (
+        main.Add (
                  button = new Button
                  {
                      X = 2,
@@ -84,16 +86,16 @@ public class Buttons : Scenario
         DoMessage (button, button.Text);
 
         // Note the 'N' in 'Newline' will be the hotkey
-        Win.Add (
+        main.Add (
                  button = new Button { X = 2, Y = Pos.Bottom (button) + 1, Text = "a Newline\nin the button" }
                 );
         button.Accept += (s, e) => MessageBox.Query ("Message", "Question?", "Yes", "No");
 
         var textChanger = new Button { X = 2, Y = Pos.Bottom (button) + 1, Text = "Te_xt Changer" };
-        Win.Add (textChanger);
+        main.Add (textChanger);
         textChanger.Accept += (s, e) => textChanger.Text += "!";
 
-        Win.Add (
+        main.Add (
                  button = new Button
                  {
                      X = Pos.Right (textChanger) + 2,
@@ -106,13 +108,13 @@ public class Buttons : Scenario
         {
             X = 2, Y = Pos.Bottom (button) + 1, ColorScheme = Colors.ColorSchemes ["Error"], Text = "Remove this button"
         };
-        Win.Add (removeButton);
+        main.Add (removeButton);
 
         // This in interesting test case because `moveBtn` and below are laid out relative to this one!
         removeButton.Accept += (s, e) =>
                                 {
                                     // Now this throw a InvalidOperationException on the TopologicalSort method as is expected.
-                                    //Win.Remove (removeButton);
+                                    //main.Remove (removeButton);
 
                                     removeButton.Visible = false;
                                 };
@@ -125,7 +127,7 @@ public class Buttons : Scenario
             Height = 5,
             Title = "Computed Layout"
         };
-        Win.Add (computedFrame);
+        main.Add (computedFrame);
 
         // Demonstrates how changing the View.Frame property can move Views
         var moveBtn = new Button
@@ -176,7 +178,7 @@ public class Buttons : Scenario
             Height = 5,
             Title = "Absolute Layout"
         };
-        Win.Add (absoluteFrame);
+        main.Add (absoluteFrame);
 
         // Demonstrates how changing the View.Frame property can move Views
         var moveBtnA = new Button { ColorScheme = Colors.ColorSchemes ["Error"], Text = "Move This Button via Frame" };
@@ -213,7 +215,7 @@ public class Buttons : Scenario
         {
             X = 2, Y = Pos.Bottom (computedFrame) + 1, Text = "Text Alignment (changes the four buttons above): "
         };
-        Win.Add (label);
+        main.Add (label);
 
         var radioGroup = new RadioGroup
         {
@@ -222,7 +224,7 @@ public class Buttons : Scenario
             SelectedItem = 2,
             RadioLabels = new [] { "Left", "Right", "Centered", "Justified" }
         };
-        Win.Add (radioGroup);
+        main.Add (radioGroup);
 
         // Demo changing hotkey
         string MoveHotkey (string txt)
@@ -269,7 +271,7 @@ public class Buttons : Scenario
             Text = mhkb
         };
         moveHotKeyBtn.Accept += (s, e) => { moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text); };
-        Win.Add (moveHotKeyBtn);
+        main.Add (moveHotKeyBtn);
 
         var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
 
@@ -284,51 +286,157 @@ public class Buttons : Scenario
             Text = muhkb
         };
         moveUnicodeHotKeyBtn.Accept += (s, e) => { moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text); };
-        Win.Add (moveUnicodeHotKeyBtn);
+        main.Add (moveUnicodeHotKeyBtn);
 
         radioGroup.SelectedItemChanged += (s, args) =>
-                                          {
-                                              switch (args.SelectedItem)
-                                              {
-                                                  case 0:
-                                                      moveBtn.TextAlignment = TextAlignment.Left;
-                                                      sizeBtn.TextAlignment = TextAlignment.Left;
-                                                      moveBtnA.TextAlignment = TextAlignment.Left;
-                                                      sizeBtnA.TextAlignment = TextAlignment.Left;
-                                                      moveHotKeyBtn.TextAlignment = TextAlignment.Left;
-                                                      moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
-
-                                                      break;
-                                                  case 1:
-                                                      moveBtn.TextAlignment = TextAlignment.Right;
-                                                      sizeBtn.TextAlignment = TextAlignment.Right;
-                                                      moveBtnA.TextAlignment = TextAlignment.Right;
-                                                      sizeBtnA.TextAlignment = TextAlignment.Right;
-                                                      moveHotKeyBtn.TextAlignment = TextAlignment.Right;
-                                                      moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
-
-                                                      break;
-                                                  case 2:
-                                                      moveBtn.TextAlignment = TextAlignment.Centered;
-                                                      sizeBtn.TextAlignment = TextAlignment.Centered;
-                                                      moveBtnA.TextAlignment = TextAlignment.Centered;
-                                                      sizeBtnA.TextAlignment = TextAlignment.Centered;
-                                                      moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
-                                                      moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
-
-                                                      break;
-                                                  case 3:
-                                                      moveBtn.TextAlignment = TextAlignment.Justified;
-                                                      sizeBtn.TextAlignment = TextAlignment.Justified;
-                                                      moveBtnA.TextAlignment = TextAlignment.Justified;
-                                                      sizeBtnA.TextAlignment = TextAlignment.Justified;
-                                                      moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
-                                                      moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
-
-                                                      break;
-                                              }
-                                          };
-
-        Top.Ready += (s, e) => radioGroup.Refresh ();
+        {
+            switch (args.SelectedItem)
+            {
+                case 0:
+                    moveBtn.TextAlignment = TextAlignment.Left;
+                    sizeBtn.TextAlignment = TextAlignment.Left;
+                    moveBtnA.TextAlignment = TextAlignment.Left;
+                    sizeBtnA.TextAlignment = TextAlignment.Left;
+                    moveHotKeyBtn.TextAlignment = TextAlignment.Left;
+                    moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
+
+                    break;
+                case 1:
+                    moveBtn.TextAlignment = TextAlignment.Right;
+                    sizeBtn.TextAlignment = TextAlignment.Right;
+                    moveBtnA.TextAlignment = TextAlignment.Right;
+                    sizeBtnA.TextAlignment = TextAlignment.Right;
+                    moveHotKeyBtn.TextAlignment = TextAlignment.Right;
+                    moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
+
+                    break;
+                case 2:
+                    moveBtn.TextAlignment = TextAlignment.Centered;
+                    sizeBtn.TextAlignment = TextAlignment.Centered;
+                    moveBtnA.TextAlignment = TextAlignment.Centered;
+                    sizeBtnA.TextAlignment = TextAlignment.Centered;
+                    moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
+                    moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
+
+                    break;
+                case 3:
+                    moveBtn.TextAlignment = TextAlignment.Justified;
+                    sizeBtn.TextAlignment = TextAlignment.Justified;
+                    moveBtnA.TextAlignment = TextAlignment.Justified;
+                    sizeBtnA.TextAlignment = TextAlignment.Justified;
+                    moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
+                    moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
+
+                    break;
+            }
+        };
+
+        label = new Label ()
+        {
+            X = 0,
+            Y = Pos.Bottom (moveUnicodeHotKeyBtn) + 1,
+            Title = "_Numeric Up/Down (press-and-hold):",
+        };
+        var downButton = new Button ()
+        {
+            CanFocus = false,
+            AutoSize = false,
+            X = Pos.Right(label)+1,
+            Y = Pos.Top (label),
+            Height = 1,
+            Width = 1,
+            NoPadding = true,
+            NoDecorations = true,
+            Title = $"{CM.Glyphs.DownArrow}",
+            WantContinuousButtonPressed = true,
+        };
+
+        var numericEdit = new TextField ()
+        {
+            Text = "1966",
+            X = Pos.Right (downButton),
+            Y = Pos.Top (downButton),
+            Width = 5,
+            Height = 1,
+        };
+        var upButton = new Button ()
+        {
+            CanFocus = false,
+            AutoSize = false,
+            X = Pos.Right (numericEdit),
+            Y = Pos.Top (numericEdit),
+            Height = 1,
+            Width = 1,
+            NoPadding = true,
+            NoDecorations = true,
+            Title = $"{CM.Glyphs.UpArrow}",
+            WantContinuousButtonPressed = true,
+        };
+        downButton.Accept += (s, e) =>
+                             {
+                                 numericEdit.Text = $"{int.Parse(numericEdit.Text) - 1}";
+                             };
+        upButton.Accept += (s, e) =>
+                           {
+                               numericEdit.Text = $"{int.Parse (numericEdit.Text) + 1}";
+                           };
+
+        main.Add (label, downButton, numericEdit, upButton);
+
+        label = new Label ()
+        {
+            X = 0,
+            Y = Pos.Bottom (label) + 1,
+            Title = "_No Repeat:",
+        };
+        int noRepeatAcceptCount = 0;
+        var noRepeatButton = new Button ()
+        {
+            X = Pos.Right (label) + 1,
+            Y = Pos.Top (label),
+            Title = $"Accept Cou_nt: {noRepeatAcceptCount}",
+            WantContinuousButtonPressed = false,
+        };
+        noRepeatButton.Accept += (s, e) =>
+                                 {
+                                     noRepeatButton.Title = $"Accept Cou_nt: {++noRepeatAcceptCount}";
+                                 };
+        main.Add(label, noRepeatButton);
+
+        label = new Label ()
+        {
+            X = 0,
+            Y = Pos.Bottom (label) + 1,
+            Title = "_Repeat (press-and-hold):",
+        };
+        int acceptCount = 0;
+        var repeatButton = new Button ()
+        {
+            X = Pos.Right (label) + 1,
+            Y = Pos.Top (label),
+            Title = $"Accept Co_unt: {acceptCount}",
+            WantContinuousButtonPressed = true,
+        };
+        repeatButton.Accept += (s, e) =>
+                               {
+                                   repeatButton.Title = $"Accept Co_unt: {++acceptCount}";
+                               };
+
+        var enableCB = new CheckBox ()
+        {
+            X = Pos.Right (repeatButton) + 1,
+            Y = Pos.Top (repeatButton),
+            Title = "Enabled",
+            Checked = true,
+        };
+        enableCB.Toggled += (s, e) =>
+                            {
+                                repeatButton.Enabled = !repeatButton.Enabled;
+                            };
+        main.Add(label, repeatButton, enableCB);
+
+        main.Ready += (s, e) => radioGroup.Refresh ();
+        Application.Run (main);
+        main.Dispose ();
     }
 }

+ 0 - 3
UICatalog/Scenarios/CharacterMap.cs

@@ -1,6 +1,3 @@
-#define DRAW_CONTENT
-
-//#define BASE_DRAW_CONTENT
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;

+ 1 - 1
UICatalog/Scenarios/ContextMenus.cs

@@ -74,7 +74,7 @@ public class ContextMenus : Scenario
 
         Application.MouseEvent += ApplicationMouseEvent;
 
-        void ApplicationMouseEvent (object sender, MouseEventEventArgs a) { mousePos = new Point (a.MouseEvent.X, a.MouseEvent.Y); }
+        void ApplicationMouseEvent (object sender, MouseEvent a) { mousePos = new Point (a.X, a.Y); }
 
         Win.WantMousePositionReports = true;
 

+ 95 - 21
UICatalog/Scenarios/Mouse.cs

@@ -1,4 +1,7 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.CommandLine;
+using System.Linq;
 using Terminal.Gui;
 
 namespace UICatalog.Scenarios;
@@ -15,31 +18,85 @@ public class Mouse : Scenario
             Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
         };
 
+
+        var filterSlider = new Slider<MouseFlags> ()
+        {
+            Title = "_Filter",
+            X = 0,
+            Y = 0,
+            AutoSize = true,
+            BorderStyle = LineStyle.Single,
+            Type = SliderType.Multiple,
+            Orientation = Orientation.Vertical,
+        };
+        filterSlider.Options = Enum.GetValues (typeof (MouseFlags))
+                                   .Cast<MouseFlags> ()
+                                   .Where (value => !value.ToString ().Contains ("None") && 
+                                                    !value.ToString().Contains("All"))
+                                   .Select (value => new SliderOption<MouseFlags>
+                                   {
+                                       Legend = value.ToString (),
+                                       Data = value,
+                                   })
+                                   .ToList ();
+        for (int i = 0; i < filterSlider.Options.Count; i++)
+        {
+            filterSlider.SetOption (i);
+        }
+        win.Add (filterSlider);
+
+        var clearButton = new Button ()
+        {
+            Title = "_Clear Logs",
+            X = 1,
+            Y = Pos.Bottom (filterSlider) + 1,
+        };
+        win.Add (clearButton);
         Label ml;
         var count = 0;
-        ml = new Label { X = 1, Y = 1, Text = "Mouse: " };
+        ml = new Label { X = Pos.Right(filterSlider), Y = 0, Text = "Mouse: " };
 
         win.Add (ml);
 
-        CheckBox cbWantContinuousPresses = new CheckBox ()
+        CheckBox cbWantContinuousPresses = new ()
         {
-            X = 0,
-            Y = Pos.Bottom(ml) + 1,
-            Title = "_Want Continuous Button Presses",
+            X = Pos.Right (filterSlider),
+            Y = Pos.Bottom (ml),
+            Title = "_Want Continuous Button Pressed",
         };
-        cbWantContinuousPresses.Toggled += (s,e) =>
+        cbWantContinuousPresses.Toggled += (s, e) =>
         {
             win.WantContinuousButtonPressed = !win.WantContinuousButtonPressed;
         };
 
         win.Add (cbWantContinuousPresses);
+        CheckBox cbHighlightOnPress = new ()
+        {
+            X = Pos.Right (filterSlider),
+            Y = Pos.Bottom (cbWantContinuousPresses),
+            Title = "_Highlight on Press",
+        };
+        cbHighlightOnPress.Checked = win.HighlightStyle == (HighlightStyle.Pressed | HighlightStyle.PressedOutside);
+        cbHighlightOnPress.Toggled += (s, e) =>
+                                           {
+                                               if (e.NewValue == true)
+                                               {
+                                                   win.HighlightStyle = HighlightStyle.Pressed | HighlightStyle.PressedOutside;
+                                               }
+                                               else
+                                               {
+                                                   win.HighlightStyle = HighlightStyle.None;
+                                               }
+                                           };
+
+        win.Add (cbHighlightOnPress);
 
         var demo = new MouseDemo ()
         {
-            X = 0,
-            Y = Pos.Bottom (cbWantContinuousPresses) + 1,
+            X = Pos.Right (filterSlider),
+            Y = Pos.Bottom (cbHighlightOnPress),
             Width = 20,
-            Height = 5,
+            Height = 3,
             Text = "Enter/Leave Demo",
             TextAlignment = TextAlignment.Centered,
             VerticalTextAlignment = VerticalTextAlignment.Middle,
@@ -50,15 +107,16 @@ public class Mouse : Scenario
         var label = new Label ()
         {
             Text = "_App Events:",
-            X = 0,
+            X = Pos.Right (filterSlider),
             Y = Pos.Bottom (demo),
         };
+
         List<string> appLogList = new ();
         var appLog = new ListView
         {
             X = Pos.Left (label),
             Y = Pos.Bottom (label),
-            Width = Dim.Percent(49),
+            Width = 50,
             Height = Dim.Fill (),
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
             Source = new ListWrapper (appLogList)
@@ -67,22 +125,25 @@ public class Mouse : Scenario
 
         Application.MouseEvent += (sender, a) =>
                                   {
-                                      ml.Text = $"MouseEvent: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count}";
-                                      appLogList.Add ($"({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count++}");
-                                      appLog.MoveDown ();
+                                      var i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
+                                      if (filterSlider.GetSetOptions().Contains(i))
+                                      {
+                                          ml.Text = $"MouseEvent: ({a.X},{a.Y}) - {a.Flags} {count}";
+                                          appLogList.Add ($"({a.X},{a.Y}) - {a.Flags} {count++}");
+                                          appLog.MoveDown ();
+                                      }
                                   };
 
-
         label = new Label ()
         {
             Text = "_Window Events:",
-            X = Pos.Percent(50),
-            Y = Pos.Bottom (demo),
+            X = Pos.Right (appLog)+1,
+                          Y = Pos.Top (label),
         };
         List<string> winLogList = new ();
         var winLog = new ListView
         {
-            X = Pos.Left(label),
+            X = Pos.Left (label),
             Y = Pos.Bottom (label),
             Width = Dim.Percent (50),
             Height = Dim.Fill (),
@@ -90,10 +151,23 @@ public class Mouse : Scenario
             Source = new ListWrapper (winLogList)
         };
         win.Add (label, winLog);
+
+        clearButton.Accept += (s, e) =>
+                              {
+                                  appLogList.Clear ();
+                                  appLog.SetSource (appLogList);
+                                  winLogList.Clear ();
+                                  winLog.SetSource(winLogList);
+                              };
+
         win.MouseEvent += (sender, a) =>
                           {
-                              winLogList.Add ($"MouseEvent: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count++}");
-                              winLog.MoveDown ();
+                              var i = filterSlider.Options.FindIndex (o => o.Data == a.MouseEvent.Flags);
+                              if (filterSlider.GetSetOptions ().Contains (i))
+                              {
+                                  winLogList.Add ($"MouseEvent: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count++}");
+                                  winLog.MoveDown ();
+                              }
                           };
         win.MouseClick += (sender, a) =>
                           {

+ 12 - 6
UICatalog/Scenarios/ProgressBarStyles.cs

@@ -64,19 +64,25 @@ public class ProgressBarStyles : Scenario
         {
             var colorPicker = new ColorPicker { Title = text, SelectedColor = colorName };
 
-            var dialog = new Dialog { Title = text };
+            var dialog = new Dialog { AutoSize = false, Title = text };
 
-            dialog.LayoutComplete += (sender, args) =>
+            dialog.Initialized += (sender, args) =>
                                      {
                                          // TODO: Replace with Dim.Auto
                                          dialog.X = pbList.Frame.X;
                                          dialog.Y = pbList.Frame.Height;
-
-                                         dialog.Bounds = new Rectangle (0, 0, colorPicker.Frame.Width, colorPicker.Frame.Height);
-
-                                         Top.LayoutSubviews ();
                                      };
 
+            dialog.LayoutComplete += (sender, args) =>
+                                    {
+                                        dialog.Bounds = Rectangle.Empty with
+                                        {
+                                            Width = colorPicker.Frame.Width,
+                                            Height = colorPicker.Frame.Height
+                                        };
+                                        Application.Top.LayoutSubviews();
+                                    };
+
             dialog.Add (colorPicker);
             colorPicker.ColorChanged += (s, e) => { dialog.RequestStop (); };
             Application.Run (dialog);

+ 1 - 1
UICatalog/Scenarios/Scrolling.cs

@@ -251,7 +251,7 @@ public class Scrolling : Scenario
             Text = "Mouse: "
         };
         Win.Add (mousePos);
-        Application.MouseEvent += (sender, a) => { mousePos.Text = $"Mouse: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count++}"; };
+        Application.MouseEvent += (sender, a) => { mousePos.Text = $"Mouse: ({a.X},{a.Y}) - {a.Flags} {count++}"; };
 
         var progress = new ProgressBar { X = Pos.Right (scrollView) + 1, Y = Pos.AnchorEnd (2), Width = 50 };
         Win.Add (progress);

+ 32 - 2
UICatalog/Scenarios/TrueColors.cs

@@ -67,6 +67,14 @@ public class TrueColors : Scenario
                  new Label { X = Pos.AnchorEnd (44), Y = 6, Text = "Blue:" }
                 );
 
+        Win.Add (
+                 new Label { X = Pos.AnchorEnd (44), Y = 8, Text = "Darker:" }
+                );
+
+        Win.Add (
+                 new Label { X = Pos.AnchorEnd (44), Y = 9, Text = "Lighter:" }
+                );
+
         var lblRed = new Label { X = Pos.AnchorEnd (32), Y = 4, Text = "na" };
         Win.Add (lblRed);
         var lblGreen = new Label { X = Pos.AnchorEnd (32), Y = 5, Text = "na" };
@@ -74,11 +82,33 @@ public class TrueColors : Scenario
         var lblBlue = new Label { X = Pos.AnchorEnd (32), Y = 6, Text = "na" };
         Win.Add (lblBlue);
 
+        var lblDarker = new Label { X = Pos.AnchorEnd (32), Y = 8, Text = "     " };
+        Win.Add (lblDarker);
+
+        var lblLighter = new Label { X = Pos.AnchorEnd (32), Y = 9, Text = "    " };
+        Win.Add (lblLighter);
+
         Application.MouseEvent += (s, e) =>
                                   {
-                                      if (e.MouseEvent.View != null)
+                                      if (e.View == null)
+                                      {
+                                          return;
+                                      }
+                                      if (e.Flags == MouseFlags.Button1Clicked)
+                                      {
+                                          Attribute normal = e.View.GetNormalColor ();
+                                          
+                                          lblLighter.ColorScheme = new ColorScheme(e.View.ColorScheme)
+                                          {
+                                              Normal = new Attribute (
+                                                                      normal.Foreground,
+                                                                      normal.Background.GetHighlightColor ()
+                                                                     )
+                                          };
+                                      }
+                                      else
                                       {
-                                          Attribute normal = e.MouseEvent.View.GetNormalColor ();
+                                          Attribute normal = e.View.GetNormalColor ();
                                           lblRed.Text = normal.Foreground.R.ToString ();
                                           lblGreen.Text = normal.Foreground.G.ToString ();
                                           lblBlue.Text = normal.Foreground.B.ToString ();

+ 35 - 118
UnitTests/Application/ApplicationTests.cs

@@ -41,9 +41,9 @@ public class ApplicationTests
     {
         Assert.Null (Application.Top);
         Application.Begin (new ());
-        Assert.Equal (new Rectangle (0, 0, 80, 25), Application.Top.Frame);
+        Assert.Equal (new (0, 0, 80, 25), Application.Top.Frame);
         ((FakeDriver)Application.Driver).SetBufferSize (5, 5);
-        Assert.Equal (new Rectangle (0, 0, 5, 5), Application.Top.Frame);
+        Assert.Equal (new (0, 0, 5, 5), Application.Top.Frame);
     }
 
     [Fact]
@@ -62,10 +62,10 @@ public class ApplicationTests
 
         Assert.Null (rs.Toplevel);
 
-        var top = Application.Top;
+        Toplevel top = Application.Top;
 
 #if DEBUG_IDISPOSABLE
-        var exception = Record.Exception (() => Shutdown ());
+        Exception exception = Record.Exception (() => Shutdown ());
         Assert.NotNull (exception);
         Assert.False (top.WasDisposed);
         top.Dispose ();
@@ -130,7 +130,7 @@ public class ApplicationTests
         var driver = (ConsoleDriver)Activator.CreateInstance (driverType);
         Application.Init (driverName: driverType.Name);
         Assert.NotNull (Application.Driver);
-        Assert.NotEqual(driver, Application.Driver);
+        Assert.NotEqual (driver, Application.Driver);
         Assert.Equal (driverType, Application.Driver.GetType ());
         Shutdown ();
     }
@@ -212,7 +212,7 @@ public class ApplicationTests
         Application._mainThreadId = 1;
 
         //Application._topLevels = new List<Toplevel> ();
-        Application._mouseEnteredView = new View ();
+        Application._mouseEnteredView = new ();
 
         //Application.SupportedCultures = new List<CultureInfo> ();
         Application.Force16Colors = true;
@@ -225,7 +225,7 @@ public class ApplicationTests
 
         //Application.OverlappedChildren = new List<View> ();
         //Application.OverlappedTop = 
-        Application._mouseEnteredView = new View ();
+        Application._mouseEnteredView = new ();
 
         //Application.WantContinuousButtonPressedView = new View ();
 
@@ -464,6 +464,7 @@ public class ApplicationTests
         Application.Run (t1);
 
         Assert.Equal (t1, Application.Top);
+
         // top wasn't run and so never was added to toplevel's stack
         Assert.NotEqual (top, Application.Top);
 #if DEBUG_IDISPOSABLE
@@ -511,7 +512,6 @@ public class ApplicationTests
     #region RunTests
 
     [Fact]
-
     public void Run_T_After_InitWithDriver_with_TopLevel_Does_Not_Throws ()
     {
         // Setup Mock driver
@@ -533,7 +533,6 @@ public class ApplicationTests
     }
 
     [Fact]
-
     public void Run_T_After_InitWithDriver_with_TopLevel_and_Driver_Does_Not_Throws ()
     {
         // Setup Mock driver
@@ -547,6 +546,7 @@ public class ApplicationTests
         Assert.True (Application.Top is Window);
 
         Application.Top.Dispose ();
+
         // Run<Toplevel> when already initialized or not with a Driver will not throw (because Dialog is derived from Toplevel)
         Application.Run<Dialog> (null, new FakeDriver ());
         Assert.True (Application.Top is Dialog);
@@ -561,7 +561,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_T_After_Init_Does_Not_Disposes_Application_Top ()
     {
         Init ();
@@ -572,7 +571,7 @@ public class ApplicationTests
 
         Application.Iteration += (s, a) =>
                                  {
-                                     Assert.NotEqual(initTop, Application.Top);
+                                     Assert.NotEqual (initTop, Application.Top);
 #if DEBUG_IDISPOSABLE
                                      Assert.False (initTop.WasDisposed);
 #endif
@@ -596,7 +595,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_T_After_InitWithDriver_with_TestTopLevel_DoesNotThrow ()
     {
         // Setup Mock driver
@@ -617,7 +615,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_T_After_InitNullDriver_with_TestTopLevel_DoesNotThrow ()
     {
         Application.ForceDriver = "FakeDriver";
@@ -640,7 +637,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_T_Init_Driver_Cleared_with_TestTopLevel_Throws ()
     {
         Init ();
@@ -678,7 +674,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_T_NoInit_WithDriver_DoesNotThrow ()
     {
         Application.Iteration += (s, a) => { Application.RequestStop (); };
@@ -696,7 +691,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_RequestStop_Stops ()
     {
         // Setup Mock driver
@@ -721,7 +715,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_RunningFalse_Stops ()
     {
         // Setup Mock driver
@@ -746,7 +739,6 @@ public class ApplicationTests
 
     [Fact]
     [TestRespondersDisposed]
-
     public void Run_Loaded_Ready_Unlodaded_Events ()
     {
         Init ();
@@ -782,18 +774,13 @@ public class ApplicationTests
                                      if (iteration == 0)
                                      {
                                          // TODO: Don't use Dialog here as it has more layout logic. Use Window instead.
-                                         d = new Dialog ();
+                                         d = new ();
                                          d.DrawContent += (s, a) => count++;
                                          Application.Run (d);
                                      }
                                      else if (iteration < 3)
                                      {
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            { X = 0, Y = 0, Flags = MouseFlags.ReportMousePosition }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new () { X = 0, Y = 0, Flags = MouseFlags.ReportMousePosition });
                                          Assert.False (top.NeedsDisplay);
                                          Assert.False (top.SubViewNeedsDisplay);
                                          Assert.False (top.LayoutNeeded);
@@ -825,91 +812,16 @@ public class ApplicationTests
         ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
         RunState rs = Application.Begin (w);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌───┐
-│   │
-│   │
-│   │
-└───┘",
-                                                      _output
-                                                     );
-
-        Attribute [] attributes =
-        {
-            // 0
-            new (ColorName.White, ColorName.Black),
-
-            // 1
-            Colors.ColorSchemes ["Base"].Normal
-        };
-
-        TestHelpers.AssertDriverAttributesAre (
-                                               @"
-1111100000
-1111100000
-1111100000
-1111100000
-1111100000
-",
-                                               null,
-                                               attributes
-                                              );
-
-        // TODO: In PR #2920 this breaks because the mouse is not grabbed anymore.
-        // TODO: Move the mouse grap/drag mode from Toplevel to Border.
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed }
-                                                          )
-                                 );
+        // Don't use visuals to test as style of border can change over time.
+        Assert.Equal (new Point (0, 0), w.Frame.Location);
+
+        Application.OnMouseEvent (new () { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed });
         Assert.Equal (w.Border, Application.MouseGrabView);
+        Assert.Equal (new Point (0,0), w.Frame.Location);
 
         // Move down and to the right.
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 1,
-                                                               Y = 1,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
-        Application.Refresh ();
-
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
- ┌───┐
- │   │
- │   │
- │   │
- └───┘",
-                                                      _output
-                                                     );
-
-        attributes = new []
-        {
-            // 0
-            new (ColorName.White, ColorName.Black),
-
-            // 1
-            Colors.ColorSchemes ["Base"].Normal
-        };
-
-        TestHelpers.AssertDriverAttributesAre (
-                                               @"
-0000000000
-0111110000
-0111110000
-0111110000
-0111110000
-0111110000
-",
-                                               null,
-                                               attributes
-                                              );
+        Application.OnMouseEvent (new () { X = 1, Y = 1, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
+        Assert.Equal (new Point (1, 1), w.Frame.Location);
 
         Application.End (rs);
         w.Dispose ();
@@ -925,7 +837,7 @@ public class ApplicationTests
 
         Window w = new ();
         w.Ready += (s, e) => Application.RequestStop (); // Causes `End` to be called
-        Application.Run(w);
+        Application.Run (w);
 
 #if DEBUG_IDISPOSABLE
         Assert.False (w.WasDisposed);
@@ -934,20 +846,23 @@ public class ApplicationTests
         Assert.NotNull (w);
         Assert.Equal (string.Empty, w.Title); // Valid - w has not been disposed. The user may want to run it again
         Assert.NotNull (Application.Top);
-        Assert.Equal(w, Application.Top);
-        Assert.NotEqual(top, Application.Top);
+        Assert.Equal (w, Application.Top);
+        Assert.NotEqual (top, Application.Top);
         Assert.Null (Application.Current);
 
-        Application.Run(w); // Valid - w has not been disposed.
+        Application.Run (w); // Valid - w has not been disposed.
 
 #if DEBUG_IDISPOSABLE
         Assert.False (w.WasDisposed);
-        var exception = Record.Exception (() => Application.Shutdown()); // Invalid - w has not been disposed.
+        Exception exception = Record.Exception (() => Application.Shutdown ()); // Invalid - w has not been disposed.
         Assert.NotNull (exception);
 
         w.Dispose ();
         Assert.True (w.WasDisposed);
-        exception = Record.Exception (() => Application.Run (w)); // Invalid - w has been disposed. Run it in debug mode will throw, otherwise the user may want to run it again
+
+        exception = Record.Exception (
+                                      () => Application.Run (
+                                                             w)); // Invalid - w has been disposed. Run it in debug mode will throw, otherwise the user may want to run it again
         Assert.NotNull (exception);
 
         exception = Record.Exception (() => Assert.Equal (string.Empty, w.Title)); // Invalid - w has been disposed and cannot be accessed
@@ -974,11 +889,11 @@ public class ApplicationTests
                                      Assert.NotNull (Application.Top);
                                      Application.RequestStop ();
                                  };
-        var top = Application.Run (null, driver);
+        Toplevel top = Application.Run (null, driver);
 #if DEBUG_IDISPOSABLE
-        Assert.Equal(top, Application.Top);
+        Assert.Equal (top, Application.Top);
         Assert.False (top.WasDisposed);
-        var exception = Record.Exception (() => Application.Shutdown ());
+        Exception exception = Record.Exception (() => Application.Shutdown ());
         Assert.NotNull (exception);
         Assert.False (top.WasDisposed);
 #endif
@@ -1010,9 +925,10 @@ public class ApplicationTests
         Application.Run<Toplevel> (null, driver);
 #if DEBUG_IDISPOSABLE
         Assert.False (Application.Top.WasDisposed);
-        var exception = Record.Exception (() => Application.Shutdown ());
+        Exception exception = Record.Exception (() => Application.Shutdown ());
         Assert.NotNull (exception);
         Assert.False (Application.Top.WasDisposed);
+
         // It's up to caller to dispose it
         Application.Top.Dispose ();
         Assert.True (Application.Top.WasDisposed);
@@ -1038,9 +954,10 @@ public class ApplicationTests
         Application.Run (new (), null, driver);
 #if DEBUG_IDISPOSABLE
         Assert.False (Application.Top.WasDisposed);
-        var exception = Record.Exception (() => Application.Shutdown ());
+        Exception exception = Record.Exception (() => Application.Shutdown ());
         Assert.NotNull (exception);
         Assert.False (Application.Top.WasDisposed);
+
         // It's up to caller to dispose it
         Application.Top.Dispose ();
         Assert.True (Application.Top.WasDisposed);

+ 17 - 38
UnitTests/Application/MouseTests.cs

@@ -42,19 +42,18 @@ public class MouseTests
     )
     {
         var mouseEvent = new MouseEvent { X = clickX, Y = clickY, Flags = MouseFlags.Button1Pressed };
-        var mouseEventArgs = new MouseEventEventArgs (mouseEvent);
         var clicked = false;
 
-        void OnApplicationOnMouseEvent (object s, MouseEventEventArgs e)
+        void OnApplicationOnMouseEvent (object s, MouseEvent e)
         {
-            Assert.Equal (expectedX, e.MouseEvent.X);
-            Assert.Equal (expectedY, e.MouseEvent.Y);
+            Assert.Equal (expectedX, e.X);
+            Assert.Equal (expectedY, e.Y);
             clicked = true;
         }
 
         Application.MouseEvent += OnApplicationOnMouseEvent;
 
-        Application.OnMouseEvent (mouseEventArgs);
+        Application.OnMouseEvent (mouseEvent);
         Assert.Equal (expectedClicked, clicked);
         Application.MouseEvent -= OnApplicationOnMouseEvent;
     }
@@ -107,7 +106,8 @@ public class MouseTests
         Point pos = new (offset, offset);
 
         var clicked = false;
-        var view = new View ()
+
+        var view = new View
         {
             X = pos.X,
             Y = pos.Y,
@@ -116,20 +116,19 @@ public class MouseTests
         };
 
         var mouseEvent = new MouseEvent { X = clickX, Y = clickY, Flags = MouseFlags.Button1Clicked };
-        var mouseEventArgs = new MouseEventEventArgs (mouseEvent);
 
         view.MouseClick += (s, e) =>
-                                      {
-                                          Assert.Equal (expectedX, e.MouseEvent.X);
-                                          Assert.Equal (expectedY, e.MouseEvent.Y);
-                                          clicked = true;
-                                      };
+                           {
+                               Assert.Equal (expectedX, e.MouseEvent.X);
+                               Assert.Equal (expectedY, e.MouseEvent.Y);
+                               clicked = true;
+                           };
 
         var top = new Toplevel ();
         top.Add (view);
         Application.Begin (top);
 
-        Application.OnMouseEvent (mouseEventArgs);
+        Application.OnMouseEvent (mouseEvent);
         Assert.Equal (expectedClicked, clicked);
     }
 
@@ -215,7 +214,6 @@ public class MouseTests
         top.Add (view);
         Application.Begin (top);
         var mouseEvent = new MouseEvent { X = clickX, Y = clickY, Flags = MouseFlags.Button1Clicked };
-        var mouseEventArgs = new MouseEventEventArgs (mouseEvent);
 
         view.MouseClick += (s, e) =>
                            {
@@ -224,7 +222,7 @@ public class MouseTests
                                clicked = true;
                            };
 
-        Application.OnMouseEvent (mouseEventArgs);
+        Application.OnMouseEvent (mouseEvent);
         Assert.Equal (expectedClicked, clicked);
     }
 
@@ -254,12 +252,7 @@ public class MouseTests
                                          Assert.True (tf.HasFocus);
                                          Assert.Null (Application.MouseGrabView);
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                                { X = 5, Y = 5, Flags = MouseFlags.ReportMousePosition }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new() { X = 5, Y = 5, Flags = MouseFlags.ReportMousePosition });
 
                                          Assert.Equal (sv, Application.MouseGrabView);
 
@@ -273,29 +266,15 @@ public class MouseTests
                                          // another toplevel (Dialog) was opened
                                          Assert.Null (Application.MouseGrabView);
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                                { X = 5, Y = 5, Flags = MouseFlags.ReportMousePosition }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new() { X = 5, Y = 5, Flags = MouseFlags.ReportMousePosition });
 
                                          Assert.Null (Application.MouseGrabView);
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                                { X = 40, Y = 12, Flags = MouseFlags.ReportMousePosition }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new() { X = 40, Y = 12, Flags = MouseFlags.ReportMousePosition });
 
                                          Assert.Null (Application.MouseGrabView);
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new() { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed });
 
                                          Assert.Null (Application.MouseGrabView);
 

+ 2 - 10
UnitTests/Input/EscSeqUtilsTests.cs

@@ -699,11 +699,7 @@ public class EscSeqUtilsTests
         top.Add (view);
         Application.Begin (top);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 0, Y = 0, Flags = 0 }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = 0 });
 
         ClearAll ();
 
@@ -760,11 +756,7 @@ public class EscSeqUtilsTests
                                          // set Application.WantContinuousButtonPressedView to null
                                          view.WantContinuousButtonPressed = false;
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent { X = 0, Y = 0, Flags = 0 }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = 0 });
 
                                          Application.RequestStop ();
                                      }

+ 3 - 3
UnitTests/Input/ResponderTests.cs

@@ -234,9 +234,9 @@ public class ResponderTests
         //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown }));
         Assert.False (r.OnKeyDown (new Key { KeyCode = KeyCode.Null }));
         Assert.False (r.OnKeyUp (new Key { KeyCode = KeyCode.Null }));
-        Assert.False (r.OnMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
-        Assert.False (r.OnMouseEnter (new MouseEvent { Flags = MouseFlags.AllEvents }));
-        Assert.False (r.OnMouseLeave (new MouseEvent { Flags = MouseFlags.AllEvents }));
+        Assert.False (r.NewMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
+        Assert.False (r.NewMouseEnterEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
+        Assert.False (r.NewMouseLeaveEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
 
         var v = new View ();
         Assert.False (r.OnEnter (v));

+ 82 - 0
UnitTests/TestHelpers.cs

@@ -74,6 +74,7 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
 
         if (AutoInit)
         {
+            // TODO: This Dispose call is here until all unit tests that don't correctly dispose Toplevel's they create are fixed.
             Application.Top?.Dispose ();
             Application.Shutdown ();
 #if DEBUG_IDISPOSABLE
@@ -728,6 +729,87 @@ internal partial class TestHelpers
         return view;
     }
 
+    public static List<Type> GetAllViewClasses ()
+    {
+        return typeof (View).Assembly.GetTypes ()
+                            .Where (
+                                    myType => myType.IsClass
+                                              && !myType.IsAbstract
+                                              && myType.IsPublic
+                                              && myType.IsSubclassOf (typeof (View))
+                                   )
+                            .ToList ();
+    }
+
+    public static View CreateViewFromType (Type type, ConstructorInfo ctor)
+    {
+        View viewType = null;
+
+        if (type.IsGenericType && type.IsTypeDefinition)
+        {
+            List<Type> gTypes = new ();
+
+            foreach (Type args in type.GetGenericArguments ())
+            {
+                gTypes.Add (typeof (object));
+            }
+
+            type = type.MakeGenericType (gTypes.ToArray ());
+
+            Assert.IsType (type, (View)Activator.CreateInstance (type));
+        }
+        else
+        {
+            ParameterInfo [] paramsInfo = ctor.GetParameters ();
+            Type paramType;
+            List<object> pTypes = new ();
+
+            if (type.IsGenericType)
+            {
+                foreach (Type args in type.GetGenericArguments ())
+                {
+                    paramType = args.GetType ();
+
+                    if (args.Name == "T")
+                    {
+                        pTypes.Add (typeof (object));
+                    }
+                    else
+                    {
+                        AddArguments (paramType, pTypes);
+                    }
+                }
+            }
+
+            foreach (ParameterInfo p in paramsInfo)
+            {
+                paramType = p.ParameterType;
+
+                if (p.HasDefaultValue)
+                {
+                    pTypes.Add (p.DefaultValue);
+                }
+                else
+                {
+                    AddArguments (paramType, pTypes);
+                }
+            }
+
+            if (type.IsGenericType && !type.IsTypeDefinition)
+            {
+                viewType = (View)Activator.CreateInstance (type);
+                Assert.IsType (type, viewType);
+            }
+            else
+            {
+                viewType = (View)ctor.Invoke (pTypes.ToArray ());
+                Assert.IsType (type, viewType);
+            }
+        }
+
+        return viewType;
+    }
+
     [GeneratedRegex ("^\\s+", RegexOptions.Multiline)]
     private static partial Regex LeadingWhitespaceRegEx ();
 

+ 1 - 1
UnitTests/Text/AutocompleteTests.cs

@@ -50,7 +50,7 @@ This a long line and against TextView.
         }
 
         Assert.True (
-                     tv.OnMouseEvent (
+                     tv.NewMouseEvent (
                                     new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );

+ 495 - 6
UnitTests/View/MouseTests.cs

@@ -27,7 +27,7 @@ public class MouseTests (ITestOutputHelper output)
             testView.SetFocus ();
         }
 
-        testView.OnMouseEvent (new () { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked });
+        testView.NewMouseEvent (new () { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked });
         Assert.True (superView.HasFocus);
         Assert.Equal (expectedHasFocus, testView.HasFocus);
     }
@@ -73,11 +73,9 @@ public class MouseTests (ITestOutputHelper output)
         Application.Begin (top);
 
         Assert.Equal (new Point (4, 4), testView.Frame.Location);
-        Application.OnMouseEvent (new (new () { X = xy, Y = xy, Flags = MouseFlags.Button1Pressed }));
+        Application.OnMouseEvent (new () { X = xy, Y = xy, Flags = MouseFlags.Button1Pressed });
 
-        Assert.False (Application.MouseGrabView is { } && (Application.MouseGrabView != testView.Margin && Application.MouseGrabView != testView.Border));
-
-        Application.OnMouseEvent (new (new () { X = xy + 1, Y = xy + 1, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }));
+        Application.OnMouseEvent (new () { X = xy + 1, Y = xy + 1, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
 
         Assert.Equal (expectedMoved, new Point (5, 5) == testView.Frame.Location);
     }
@@ -91,7 +89,498 @@ public class MouseTests (ITestOutputHelper output)
         var view = new View ();
         view.MouseEvent += (s, e) => mouseFlagsFromEvent = e.MouseEvent.Flags;
 
-        view.OnMouseEvent (new MouseEvent () { Flags = mouseFlags });
+        view.NewMouseEvent (new MouseEvent () { Flags = mouseFlags });
         Assert.Equal (mouseFlagsFromEvent, expectedMouseFlagsFromEvent);
     }
+
+    public static TheoryData<View, string> AllViews => TestHelpers.GetAllViewsTheoryData ();
+
+
+    [Theory]
+    [MemberData (nameof (AllViews))]
+
+    public void AllViews_Enter_Leave_Events (View view, string viewName)
+    {
+        if (view == null)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It's a Generic");
+            return;
+        }
+
+        if (!view.CanFocus)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It can't focus.");
+
+            return;
+        }
+
+        if (view is Toplevel && ((Toplevel)view).Modal)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It's a Modal Toplevel");
+
+            return;
+        }
+
+        Application.Init (new FakeDriver ());
+
+        Toplevel top = new ()
+        {
+            Height = 10,
+            Width = 10
+        };
+
+        View otherView = new ()
+        {
+            X = 0, Y = 0,
+            Height = 1,
+            Width = 1,
+            CanFocus = true,
+        };
+
+        view.AutoSize = false;
+        view.X = Pos.Right (otherView);
+        view.Y = 0;
+        view.Width = 10;
+        view.Height = 1;
+
+        var nEnter = 0;
+        var nLeave = 0;
+
+        view.Enter += (s, e) => nEnter++;
+        view.Leave += (s, e) => nLeave++;
+
+        top.Add (view, otherView);
+        Application.Begin (top);
+
+        // Start with the focus on our test view
+        view.SetFocus ();
+
+        Assert.Equal (1, nEnter);
+        Assert.Equal (0, nLeave);
+
+        // Use keyboard to navigate to next view (otherView). 
+        if (view is TextView)
+        {
+            top.NewKeyDownEvent (Key.Tab.WithCtrl);
+        }
+        else if (view is DatePicker)
+        {
+            for (var i = 0; i < 4; i++)
+            {
+                top.NewKeyDownEvent (Key.Tab.WithCtrl);
+            }
+        }
+        else
+        {
+            top.NewKeyDownEvent (Key.Tab);
+        }
+
+        Assert.Equal (1, nEnter);
+        Assert.Equal (1, nLeave);
+
+        top.NewKeyDownEvent (Key.Tab);
+
+        Assert.Equal (2, nEnter);
+        Assert.Equal (1, nLeave);
+
+        top.Dispose ();
+        Application.Shutdown ();
+    }
+
+
+    [Theory]
+    [MemberData (nameof (AllViews))]
+
+    public void AllViews_Enter_Leave_Events_Visible_False (View view, string viewName)
+    {
+        if (view == null)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It's a Generic");
+            return;
+        }
+
+        if (!view.CanFocus)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It can't focus.");
+
+            return;
+        }
+
+        if (view is Toplevel && ((Toplevel)view).Modal)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It's a Modal Toplevel");
+
+            return;
+        }
+
+        Application.Init (new FakeDriver ());
+
+        Toplevel top = new ()
+        {
+            Height = 10,
+            Width = 10
+        };
+
+        View otherView = new ()
+        {
+            X = 0, Y = 0,
+            Height = 1,
+            Width = 1,
+            CanFocus = true,
+        };
+
+        view.Visible = false;
+        view.AutoSize = false;
+        view.X = Pos.Right (otherView);
+        view.Y = 0;
+        view.Width = 10;
+        view.Height = 1;
+
+        var nEnter = 0;
+        var nLeave = 0;
+
+        view.Enter += (s, e) => nEnter++;
+        view.Leave += (s, e) => nLeave++;
+
+        top.Add (view, otherView);
+        Application.Begin (top);
+
+        // Start with the focus on our test view
+        view.SetFocus ();
+
+        Assert.Equal (0, nEnter);
+        Assert.Equal (0, nLeave);
+
+        // Use keyboard to navigate to next view (otherView). 
+        if (view is TextView)
+        {
+            top.NewKeyDownEvent (Key.Tab.WithCtrl);
+        }
+        else if (view is DatePicker)
+        {
+            for (var i = 0; i < 4; i++)
+            {
+                top.NewKeyDownEvent (Key.Tab.WithCtrl);
+            }
+        }
+        else
+        {
+            top.NewKeyDownEvent (Key.Tab);
+        }
+
+        Assert.Equal (0, nEnter);
+        Assert.Equal (0, nLeave);
+
+        top.NewKeyDownEvent (Key.Tab);
+
+        Assert.Equal (0, nEnter);
+        Assert.Equal (0, nLeave);
+
+        top.Dispose ();
+        Application.Shutdown ();
+    }
+
+    [Fact]
+    public void NewMouseEvent_Invokes_MouseEvent_Properly ()
+    {
+        View view = new ()
+        {
+            Width = 1,
+            Height = 1,
+        };
+        bool mouseEventInvoked = false;
+        view.MouseEvent += (s, e) =>
+                           {
+                               mouseEventInvoked = true;
+                               e.Handled = true;
+                           };
+
+        MouseEvent me = new ();
+        view.NewMouseEvent (me);
+        Assert.True (mouseEventInvoked);
+        Assert.True (me.Handled);
+
+        view.Dispose ();
+    }
+
+    [Theory]
+    [MemberData (nameof (AllViews))]
+    public void AllViews_NewMouseEvent_Enabled_False_Does_Not_Set_Handled (View view, string viewName)
+    {
+        if (view == null)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It's a Generic");
+            return;
+        }
+
+        view.Enabled = false;
+        var me = new MouseEvent ();
+        view.NewMouseEvent (me);
+        Assert.False (me.Handled);
+        view.Dispose ();
+    }
+
+    [Theory]
+    [MemberData (nameof (AllViews))]
+    public void AllViews_NewMouseEvent_Clicked_Enabled_False_Does_Not_Set_Handled (View view, string viewName)
+    {
+        if (view == null)
+        {
+            output.WriteLine ($"Ignoring {viewName} - It's a Generic");
+            return;
+        }
+
+        view.Enabled = false;
+        var me = new MouseEvent ()
+        {
+            Flags = MouseFlags.Button1Clicked
+        };
+        view.NewMouseEvent (me);
+        Assert.False (me.Handled);
+        view.Dispose ();
+    }
+
+    [Theory]
+    [InlineData (MouseFlags.Button1Pressed, MouseFlags.Button1Released, MouseFlags.Button1Clicked)]
+    [InlineData (MouseFlags.Button2Pressed, MouseFlags.Button2Released, MouseFlags.Button2Clicked)]
+    [InlineData (MouseFlags.Button3Pressed, MouseFlags.Button3Released, MouseFlags.Button3Clicked)]
+    [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)]
+    public void WantContinuousButtonPressed_False_Button_Press_Release_DoesNotClick (MouseFlags pressed, MouseFlags released, MouseFlags clicked)
+    {
+        var me = new MouseEvent ();
+
+        var view = new View ()
+        {
+            Width = 1,
+            Height = 1,
+            WantContinuousButtonPressed = false
+        };
+
+        var clickedCount = 0;
+
+        view.MouseClick += (s, e) => clickedCount++;
+
+        me.Flags = pressed;
+        view.NewMouseEvent (me);
+        Assert.Equal (0, clickedCount);
+        me.Handled = false;
+
+        me.Flags = pressed;
+        view.NewMouseEvent (me);
+        Assert.Equal (0, clickedCount);
+        me.Handled = false;
+
+        me.Flags = released;
+        view.NewMouseEvent (me);
+        Assert.Equal (0, clickedCount);
+        me.Handled = false;
+
+        me.Flags =clicked;
+        view.NewMouseEvent (me);
+        Assert.Equal (1, clickedCount);
+
+        view.Dispose ();
+    }
+
+    [Theory]
+    [InlineData (MouseFlags.Button1Pressed, MouseFlags.Button1Released, MouseFlags.Button1Clicked)]
+    [InlineData (MouseFlags.Button2Pressed, MouseFlags.Button2Released, MouseFlags.Button2Clicked)]
+    [InlineData (MouseFlags.Button3Pressed, MouseFlags.Button3Released, MouseFlags.Button3Clicked)]
+    [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)]
+    public void WantContinuousButtonPressed_True_Button_Press_Release_Clicks_Repeatedly (MouseFlags pressed, MouseFlags released, MouseFlags clicked)
+    {
+        var me = new MouseEvent ();
+
+        var view = new View ()
+        {
+            Width = 1,
+            Height = 1,
+            WantContinuousButtonPressed = true
+        };
+
+        var clickedCount = 0;
+
+        view.MouseClick += (s, e) => clickedCount++;
+
+        me.Flags = pressed;
+        view.NewMouseEvent (me);
+        Assert.Equal (1, clickedCount);
+        me.Handled = false;
+
+        me.Flags = pressed;
+        view.NewMouseEvent (me);
+        Assert.Equal (2, clickedCount);
+        me.Handled = false;
+
+        me.Flags = released;
+        view.NewMouseEvent (me);
+        Assert.Equal (2, clickedCount);
+        me.Handled = false;
+
+        me.Flags = clicked;
+        view.NewMouseEvent (me);
+        Assert.Equal (2, clickedCount);
+
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void WantContinuousButtonPressed_True_Move_InViewport_OutOfViewport_Keeps_Counting ()
+    {
+        var me = new MouseEvent ();
+
+        var view = new View ()
+        {
+            Width = 1,
+            Height = 1,
+            WantContinuousButtonPressed = true
+        };
+
+        var clickedCount = 0;
+
+        view.MouseClick += (s, e) => clickedCount++;
+
+        // Start in Viewport
+        me.Flags = MouseFlags.Button1Pressed;
+        me.X = 0;
+        view.NewMouseEvent (me);
+        Assert.Equal (1, clickedCount);
+        me.Handled = false;
+
+        // Move out of Viewport
+        me.Flags = MouseFlags.Button1Pressed;
+        me.X = 1;
+        view.NewMouseEvent (me);
+        Assert.Equal (2, clickedCount);
+        me.Handled = false;
+
+        // Move into Viewport
+        me.Flags = MouseFlags.Button1Pressed;
+        me.X = 0;
+        view.NewMouseEvent (me);
+        Assert.Equal (3, clickedCount);
+        me.Handled = false;
+
+        view.Dispose ();
+    }
+
+    [Theory]
+    [InlineData (HighlightStyle.None, 0, 0)]
+    [InlineData (HighlightStyle.Pressed | HighlightStyle.PressedOutside, 1, 1)]
+    public void HighlightOnPress_Fires_Events_And_Highlights (HighlightStyle highlightOnPress, int expectedEnabling, int expectedDisabling)
+    {
+        var view = new View ()
+        {
+            HighlightStyle = highlightOnPress,
+            Height = 1,
+            Width = 1
+        };
+
+        int enablingHighlight = 0;
+        int disablingHighlight = 0;
+        view.Highlight += View_Highlight;
+        view.ColorScheme = new ColorScheme (new Attribute (ColorName.Red, ColorName.Blue));
+        ColorScheme originalColorScheme = view.ColorScheme;
+
+        view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, });
+
+        if (highlightOnPress != HighlightStyle.None)
+        {
+            Assert.NotEqual (originalColorScheme, view.ColorScheme);
+        }
+        else
+        {
+            Assert.Equal (originalColorScheme, view.ColorScheme);
+        }
+
+        view.NewMouseEvent (new () { Flags = MouseFlags.Button1Released, });
+        Assert.Equal (originalColorScheme, view.ColorScheme);
+        Assert.Equal (expectedEnabling, enablingHighlight);
+        Assert.Equal (expectedDisabling, disablingHighlight);
+
+        view.Dispose ();
+
+        return;
+
+        void View_Highlight (object sender, HighlightEventArgs e)
+        {
+            if (e.HighlightStyle == HighlightStyle.None)
+            {
+                disablingHighlight++;
+            }
+            else
+            {
+                enablingHighlight++;
+            }
+        }
+    }
+
+    // TODO: Add tests for each combination of HighlightFlags
+
+    [Theory]
+    [InlineData (0)]
+    [InlineData (1)]
+    [InlineData (10)]
+    public void HighlightOnPress_Move_Keeps_Highlight (int x)
+    {
+        var view = new View ()
+        {
+            HighlightStyle = HighlightStyle.Pressed | HighlightStyle.PressedOutside,
+            Height = 1,
+            Width = 1
+        };
+        int enablingHighlight = 0;
+        int disablingHighlight = 0;
+        view.Highlight += View_Highlight;
+        bool inViewport = view.Bounds.Contains (x, 0);
+
+        // Start at 0,0 ; in viewport
+        view.NewMouseEvent (new () { X = 0, Flags = MouseFlags.Button1Pressed });
+        Assert.Equal (1, enablingHighlight);
+        Assert.Equal (0, disablingHighlight);
+
+        // Move to x,0 
+        view.NewMouseEvent (new () { X = x, Flags = MouseFlags.Button1Pressed });
+
+        if (inViewport)
+        {
+            Assert.Equal (2, enablingHighlight);
+            Assert.Equal (0, disablingHighlight);
+        }
+        else
+        {
+            Assert.Equal (2, enablingHighlight);
+            Assert.Equal (0, disablingHighlight);
+        }
+
+        // Move backto 0,0 ; in viewport
+        view.NewMouseEvent (new () { X = 0, Flags = MouseFlags.Button1Pressed });
+        if (inViewport)
+        {
+            Assert.Equal (3, enablingHighlight);
+            Assert.Equal (0, disablingHighlight);
+        }
+        else
+        {
+            Assert.Equal (3, enablingHighlight);
+            Assert.Equal (0, disablingHighlight);
+        }
+
+        view.Dispose ();
+
+        return;
+
+        void View_Highlight (object sender, HighlightEventArgs e)
+        {
+            if (e.HighlightStyle == HighlightStyle.None)
+            {
+                disablingHighlight++;
+            }
+            else
+            {
+                enablingHighlight++;
+            }
+        }
+    }
+
 }

+ 4 - 4
UnitTests/View/NavigationTests.cs

@@ -452,7 +452,7 @@ public class NavigationTests
 
         view.NewKeyDownEvent (Key.Space);
         Assert.True (wasClicked);
-        view.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
+        view.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
         Assert.False (wasClicked);
         Assert.True (view.Enabled);
         Assert.True (view.CanFocus);
@@ -461,7 +461,7 @@ public class NavigationTests
         view.Enabled = false;
         view.NewKeyDownEvent (Key.Space);
         Assert.False (wasClicked);
-        view.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
+        view.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
         Assert.False (wasClicked);
         Assert.False (view.Enabled);
         Assert.True (view.CanFocus);
@@ -491,7 +491,7 @@ public class NavigationTests
 
                                      win.NewKeyDownEvent (Key.Enter);
                                      Assert.True (wasClicked);
-                                     button.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
+                                     button.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
                                      Assert.False (wasClicked);
                                      Assert.True (button.Enabled);
                                      Assert.True (button.CanFocus);
@@ -503,7 +503,7 @@ public class NavigationTests
                                      win.Enabled = false;
                                      button.NewKeyDownEvent (Key.Enter);
                                      Assert.False (wasClicked);
-                                     button.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
+                                     button.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked });
                                      Assert.False (wasClicked);
                                      Assert.False (button.Enabled);
                                      Assert.True (button.CanFocus);

+ 3 - 3
UnitTests/View/ViewTests.cs

@@ -865,9 +865,9 @@ At 0,0
 
         //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown }));
         Assert.False (r.OnKeyUp (new Key { KeyCode = KeyCode.Null }));
-        Assert.False (r.OnMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
-        Assert.False (r.OnMouseEnter (new MouseEvent { Flags = MouseFlags.AllEvents }));
-        Assert.False (r.OnMouseLeave (new MouseEvent { Flags = MouseFlags.AllEvents }));
+        Assert.False (r.NewMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
+        Assert.False (r.NewMouseEnterEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
+        Assert.False (r.NewMouseLeaveEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
 
         var v1 = new View ();
         Assert.False (r.OnEnter (v1));

+ 5 - 85
UnitTests/Views/AllViewsTests.cs

@@ -58,14 +58,14 @@ public class AllViewsTests (ITestOutputHelper output)
     [Fact]
     public void AllViews_Enter_Leave_Events ()
     {
-        foreach (Type type in GetAllViewClasses ())
+        foreach (Type type in TestHelpers.GetAllViewClasses ())
         {
             output.WriteLine ($"Testing {type.Name}");
 
             Application.Init (new FakeDriver ());
 
             Toplevel top = new ();
-            View vType = CreateViewFromType (type, type.GetConstructor (Array.Empty<Type> ()));
+            View vType = TestHelpers.CreateViewFromType (type, type.GetConstructor (Array.Empty<Type> ()));
 
             if (vType == null)
             {
@@ -139,12 +139,13 @@ public class AllViewsTests (ITestOutputHelper output)
         }
     }
 
+
     [Fact]
     public void AllViews_Tests_All_Constructors ()
     {
         Application.Init (new FakeDriver ());
 
-        foreach (Type type in GetAllViewClasses ())
+        foreach (Type type in TestHelpers.GetAllViewClasses ())
         {
             Assert.True (Test_All_Constructors_Of_Type (type));
         }
@@ -152,18 +153,6 @@ public class AllViewsTests (ITestOutputHelper output)
         Application.Shutdown ();
     }
 
-    public static List<Type> GetAllViewClasses ()
-    {
-        return typeof (View).Assembly.GetTypes ()
-                            .Where (
-                                    myType => myType.IsClass
-                                              && !myType.IsAbstract
-                                              && myType.IsPublic
-                                              && myType.IsSubclassOf (typeof (View))
-                                   )
-                            .ToList ();
-    }
-
     //[Fact]
     //public void AllViews_HotKey_Works ()
     //{
@@ -180,7 +169,7 @@ public class AllViewsTests (ITestOutputHelper output)
     {
         foreach (ConstructorInfo ctor in type.GetConstructors ())
         {
-            View view = CreateViewFromType (type, ctor);
+            View view = TestHelpers.CreateViewFromType (type, ctor);
 
             if (view != null)
             {
@@ -243,73 +232,4 @@ public class AllViewsTests (ITestOutputHelper output)
             pTypes.Add (null);
         }
     }
-
-    private static View CreateViewFromType (Type type, ConstructorInfo ctor)
-    {
-        View viewType = null;
-
-        if (type.IsGenericType && type.IsTypeDefinition)
-        {
-            List<Type> gTypes = new ();
-
-            foreach (Type args in type.GetGenericArguments ())
-            {
-                gTypes.Add (typeof (object));
-            }
-
-            type = type.MakeGenericType (gTypes.ToArray ());
-
-            Assert.IsType (type, (View)Activator.CreateInstance (type));
-        }
-        else
-        {
-            ParameterInfo [] paramsInfo = ctor.GetParameters ();
-            Type paramType;
-            List<object> pTypes = new ();
-
-            if (type.IsGenericType)
-            {
-                foreach (Type args in type.GetGenericArguments ())
-                {
-                    paramType = args.GetType ();
-
-                    if (args.Name == "T")
-                    {
-                        pTypes.Add (typeof (object));
-                    }
-                    else
-                    {
-                        AddArguments (paramType, pTypes);
-                    }
-                }
-            }
-
-            foreach (ParameterInfo p in paramsInfo)
-            {
-                paramType = p.ParameterType;
-
-                if (p.HasDefaultValue)
-                {
-                    pTypes.Add (p.DefaultValue);
-                }
-                else
-                {
-                    AddArguments (paramType, pTypes);
-                }
-            }
-
-            if (type.IsGenericType && !type.IsTypeDefinition)
-            {
-                viewType = (View)Activator.CreateInstance (type);
-                Assert.IsType (type, viewType);
-            }
-            else
-            {
-                viewType = (View)ctor.Invoke (pTypes.ToArray ());
-                Assert.IsType (type, viewType);
-            }
-        }
-
-        return viewType;
-    }
 }

+ 88 - 142
UnitTests/Views/ButtonTests.cs

@@ -3,11 +3,8 @@ using Xunit.Abstractions;
 
 namespace Terminal.Gui.ViewsTests;
 
-public class ButtonTests
+public class ButtonTests (ITestOutputHelper output)
 {
-    private readonly ITestOutputHelper _output;
-    public ButtonTests (ITestOutputHelper output) { _output = output; }
-
     // Test that Title and Text are the same
     [Fact]
     public void Text_Mirrors_Title ()
@@ -15,10 +12,11 @@ public class ButtonTests
         var view = new Button ();
         view.Title = "Hello";
         Assert.Equal ("Hello", view.Title);
-        Assert.Equal ($"Hello", view.TitleTextFormatter.Text);
+        Assert.Equal ("Hello", view.TitleTextFormatter.Text);
 
         Assert.Equal ("Hello", view.Text);
         Assert.Equal ($"{CM.Glyphs.LeftBracket} Hello {CM.Glyphs.RightBracket}", view.TextFormatter.Text);
+        view.Dispose ();
     }
 
     [Fact]
@@ -30,7 +28,8 @@ public class ButtonTests
         Assert.Equal ($"{CM.Glyphs.LeftBracket} Hello {CM.Glyphs.RightBracket}", view.TextFormatter.Text);
 
         Assert.Equal ("Hello", view.Title);
-        Assert.Equal ($"Hello", view.TitleTextFormatter.Text);
+        Assert.Equal ("Hello", view.TitleTextFormatter.Text);
+        view.Dispose ();
     }
 
     // BUGBUG: This test is NOT a unit test and needs to be broken apart into 
@@ -105,7 +104,7 @@ public class ButtonTests
         tab.Add (ckbMatchWholeWord);
 
         var tabView = new TabView { Width = Dim.Fill (), Height = Dim.Fill () };
-        tabView.AddTab (new Tab { DisplayText = "Find", View = tab }, true);
+        tabView.AddTab (new () { DisplayText = "Find", View = tab }, true);
 
         var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
 
@@ -119,11 +118,11 @@ public class ButtonTests
         Application.Begin (top);
         ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
 
-        Assert.Equal (new Rectangle (0, 0, 54, 11), win.Frame);
-        Assert.Equal (new Rectangle (0, 0, 52, 9), tabView.Frame);
-        Assert.Equal (new Rectangle (0, 0, 50, 7), tab.Frame);
-        Assert.Equal (new Rectangle (0, 1, 8, 1), view.Frame);
-        Assert.Equal (new Rectangle (9, 1, 20, 1), txtToFind.Frame);
+        Assert.Equal (new (0, 0, 54, 11), win.Frame);
+        Assert.Equal (new (0, 0, 52, 9), tabView.Frame);
+        Assert.Equal (new (0, 0, 50, 7), tab.Frame);
+        Assert.Equal (new (0, 1, 8, 1), view.Frame);
+        Assert.Equal (new (9, 1, 20, 1), txtToFind.Frame);
 
         Assert.Equal (0, txtToFind.ScrollOffset);
         Assert.Equal (16, txtToFind.CursorPosition);
@@ -131,19 +130,12 @@ public class ButtonTests
         Assert.Equal (new (30, 1, 20, 1), btnFindNext.Frame);
         Assert.Equal (new (30, 2, 20, 1), btnFindPrevious.Frame);
         Assert.Equal (new (30, 4, 20, 1), btnCancel.Frame);
-//        Assert.Equal (new (0, 3, 12, 1), ckbMatchCase.Frame);
-//        Assert.Equal (new (0, 4, 18, 1), ckbMatchWholeWord.Frame);
+
+        //        Assert.Equal (new (0, 3, 12, 1), ckbMatchCase.Frame);
+        //        Assert.Equal (new (0, 4, 18, 1), ckbMatchWholeWord.Frame);
 
         var btn1 =
-            $"{
-                CM.Glyphs.LeftBracket
-            }{
-                CM.Glyphs.LeftDefaultIndicator
-            } Find Next {
-                CM.Glyphs.RightDefaultIndicator
-            }{
-                CM.Glyphs.RightBracket
-            }";
+            $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Find Next {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
         var btn2 = $"{CM.Glyphs.LeftBracket} Find Previous {CM.Glyphs.RightBracket}";
         var btn3 = $"{CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket}";
 
@@ -153,25 +145,16 @@ public class ButtonTests
 ││Find│                                              │
 ││    ╰─────────────────────────────────────────────╮│
 ││                                                  ││
-││   Find: Testing buttons.       {
-    btn1
-}   ││
-││                               {
-    btn2
-}  ││
-││{
-    CM.Glyphs.Checked
-} Match case                                      ││
-││{
-    CM.Glyphs.UnChecked
-} Match whole word                 {
-    btn3
-}     ││
+││   Find: Testing buttons.       {btn1}   ││
+││                               {btn2}  ││
+││{CM.Glyphs.Checked} Match case                                      ││
+││{CM.Glyphs.UnChecked} Match whole word                 {btn3}     ││
 │└──────────────────────────────────────────────────┘│
 └────────────────────────────────────────────────────┘
 ";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        view.Dispose ();
     }
 
     [Fact]
@@ -197,14 +180,12 @@ public class ButtonTests
         var expected = @$"
 ┌────────────────────────────┐
 │                            │
-│            {
-    btnTxt
-}│
+│            {btnTxt}│
 │                            │
 └────────────────────────────┘
 ";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
         Assert.True (btn.AutoSize);
         btn.Text = "Say Hello 你 changed";
@@ -215,14 +196,13 @@ public class ButtonTests
         expected = @$"
 ┌────────────────────────────┐
 │                            │
-│    {
-    btnTxt
-}│
+│    {btnTxt}│
 │                            │
 └────────────────────────────┘
 ";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        top.Dispose ();
     }
 
     [Fact]
@@ -244,16 +224,12 @@ public class ButtonTests
         var expected = @$"
 ┌────────────────────────────┐
 │                            │
-│      {
-    CM.Glyphs.LeftBracket
-} Say Hello 你 {
-    CM.Glyphs.RightBracket
-}      │
+│      {CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}      │
 │                            │
 └────────────────────────────┘
 ";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
         Assert.True (btn.AutoSize);
         btn.Text = "Say Hello 你 changed";
@@ -263,16 +239,13 @@ public class ButtonTests
         expected = @$"
 ┌────────────────────────────┐
 │                            │
-│  {
-    CM.Glyphs.LeftBracket
-} Say Hello 你 changed {
-    CM.Glyphs.RightBracket
-}  │
+│  {CM.Glyphs.LeftBracket} Say Hello 你 changed {CM.Glyphs.RightBracket}  │
 │                            │
 └────────────────────────────┘
 ";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        top.Dispose ();
     }
 
     [Fact]
@@ -284,7 +257,7 @@ public class ButtonTests
         var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
         win.Add (btn);
         var top = new Toplevel ();
-       top.Add (win);
+        top.Add (win);
 
         Assert.True (btn.AutoSize);
 
@@ -298,16 +271,13 @@ public class ButtonTests
         var expected = @$"
 ┌────────────────────────────┐
 │                            │
-│      {
-    CM.Glyphs.LeftBracket
-} Say Hello 你 {
-    CM.Glyphs.RightBracket
-}      │
+│      {CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}      │
 │                            │
 └────────────────────────────┘
 ";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        top.Dispose ();
     }
 
     [Fact]
@@ -347,22 +317,11 @@ public class ButtonTests
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @$"
-    {
-        CM.Glyphs.LeftBracket
-    } {
-        btn1.Text
-    } {
-        CM.Glyphs.RightBracket
-    }
-   {
-       CM.Glyphs.LeftBracket
-   } {
-       btn2.Text
-   } {
-       CM.Glyphs.RightBracket
-   }",
-                                                      _output
+    {CM.Glyphs.LeftBracket} {btn1.Text} {CM.Glyphs.RightBracket}
+   {CM.Glyphs.LeftBracket} {btn2.Text} {CM.Glyphs.RightBracket}",
+                                                      output
                                                      );
+        top.Dispose ();
     }
 
     [Fact]
@@ -394,10 +353,10 @@ public class ButtonTests
         Assert.Same (btn, sender);
         Assert.Equal (KeyCode.Y, args.OldKey);
         Assert.Equal (KeyCode.R, args.NewKey);
+        btn.Dispose ();
     }
 
     [Fact]
-    [AutoInitShutdown]
     public void Button_HotKeyChanged_EventFires_WithNone ()
     {
         var btn = new Button ();
@@ -415,6 +374,7 @@ public class ButtonTests
         Assert.Same (btn, sender);
         Assert.Equal (KeyCode.Null, args.OldKey);
         Assert.Equal (KeyCode.R, args.NewKey);
+        btn.Dispose ();
     }
 
     [Fact]
@@ -431,15 +391,15 @@ public class ButtonTests
         Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
         Assert.Equal ('_', btn.HotKeySpecifier.Value);
         Assert.True (btn.CanFocus);
-        Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Bounds);
-        Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Frame);
+        Assert.Equal (new (0, 0, 4, 1), btn.Bounds);
+        Assert.Equal (new (0, 0, 4, 1), btn.Frame);
         Assert.Equal ($"{CM.Glyphs.LeftBracket}  {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
         Assert.False (btn.IsDefault);
         Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
         Assert.Equal ('_', btn.HotKeySpecifier.Value);
         Assert.True (btn.CanFocus);
-        Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Bounds);
-        Assert.Equal (new Rectangle (0, 0, 4, 1), btn.Frame);
+        Assert.Equal (new (0, 0, 4, 1), btn.Bounds);
+        Assert.Equal (new (0, 0, 4, 1), btn.Frame);
 
         Assert.Equal (string.Empty, btn.Title);
         Assert.Equal (KeyCode.Null, btn.HotKey);
@@ -447,15 +407,12 @@ public class ButtonTests
         btn.Draw ();
 
         var expected = @$"
-{
-    CM.Glyphs.LeftBracket
-}  {
-    CM.Glyphs.RightBracket
-}
+{CM.Glyphs.LeftBracket}  {CM.Glyphs.RightBracket}
 ";
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        btn.Dispose ();
 
-        btn = new Button { Text = "_Test", IsDefault = true };
+        btn = new () { Text = "_Test", IsDefault = true };
         btn.BeginInit ();
         btn.EndInit ();
         Assert.Equal ('_', btn.HotKeySpecifier.Value);
@@ -463,40 +420,26 @@ public class ButtonTests
         Assert.Equal ("_Test", btn.Text);
 
         Assert.Equal (
-                      $"{
-                          CM.Glyphs.LeftBracket
-                      }{
-                          CM.Glyphs.LeftDefaultIndicator
-                      } Test {
-                          CM.Glyphs.RightDefaultIndicator
-                      }{
-                          CM.Glyphs.RightBracket
-                      }",
+                      $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Test {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}",
                       btn.TextFormatter.Format ()
                      );
         Assert.True (btn.IsDefault);
         Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
         Assert.True (btn.CanFocus);
-        Assert.Equal (new Rectangle (0, 0, 10, 1), btn.Bounds);
-        Assert.Equal (new Rectangle (0, 0, 10, 1), btn.Frame);
+        Assert.Equal (new (0, 0, 10, 1), btn.Bounds);
+        Assert.Equal (new (0, 0, 10, 1), btn.Frame);
         Assert.Equal (KeyCode.T, btn.HotKey);
 
-        btn = new Button { X = 1, Y = 2, Text = "_abc", IsDefault = true };
+        btn.Dispose ();
+
+        btn = new () { X = 1, Y = 2, Text = "_abc", IsDefault = true };
         btn.BeginInit ();
         btn.EndInit ();
         Assert.Equal ("_abc", btn.Text);
         Assert.Equal (Key.A, btn.HotKey);
 
         Assert.Equal (
-                      $"{
-                          CM.Glyphs.LeftBracket
-                      }{
-                          CM.Glyphs.LeftDefaultIndicator
-                      } abc {
-                          CM.Glyphs.RightDefaultIndicator
-                      }{
-                          CM.Glyphs.RightBracket
-                      }",
+                      $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} abc {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}",
                       btn.TextFormatter.Format ()
                      );
         Assert.True (btn.IsDefault);
@@ -508,20 +451,13 @@ public class ButtonTests
         btn.Draw ();
 
         expected = @$"
- {
-     CM.Glyphs.LeftBracket
- }{
-     CM.Glyphs.LeftDefaultIndicator
- } abc {
-     CM.Glyphs.RightDefaultIndicator
- }{
-     CM.Glyphs.RightBracket
- }
+ {CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} abc {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}
 ";
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
-        Assert.Equal (new Rectangle (0, 0, 9, 1), btn.Bounds);
-        Assert.Equal (new Rectangle (1, 2, 9, 1), btn.Frame);
+        Assert.Equal (new (0, 0, 9, 1), btn.Bounds);
+        Assert.Equal (new (1, 2, 9, 1), btn.Frame);
+        btn.Dispose ();
     }
 
     [Fact]
@@ -547,6 +483,7 @@ public class ButtonTests
         btn.HotKey = KeyCode.E;
         Assert.True (btn.NewKeyDownEvent (Key.E.WithAlt));
         Assert.True (clicked);
+        top.Dispose ();
     }
 
     /// <summary>
@@ -571,7 +508,7 @@ public class ButtonTests
         Application.Begin (top);
 
         // default keybinding is Space which results in keypress
-        Application.OnKeyDown (new Key ((KeyCode)' '));
+        Application.OnKeyDown (new ((KeyCode)' '));
         Assert.Equal (1, pressed);
 
         // remove the default keybinding (Space)
@@ -579,7 +516,7 @@ public class ButtonTests
         btn.KeyBindings.Clear (Command.Accept);
 
         // After clearing the default keystroke the Space button no longer does anything for the Button
-        Application.OnKeyDown (new Key ((KeyCode)' '));
+        Application.OnKeyDown (new ((KeyCode)' '));
         Assert.Equal (1, pressed);
 
         // Set a new binding of b for the click (Accept) event
@@ -601,6 +538,7 @@ public class ButtonTests
         // now pressing Shift-Alt-B should NOT call the button click event
         Application.OnKeyDown (Key.B.WithAlt.WithShift);
         Assert.Equal (2, pressed);
+        top.Dispose ();
     }
 
     [Fact]
@@ -659,7 +597,7 @@ public class ButtonTests
         Assert.True (clicked);
         clicked = false;
 
-        Assert.True (btn.NewKeyDownEvent (new Key ((KeyCode)'T')));
+        Assert.True (btn.NewKeyDownEvent (new ((KeyCode)'T')));
         Assert.True (clicked);
         clicked = false;
 
@@ -668,6 +606,8 @@ public class ButtonTests
         Assert.True (btn.NewKeyDownEvent (btn.HotKey));
         Assert.True (clicked);
         clicked = false;
+
+        top.Dispose ();
     }
 
     [Fact]
@@ -680,8 +620,10 @@ public class ButtonTests
         button.InvokeCommand (Command.HotKey);
 
         Assert.True (accepted);
+        button.Dispose ();
 
         return;
+
         void ButtonOnAccept (object sender, CancelEventArgs e) { accepted = true; }
     }
 
@@ -693,17 +635,21 @@ public class ButtonTests
 
         button.Accept += ButtonAccept;
 
-        var ret = button.InvokeCommand (Command.Accept);
+        bool? ret = button.InvokeCommand (Command.Accept);
         Assert.True (ret);
         Assert.True (acceptInvoked);
 
+        button.Dispose ();
+
         return;
+
         void ButtonAccept (object sender, CancelEventArgs e)
         {
             acceptInvoked = true;
             e.Cancel = true;
         }
     }
+
     [Fact]
     public void Setting_Empty_Text_Sets_HoKey_To_KeyNull ()
     {
@@ -726,6 +672,7 @@ public class ButtonTests
         btn.Text = "Te_st";
         Assert.Equal ("Te_st", btn.Text);
         Assert.Equal (KeyCode.S, btn.HotKey);
+        super.Dispose ();
     }
 
     [Fact]
@@ -740,6 +687,7 @@ public class ButtonTests
 
         // with cast
         Assert.Equal ("heyb", ((Button)b).Text);
+        b.Dispose ();
     }
 
     [Fact]
@@ -760,21 +708,20 @@ public class ButtonTests
         Assert.True (btn.IsInitialized);
         Assert.Equal ("Say Hello 你", btn.Text);
         Assert.Equal ($"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
-        Assert.Equal (new Rectangle (0, 0, 16, 1), btn.Bounds);
+        Assert.Equal (new (0, 0, 16, 1), btn.Bounds);
         var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
 
         var expected = @$"
 ┌────────────────────────────┐
 │                            │
-│      {
-    btnTxt
-}      │
+│      {btnTxt}      │
 │                            │
 └────────────────────────────┘
 ";
 
-        Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
-        Assert.Equal (new Rectangle (0, 0, 30, 5), pos);
+        Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        Assert.Equal (new (0, 0, 30, 5), pos);
+        top.Dispose ();
     }
 
     [Fact]
@@ -795,20 +742,19 @@ public class ButtonTests
         Assert.True (btn.IsInitialized);
         Assert.Equal ("Say Hello 你", btn.Text);
         Assert.Equal ($"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
-        Assert.Equal (new Rectangle (0, 0, 16, 1), btn.Bounds);
+        Assert.Equal (new (0, 0, 16, 1), btn.Bounds);
         var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
 
         var expected = @$"
 ┌────────────────────────────┐
 │                            │
-│      {
-    btnTxt
-}      │
+│      {btnTxt}      │
 │                            │
 └────────────────────────────┘
 ";
 
-        Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
-        Assert.Equal (new Rectangle (0, 0, 30, 5), pos);
+        Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+        Assert.Equal (new (0, 0, 30, 5), pos);
+        top.Dispose ();
     }
-}
+}

+ 3 - 3
UnitTests/Views/CheckBoxTests.cs

@@ -47,7 +47,7 @@ public class CheckBoxTests
         Assert.False (checkBox.Checked);
         Assert.True (checkBox.NewKeyDownEvent (Key.Space));
         Assert.True (checkBox.Checked);
-        Assert.True (checkBox.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (checkBox.NewMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }));
         Assert.False (checkBox.Checked);
 
         checkBox.AllowNullChecked = true;
@@ -60,11 +60,11 @@ public class CheckBoxTests
 {CM.Glyphs.NullChecked} Check this out 你",
                                                       _output
                                                      );
-        Assert.True (checkBox.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (checkBox.NewMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }));
         Assert.True (checkBox.Checked);
         Assert.True (checkBox.NewKeyDownEvent (Key.Space));
         Assert.False (checkBox.Checked);
-        Assert.True (checkBox.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (checkBox.NewMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }));
         Assert.Null (checkBox.Checked);
 
         checkBox.AllowNullChecked = false;

+ 2 - 2
UnitTests/Views/ColorPickerTests.cs

@@ -52,9 +52,9 @@ public class ColorPickerTests
         top.Add (colorPicker);
         Application.Begin (top);
 
-        Assert.False (colorPicker.OnMouseEvent (new MouseEvent ()));
+        Assert.False (colorPicker.NewMouseEvent (new MouseEvent ()));
 
-        Assert.True (colorPicker.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked, X = 4, Y = 1 }));
+        Assert.True (colorPicker.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Clicked, X = 4, Y = 1 }));
         Assert.Equal (ColorName.Blue, colorPicker.SelectedColor);
     }
 

+ 27 - 27
UnitTests/Views/ComboBoxTests.cs

@@ -146,7 +146,7 @@ public class ComboBoxTests
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -203,7 +203,7 @@ public class ComboBoxTests
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -240,7 +240,7 @@ public class ComboBoxTests
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -297,7 +297,7 @@ public class ComboBoxTests
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -308,7 +308,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = 1, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -319,7 +319,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = 1, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -332,7 +332,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = 2, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -342,14 +342,14 @@ public class ComboBoxTests
         Assert.Equal ("Three", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = 2, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -359,7 +359,7 @@ public class ComboBoxTests
         Assert.Equal ("Three", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -370,7 +370,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -398,14 +398,14 @@ public class ComboBoxTests
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -416,7 +416,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = -1, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -429,7 +429,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -440,7 +440,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = -1, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -453,7 +453,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -464,7 +464,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = cb.Frame.Width, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -477,7 +477,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -488,7 +488,7 @@ public class ComboBoxTests
 
         Assert.True (
                      cb.Subviews [1]
-                       .OnMouseEvent (
+                       .NewMouseEvent (
                                     new MouseEvent { X = 0, Y = cb.Frame.Height, Flags = MouseFlags.Button1Clicked }
                                    )
                     );
@@ -516,7 +516,7 @@ public class ComboBoxTests
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -673,7 +673,7 @@ Three ",
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -685,7 +685,7 @@ Three ",
         Assert.True (cb.Subviews [1].NewKeyDownEvent (Key.CursorDown));
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -695,7 +695,7 @@ Three ",
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -707,7 +707,7 @@ Three ",
         Assert.True (cb.Subviews [1].NewKeyDownEvent (Key.CursorUp));
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -735,7 +735,7 @@ Three ",
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );
@@ -792,7 +792,7 @@ Three ",
         Assert.Equal ("", cb.Text);
 
         Assert.True (
-                     cb.OnMouseEvent (
+                     cb.NewMouseEvent (
                                     new MouseEvent { X = cb.Bounds.Right - 1, Y = 0, Flags = MouseFlags.Button1Pressed }
                                    )
                     );

+ 19 - 51
UnitTests/Views/ContextMenuTests.cs

@@ -107,11 +107,11 @@ public class ContextMenuTests
         Assert.True (ContextMenu.IsShow);
         Assert.Equal (cm.MenuBar, Application.MouseGrabView);
         Assert.False (menu.IsMenuOpen);
-        Assert.False (menu.OnMouseEvent (new MouseEvent { X = 1, Flags = MouseFlags.ReportMousePosition, View = menu }));
+        Assert.False (menu.NewMouseEvent(new MouseEvent { X = 1, Flags = MouseFlags.ReportMousePosition, View = menu }));
         Assert.True (ContextMenu.IsShow);
         Assert.Equal (cm.MenuBar, Application.MouseGrabView);
         Assert.False (menu.IsMenuOpen);
-        Assert.True (menu.OnMouseEvent (new MouseEvent { X = 1, Flags = MouseFlags.Button1Clicked, View = menu }));
+        Assert.True (menu.NewMouseEvent(new MouseEvent { X = 1, Flags = MouseFlags.Button1Clicked, View = menu }));
         Assert.False (ContextMenu.IsShow);
         Assert.Equal (menu, Application.MouseGrabView);
         Assert.True (menu.IsMenuOpen);
@@ -269,11 +269,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 8, Y = 2, Flags = MouseFlags.Button3Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 8, Y = 2, Flags = MouseFlags.Button3Clicked });
 
         var firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -355,11 +351,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 9, Y = 3, Flags = MouseFlags.Button3Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 9, Y = 3, Flags = MouseFlags.Button3Clicked });
 
         var firstIteration = false;
         Application.RunIteration (ref rsDialog, ref firstIteration);
@@ -414,11 +406,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 9, Y = 3, Flags = MouseFlags.Button3Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 9, Y = 3, Flags = MouseFlags.Button3Clicked });
 
         var firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -517,7 +505,7 @@ public class ContextMenuTests
         top.RequestStop ();
         Assert.False (ContextMenu.IsShow);
     }
-    
+
     [Fact]
     [AutoInitShutdown]
     public void Key_Open_And_Close_The_ContextMenu ()
@@ -653,7 +641,7 @@ public class ContextMenuTests
 
         Assert.True (
                      top.Subviews [0]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 0, Y = 3, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
                                     )
                     );
@@ -701,7 +689,7 @@ public class ContextMenuTests
 
         Assert.True (
                      top.Subviews [0]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 30, Y = 3, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
                                     )
                     );
@@ -748,7 +736,7 @@ public class ContextMenuTests
 
         Assert.True (
                      top.Subviews [0]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 30, Y = 3, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
                                     )
                     );
@@ -792,7 +780,7 @@ public class ContextMenuTests
 
         Assert.True (
                      top.Subviews [0]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 30, Y = 3, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
                                     )
                     );
@@ -836,7 +824,7 @@ public class ContextMenuTests
 
         Assert.True (
                      top.Subviews [0]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 30, Y = 3, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
                                     )
                     );
@@ -879,12 +867,12 @@ public class ContextMenuTests
         top.Add (lbl);
         Application.Begin (top);
 
-        Assert.True (lbl.OnMouseEvent (new MouseEvent { Flags = cm.MouseFlags }));
+        Assert.True (lbl.NewMouseEvent (new MouseEvent { Flags = cm.MouseFlags }));
         Assert.Equal ("Replaced", lbl.Text);
 
         lbl.Text = "Original";
         cm.MouseFlags = MouseFlags.Button2Clicked;
-        Assert.True (lbl.OnMouseEvent (new MouseEvent { Flags = cm.MouseFlags }));
+        Assert.True (lbl.NewMouseEvent (new MouseEvent { Flags = cm.MouseFlags }));
         Assert.Equal ("Replaced", lbl.Text);
     }
 
@@ -1326,11 +1314,7 @@ public class ContextMenuTests
                                                      );
 
         // X=5 is the border and so need to use at least one more
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.Button1Clicked });
 
         var firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -1348,11 +1332,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 6, Y = 12, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 6, Y = 12, Flags = MouseFlags.Button1Clicked });
 
         firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -1371,7 +1351,7 @@ public class ContextMenuTests
         Application.End (rs);
     }
 
-        [Fact]
+    [Fact]
     [AutoInitShutdown]
     public void UseSubMenusSingleFrame_False_By_Mouse ()
     {
@@ -1423,11 +1403,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.ReportMousePosition }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.ReportMousePosition });
 
         var firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -1444,11 +1420,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 6, Y = 14, Flags = MouseFlags.ReportMousePosition }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 6, Y = 14, Flags = MouseFlags.ReportMousePosition });
 
         firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -1466,11 +1438,7 @@ public class ContextMenuTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.ReportMousePosition }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.ReportMousePosition });
 
         firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);

+ 1 - 1
UnitTests/Views/LabelTests.cs

@@ -67,7 +67,7 @@ public class LabelTests
         Assert.False (label.HasFocus);
         Assert.False (nextSubview.HasFocus);
 
-        label.OnMouseEvent (new MouseEvent () { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked });
+        label.NewMouseEvent (new MouseEvent () { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked });
         Assert.False (label.HasFocus);
         Assert.True (nextSubview.HasFocus);
     }

+ 10 - 15
UnitTests/Views/ListViewTests.cs

@@ -425,7 +425,7 @@ Item 6",
     public void Accept_Command_Accepts_and_Opens_Selected_Item ()
     {
         List<string> source = ["One", "Two", "Three"];
-        var listView = new ListView {Source = new ListWrapper (source) };
+        var listView = new ListView { Source = new ListWrapper (source) };
         listView.SelectedItem = 0;
 
         var accepted = false;
@@ -719,48 +719,43 @@ Item 6",
 │Three│
 └─────┘", _output);
 
-        Application.OnMouseEvent (new (new ()
-        {
-            X = 0,
-            Y = 0,
-            Flags = MouseFlags.Button1Clicked
-        }));
+        Application.OnMouseEvent (new () { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked });
         Assert.Equal ("", selected);
         Assert.Equal (-1, lv.SelectedItem);
 
-        Application.OnMouseEvent (new (new ()
+        Application.OnMouseEvent (new ()
         {
             X = 1,
             Y = 1,
             Flags = MouseFlags.Button1Clicked
-        }));
+        });
         Assert.Equal ("One", selected);
         Assert.Equal (0, lv.SelectedItem);
 
-        Application.OnMouseEvent (new (new ()
+        Application.OnMouseEvent (new ()
         {
             X = 1,
             Y = 2,
             Flags = MouseFlags.Button1Clicked
-        }));
+        });
         Assert.Equal ("Two", selected);
         Assert.Equal (1, lv.SelectedItem);
 
-        Application.OnMouseEvent (new (new ()
+        Application.OnMouseEvent (new ()
         {
             X = 1,
             Y = 3,
             Flags = MouseFlags.Button1Clicked
-        }));
+        });
         Assert.Equal ("Three", selected);
         Assert.Equal (2, lv.SelectedItem);
 
-        Application.OnMouseEvent (new (new ()
+        Application.OnMouseEvent (new ()
         {
             X = 1,
             Y = 4,
             Flags = MouseFlags.Button1Clicked
-        }));
+        });
         Assert.Equal ("Three", selected);
         Assert.Equal (2, lv.SelectedItem);
     }

+ 43 - 59
UnitTests/Views/MenuBarTests.cs

@@ -37,13 +37,13 @@ public class MenuBarTests
         Assert.True (mi.Checked);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
 
         Assert.True (
-                     menu._openMenu.OnMouseEvent (
+                     menu._openMenu.NewMouseEvent (
                                                 new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked, View = menu._openMenu }
                                                )
                     );
@@ -57,7 +57,7 @@ public class MenuBarTests
         Assert.Null (mi.Checked);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -75,7 +75,7 @@ public class MenuBarTests
                                                      );
 
         Assert.True (
-                     menu._openMenu.OnMouseEvent (
+                     menu._openMenu.NewMouseEvent (
                                                 new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked, View = menu._openMenu }
                                                )
                     );
@@ -87,13 +87,13 @@ public class MenuBarTests
         Assert.False (mi.Checked);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
 
         Assert.True (
-                     menu._openMenu.OnMouseEvent (
+                     menu._openMenu.NewMouseEvent (
                                                 new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Clicked, View = menu._openMenu }
                                                )
                     );
@@ -296,7 +296,7 @@ public class MenuBarTests
                                               );
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -317,7 +317,7 @@ public class MenuBarTests
 
         Assert.True (
                      top.Subviews [1]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 0, Y = 2, Flags = MouseFlags.Button1Clicked, View = top.Subviews [1] }
                                     )
                     );
@@ -338,7 +338,7 @@ public class MenuBarTests
 
         Assert.True (
                      top.Subviews [1]
-                        .OnMouseEvent (
+                        .NewMouseEvent (
                                      new MouseEvent { X = 0, Y = 2, Flags = MouseFlags.ReportMousePosition, View = top.Subviews [1] }
                                     )
                     );
@@ -516,11 +516,7 @@ public class MenuBarTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 20, Y = 5, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 20, Y = 5, Flags = MouseFlags.Button1Clicked });
 
         firstIteration = false;
 
@@ -553,11 +549,7 @@ public class MenuBarTests
         {
             menu.OpenMenu ();
 
-            Application.OnMouseEvent (
-                                      new MouseEventEventArgs (
-                                                               new MouseEvent { X = 20, Y = 5 + i, Flags = MouseFlags.Button1Clicked }
-                                                              )
-                                     );
+            Application.OnMouseEvent (new MouseEvent { X = 20, Y = 5 + i, Flags = MouseFlags.Button1Clicked });
 
             firstIteration = false;
             Application.RunIteration (ref rsDialog, ref firstIteration);
@@ -712,11 +704,7 @@ public class MenuBarTests
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 20, Y = 5, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 20, Y = 5, Flags = MouseFlags.Button1Clicked });
 
         firstIteration = false;
 
@@ -738,11 +726,7 @@ public class MenuBarTests
         {
             menu.OpenMenu ();
 
-            Application.OnMouseEvent (
-                                      new MouseEventEventArgs (
-                                                               new MouseEvent { X = 20, Y = 5 + i, Flags = MouseFlags.Button1Clicked }
-                                                              )
-                                     );
+            Application.OnMouseEvent (new MouseEvent { X = 20, Y = 5 + i, Flags = MouseFlags.Button1Clicked });
 
             firstIteration = false;
             Application.RunIteration (ref rs, ref firstIteration);
@@ -1473,13 +1457,13 @@ wo
         top.Add (menu);
         Application.Begin (top);
 
-        Assert.True (menu.OnMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
+        Assert.True (menu.NewMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
         Assert.True (menu.IsMenuOpen);
         top.Draw ();
 
         TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), _output);
 
-        Assert.True (menu.OnMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
+        Assert.True (menu.NewMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
         Assert.False (menu.IsMenuOpen);
         top.Draw ();
         TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, _output);
@@ -2189,7 +2173,7 @@ wo
 
         // open the menu
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -2198,7 +2182,7 @@ wo
         Assert.Equal ("_New", miCurrent.Title);
 
         Assert.True (
-                     mCurrent.OnMouseEvent (
+                     mCurrent.NewMouseEvent (
                                           new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.ReportMousePosition, View = mCurrent }
                                          )
                     );
@@ -2207,7 +2191,7 @@ wo
         Assert.Equal ("_New", miCurrent.Title);
 
         Assert.True (
-                     mCurrent.OnMouseEvent (
+                     mCurrent.NewMouseEvent (
                                           new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.ReportMousePosition, View = mCurrent }
                                          )
                     );
@@ -2216,7 +2200,7 @@ wo
         Assert.Equal ("_New", miCurrent.Title);
 
         Assert.True (
-                     mCurrent.OnMouseEvent (
+                     mCurrent.NewMouseEvent (
                                           new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.ReportMousePosition, View = mCurrent }
                                          )
                     );
@@ -2226,7 +2210,7 @@ wo
 
         // close the menu
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -2394,7 +2378,7 @@ Edit
 
         // Click on Edit
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 10, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -2404,7 +2388,7 @@ Edit
 
         // Click on Paste
         Assert.True (
-                     mCurrent.OnMouseEvent (
+                     mCurrent.NewMouseEvent (
                                           new MouseEvent { X = 10, Y = 2, Flags = MouseFlags.ReportMousePosition, View = mCurrent }
                                          )
                     );
@@ -2418,7 +2402,7 @@ Edit
             {
                 // Edit menu is open. Click on the menu at Y = -1, which is outside the menu.
                 Assert.False (
-                              mCurrent.OnMouseEvent (
+                              mCurrent.NewMouseEvent (
                                                      new MouseEvent { X = 10, Y = i, Flags = MouseFlags.ReportMousePosition, View = menu }
                                                     )
                              );
@@ -2427,7 +2411,7 @@ Edit
             {
                 // Edit menu is open. Click on the menu at Y = i.
                 Assert.True (
-                             mCurrent.OnMouseEvent (
+                             mCurrent.NewMouseEvent (
                                                   new MouseEvent { X = 10, Y = i, Flags = MouseFlags.ReportMousePosition, View = mCurrent }
                                                  )
                             );
@@ -2590,14 +2574,14 @@ Edit
         Application.Begin (top);
 
         Assert.True (tf.HasFocus);
-        Assert.True (menu.OnMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
+        Assert.True (menu.NewMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
         Assert.True (menu.IsMenuOpen);
         Assert.False (tf.HasFocus);
         top.Draw ();
         TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), _output);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 8, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }
                                      )
                     );
@@ -2607,7 +2591,7 @@ Edit
         TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), _output);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }
                                      )
                     );
@@ -2617,7 +2601,7 @@ Edit
         TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (2), _output);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 8, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }
                                      )
                     );
@@ -2627,7 +2611,7 @@ Edit
         TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, _output);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.ReportMousePosition, View = menu }
                                      )
                     );
@@ -2636,7 +2620,7 @@ Edit
         top.Draw ();
         TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), _output);
 
-        Assert.True (menu.OnMouseEvent (new MouseEvent { X = 8, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
+        Assert.True (menu.NewMouseEvent (new MouseEvent { X = 8, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }));
         Assert.False (menu.IsMenuOpen);
         Assert.True (tf.HasFocus);
         top.Draw ();
@@ -2969,7 +2953,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 8, 1), pos);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -2988,7 +2972,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 10, 6), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent
                                        {
                                            X = 1, Y = 2, Flags = MouseFlags.ReportMousePosition, View = Application.Top.Subviews [1]
@@ -3011,7 +2995,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 25, 7), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent
                                        {
                                            X = 1, Y = 1, Flags = MouseFlags.ReportMousePosition, View = Application.Top.Subviews [1]
@@ -3033,7 +3017,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 10, 6), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 70, Y = 2, Flags = MouseFlags.Button1Clicked, View = Application.Top }
                                       )
                      );
@@ -3279,7 +3263,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 8, 1), pos);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -3298,7 +3282,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 10, 6), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [1] }
                                       )
                      );
@@ -3318,7 +3302,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 15, 7), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [2] }
                                       )
                      );
@@ -3337,7 +3321,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 10, 6), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 70, Y = 2, Flags = MouseFlags.Button1Clicked, View = Application.Top }
                                       )
                      );
@@ -3475,7 +3459,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 8, 1), pos);
 
         Assert.True (
-                     menu.OnMouseEvent (
+                     menu.NewMouseEvent (
                                       new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1Pressed, View = menu }
                                      )
                     );
@@ -3492,7 +3476,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 8, 4), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [1] }
                                       )
                      );
@@ -3510,7 +3494,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 13, 5), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [2] }
                                       )
                      );
@@ -3527,7 +3511,7 @@ Edit
         Assert.Equal (new Rectangle (1, 0, 8, 4), pos);
 
         Assert.False (
-                      menu.OnMouseEvent (
+                      menu.NewMouseEvent (
                                        new MouseEvent { X = 70, Y = 2, Flags = MouseFlags.Button1Clicked, View = Application.Top }
                                       )
                      );
@@ -3710,7 +3694,7 @@ Edit
         top.Add (menu, btn);
         Application.Begin (top);
 
-        Application.OnMouseEvent (new (new () { X = 0, Y = 4, Flags = MouseFlags.Button1Clicked }));
+        Application.OnMouseEvent (new () { X = 0, Y = 4, Flags = MouseFlags.Button1Clicked });
         Assert.True (btnClicked);
     }
 }

+ 13 - 76
UnitTests/Views/OverlappedTests.cs

@@ -909,46 +909,10 @@ public class OverlappedTests
         Assert.Equal (win2, Application.Current);
         Assert.Equal (win1, rsWin1.Toplevel);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
- ┌───┐
- │   │
- │   │
- │   │
- └───┘",
-                                                      _output
-                                                     );
-
-        Attribute [] attributes =
-        {
-            // 0
-            Colors.ColorSchemes ["TopLevel"].Normal,
-
-            // 1
-            Colors.ColorSchemes ["Base"].Normal
-        };
-
-        TestHelpers.AssertDriverAttributesAre (
-                                               @"
-0000000000
-0111110000
-0111110000
-0111110000
-0111110000
-0111110000
-0000000000
-0000000000
-0000000000
-0000000000",
-                                               null,
-                                               attributes
-                                              );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.Button1Pressed }
-                                                          )
-                                 );
+        // Tests that rely on visuals are too fragile. If border style changes they break.
+        // Instead we should just rely on the test above.
+
+        Application.OnMouseEvent (new MouseEvent { X = 1, Y = 1, Flags = MouseFlags.Button1Pressed });
         Assert.Equal (win2.Border, Application.MouseGrabView);
 
         Application.RunIteration (ref rsOverlapped, ref firstIteration);
@@ -960,17 +924,13 @@ public class OverlappedTests
         Assert.Equal (win2, Application.Current);
         Assert.Equal (win1, rsWin1.Toplevel);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 2,
-                                                               Y = 2,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = 2,
+            Y = 2,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         Application.RunIteration (ref rsOverlapped, ref firstIteration);
 
@@ -981,31 +941,8 @@ public class OverlappedTests
         Assert.Equal (win2, Application.Current);
         Assert.Equal (win1, rsWin1.Toplevel);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-  ┌───┐
-  │   │
-  │   │
-  │   │
-  └───┘",
-                                                      _output
-                                                     );
-
-        TestHelpers.AssertDriverAttributesAre (
-                                               @"
-0000000000
-0000000000
-0011111000
-0011111000
-0011111000
-0011111000
-0011111000
-0000000000
-0000000000
-0000000000",
-                                               null,
-                                               attributes
-                                              );
+        // Tests that rely on visuals are too fragile. If border style changes they break.
+        // Instead we should just rely on the test above.
 
         // This will end the win2 and not the overlapped
         Application.End (rsOverlapped);

+ 2 - 10
UnitTests/Views/ScrollBarViewTests.cs

@@ -1154,11 +1154,7 @@ This is a test             ",
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.Button1Clicked });
 
         Assert.Null (Application.MouseGrabView);
         Assert.True (clicked);
@@ -1186,11 +1182,7 @@ This is a test             ",
                                                       _output
                                                      );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 15, Y = 0, Flags = MouseFlags.Button1Clicked });
 
         Assert.Null (Application.MouseGrabView);
         Assert.True (clicked);

+ 1 - 1
UnitTests/Views/StatusBarTests.cs

@@ -163,7 +163,7 @@ CTRL-O Open {
                                      {
                                          Assert.Equal ("Quiting...", msg);
                                          msg = "";
-                                         sb.OnMouseEvent (new MouseEvent { X = 1, Y = 24, Flags = MouseFlags.Button1Clicked });
+                                         sb.NewMouseEvent (new MouseEvent { X = 1, Y = 24, Flags = MouseFlags.Button1Clicked });
                                      }
                                      else
                                      {

+ 10 - 28
UnitTests/Views/TabViewTests.cs

@@ -141,32 +141,26 @@ public class TabViewTests
         top.Add (tv);
         Application.Begin (top);
 
-        MouseEventEventArgs args;
+        MouseEvent args;
 
         // Waving mouse around does not trigger click
         for (var i = 0; i < 100; i++)
         {
-            args = new MouseEventEventArgs (
-                                            new MouseEvent { X = i, Y = 1, Flags = MouseFlags.ReportMousePosition }
-                                           );
+            args = new MouseEvent { X = i, Y = 1, Flags = MouseFlags.ReportMousePosition };
             Application.OnMouseEvent (args);
             Application.Refresh ();
             Assert.Null (clicked);
             Assert.Equal (tab1, tv.SelectedTab);
         }
 
-        args = new MouseEventEventArgs (
-                                        new MouseEvent { X = 3, Y = 1, Flags = MouseFlags.Button1Clicked }
-                                       );
+        args = new MouseEvent { X = 3, Y = 1, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
         Assert.Equal (tab1, clicked);
         Assert.Equal (tab1, tv.SelectedTab);
 
         // Click to tab2
-        args = new MouseEventEventArgs (
-                                        new MouseEvent { X = 6, Y = 1, Flags = MouseFlags.Button1Clicked }
-                                       );
+        args = new MouseEvent { X = 6, Y = 1, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
         Assert.Equal (tab2, clicked);
@@ -179,9 +173,7 @@ public class TabViewTests
                              e.MouseEvent.Handled = true;
                          };
 
-        args = new MouseEventEventArgs (
-                                        new MouseEvent { X = 3, Y = 1, Flags = MouseFlags.Button1Clicked }
-                                       );
+        args = new MouseEvent { X = 3, Y = 1, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
 
@@ -189,9 +181,7 @@ public class TabViewTests
         Assert.Equal (tab1, clicked);
         Assert.Equal (tab2, tv.SelectedTab);
 
-        args = new MouseEventEventArgs (
-                                        new MouseEvent { X = 12, Y = 1, Flags = MouseFlags.Button1Clicked }
-                                       );
+        args = new MouseEvent { X = 12, Y = 1, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
 
@@ -245,9 +235,7 @@ public class TabViewTests
         Application.Begin (top);
 
         // Click the right arrow
-        var args = new MouseEventEventArgs (
-                                            new MouseEvent { X = 6, Y = 2, Flags = MouseFlags.Button1Clicked }
-                                           );
+        var args = new MouseEvent { X = 6, Y = 2, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
         Assert.Null (clicked);
@@ -267,9 +255,7 @@ public class TabViewTests
                                             );
 
         // Click the left arrow
-        args = new MouseEventEventArgs (
-                                        new MouseEvent { X = 0, Y = 2, Flags = MouseFlags.Button1Clicked }
-                                       );
+        args = new MouseEvent { X = 0, Y = 2, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
         Assert.Null (clicked);
@@ -339,9 +325,7 @@ public class TabViewTests
         Application.Begin (top);
 
         // Click the right arrow
-        var args = new MouseEventEventArgs (
-                                            new MouseEvent { X = 7, Y = 3, Flags = MouseFlags.Button1Clicked }
-                                           );
+        var args = new MouseEvent { X = 7, Y = 3, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
         Assert.Null (clicked);
@@ -363,9 +347,7 @@ public class TabViewTests
                                             );
 
         // Click the left arrow
-        args = new MouseEventEventArgs (
-                                        new MouseEvent { X = 1, Y = 3, Flags = MouseFlags.Button1Clicked }
-                                       );
+        args = new MouseEvent { X = 1, Y = 3, Flags = MouseFlags.Button1Clicked };
         Application.OnMouseEvent (args);
         Application.Refresh ();
         Assert.Null (clicked);

+ 7 - 7
UnitTests/Views/TableViewTests.cs

@@ -2196,7 +2196,7 @@ public class TableViewTests
         tv.MultiSelect = true;
 
         // Clicking in bottom row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 4, Flags = MouseFlags.Button1Clicked }
                       );
 
@@ -2204,7 +2204,7 @@ public class TableViewTests
         Assert.Equal (2, tv.SelectedRow);
 
         // shift clicking top row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl }
                       );
 
@@ -2268,7 +2268,7 @@ public class TableViewTests
         tv.Style.AlwaysUseNormalColorForVerticalCellLines = true;
 
         // Clicking in bottom row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 4, Flags = MouseFlags.Button1Clicked }
                       );
 
@@ -2323,7 +2323,7 @@ public class TableViewTests
         tv.Style.ShowVerticalHeaderLines = false;
 
         // Clicking in bottom row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 4, Flags = MouseFlags.Button1Clicked }
                       );
 
@@ -2376,7 +2376,7 @@ A B C
         tv.Style.ShowHorizontalBottomline = true;
 
         // Clicking in bottom row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 4, Flags = MouseFlags.Button1Clicked }
                       );
 
@@ -2557,7 +2557,7 @@ A B C
         tv.MultiSelect = true;
 
         // Clicking in bottom row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 3, Flags = MouseFlags.Button1Clicked }
                       );
 
@@ -2565,7 +2565,7 @@ A B C
         Assert.Equal (1, tv.SelectedRow);
 
         // shift clicking top row
-        tv.OnMouseEvent (
+        tv.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked | MouseFlags.ButtonShift }
                       );
 

+ 13 - 13
UnitTests/Views/TextFieldTests.cs

@@ -122,7 +122,7 @@ public class TextFieldTests
         Assert.False (fv.CanFocus);
         Assert.False (fv.HasFocus);
 
-        tf.OnMouseEvent (
+        tf.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked }
                       );
 
@@ -136,7 +136,7 @@ public class TextFieldTests
         fv.CanFocus = true;
         tf.CanFocus = true;
 
-        tf.OnMouseEvent (
+        tf.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked }
                       );
 
@@ -148,7 +148,7 @@ public class TextFieldTests
 
         fv.CanFocus = false;
 
-        tf.OnMouseEvent (
+        tf.NewMouseEvent (
                        new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked }
                       );
 
@@ -484,7 +484,7 @@ public class TextFieldTests
         tf.Text = "Les Misérables movie.";
 
         Assert.True (
-                     tf.OnMouseEvent (
+                     tf.NewMouseEvent (
                                     new MouseEvent { X = 7, Y = 1, Flags = MouseFlags.Button1DoubleClicked, View = tf }
                                    )
                     );
@@ -1039,13 +1039,13 @@ public class TextFieldTests
 
         var mouseEvent = new MouseEvent { Flags = MouseFlags.Button1Clicked, View = tf };
 
-        Application.OnMouseEvent (new MouseEventEventArgs (mouseEvent));
+        Application.OnMouseEvent (mouseEvent);
         Assert.Equal (1, clickCounter);
 
         // Get a fresh instance that represents a right click.
         // Should be ignored because of SuppressRightClick callback
         mouseEvent = new MouseEvent { Flags = MouseFlags.Button3Clicked, View = tf };
-        Application.OnMouseEvent (new MouseEventEventArgs (mouseEvent));
+        Application.OnMouseEvent (mouseEvent);
         Assert.Equal (1, clickCounter);
 
         Application.MouseEvent -= HandleRightClick;
@@ -1058,14 +1058,14 @@ public class TextFieldTests
         // This call causes the context menu to pop, and MouseEvent() returns true.
         // Thus, the clickCounter is NOT incremented.
         // Which is correct, because the user did NOT click with the left mouse button.
-        Application.OnMouseEvent (new MouseEventEventArgs (mouseEvent));
+        Application.OnMouseEvent (mouseEvent);
         Assert.Equal (1, clickCounter);
 
         return;
 
-        void HandleRightClick (object sender, MouseEventEventArgs arg)
+        void HandleRightClick (object sender, MouseEvent arg)
         {
-            if (arg.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked))
+            if (arg.Flags.HasFlag (MouseFlags.Button3Clicked))
             {
                 arg.Handled = true;
             }
@@ -1152,12 +1152,12 @@ public class TextFieldTests
 
         var ev = new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1DoubleClicked };
 
-        tf.OnMouseEvent (ev);
+        tf.NewMouseEvent (ev);
         Assert.Equal (1, tf.SelectedLength);
 
         ev = new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked };
 
-        tf.OnMouseEvent (ev);
+        tf.NewMouseEvent (ev);
         Assert.Equal (1, tf.SelectedLength);
     }
 
@@ -1537,14 +1537,14 @@ public class TextFieldTests
         Assert.Equal ("m", runes [idx].ToString ());
 
         Assert.True (
-                     tf.OnMouseEvent (
+                     tf.NewMouseEvent (
                                     new MouseEvent { X = idx, Y = 1, Flags = MouseFlags.Button1DoubleClicked, View = tf }
                                    )
                     );
         Assert.Equal ("movie.", tf.SelectedText);
 
         Assert.True (
-                     tf.OnMouseEvent (
+                     tf.NewMouseEvent (
                                     new MouseEvent { X = idx + 1, Y = 1, Flags = MouseFlags.Button1DoubleClicked, View = tf }
                                    )
                     );

+ 1 - 1
UnitTests/Views/TextValidateFieldTests.cs

@@ -322,7 +322,7 @@ public class TextValidateField_NET_Provider_Tests
         Assert.False (field.IsValid);
         Assert.Equal ("--(1   )--", field.Provider.Text);
 
-        field.OnMouseEvent (new MouseEvent { X = 25, Flags = MouseFlags.Button1Pressed });
+        field.NewMouseEvent (new MouseEvent { X = 25, Flags = MouseFlags.Button1Pressed });
 
         field.NewKeyDownEvent (Key.D1);
 

+ 17 - 17
UnitTests/Views/TextViewTests.cs

@@ -160,7 +160,7 @@ public class TextViewTests
         Assert.False (fv.CanFocus);
         Assert.False (fv.HasFocus);
 
-        tv.OnMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked });
+        tv.NewMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked });
 
         Assert.Empty (tv.SelectedText);
         Assert.False (tv.CanFocus);
@@ -171,7 +171,7 @@ public class TextViewTests
         Assert.Throws<InvalidOperationException> (() => tv.CanFocus = true);
         fv.CanFocus = true;
         tv.CanFocus = true;
-        tv.OnMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked });
+        tv.NewMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked });
 
         Assert.Equal ("some ", tv.SelectedText);
         Assert.True (tv.CanFocus);
@@ -180,7 +180,7 @@ public class TextViewTests
         Assert.True (fv.HasFocus);
 
         fv.CanFocus = false;
-        tv.OnMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked });
+        tv.NewMouseEvent (new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked });
 
         Assert.Equal ("some ", tv.SelectedText); // Setting CanFocus to false don't change the SelectedText
         Assert.False (tv.CanFocus);
@@ -1072,7 +1072,7 @@ This is the second line.
 
         for (var i = 0; i < 12; i++)
         {
-            tv.OnMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight });
+            tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight });
             tv.PositionCursor ();
             Assert.Equal (Math.Min (i + 1, 11), tv.LeftColumn);
             Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility);
@@ -1080,7 +1080,7 @@ This is the second line.
 
         for (var i = 11; i > 0; i--)
         {
-            tv.OnMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledLeft });
+            tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledLeft });
             tv.PositionCursor ();
             Assert.Equal (i - 1, tv.LeftColumn);
 
@@ -1115,7 +1115,7 @@ This is the second line.
 
         for (var i = 0; i < 12; i++)
         {
-            tv.OnMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown });
+            tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown });
             tv.PositionCursor ();
             Assert.Equal (i + 1, tv.TopRow);
             Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility);
@@ -1123,7 +1123,7 @@ This is the second line.
 
         for (var i = 12; i > 0; i--)
         {
-            tv.OnMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledUp });
+            tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledUp });
             tv.PositionCursor ();
             Assert.Equal (i - 1, tv.TopRow);
 
@@ -6788,7 +6788,7 @@ This is the second line.
         Assert.Equal ("TAB to jump between text fields.", _textView.Text);
 
         Assert.True (
-                     _textView.OnMouseEvent (
+                     _textView.NewMouseEvent (
                                            new MouseEvent { X = 12, Y = 0, Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift }
                                           )
                     );
@@ -6798,7 +6798,7 @@ This is the second line.
         Assert.True (_textView.Selecting);
         Assert.Equal ("TAB to jump ", _textView.SelectedText);
 
-        Assert.True (_textView.OnMouseEvent (new MouseEvent { X = 12, Y = 0, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (_textView.NewMouseEvent (new MouseEvent { X = 12, Y = 0, Flags = MouseFlags.Button1Clicked }));
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (new Point (12, 0), _textView.CursorPosition);
@@ -6806,7 +6806,7 @@ This is the second line.
         Assert.Equal ("TAB to jump ", _textView.SelectedText);
 
         Assert.True (
-                     _textView.OnMouseEvent (
+                     _textView.NewMouseEvent (
                                            new MouseEvent { X = 19, Y = 0, Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift }
                                           )
                     );
@@ -6816,7 +6816,7 @@ This is the second line.
         Assert.True (_textView.Selecting);
         Assert.Equal ("TAB to jump between", _textView.SelectedText);
 
-        Assert.True (_textView.OnMouseEvent (new MouseEvent { X = 19, Y = 0, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (_textView.NewMouseEvent (new MouseEvent { X = 19, Y = 0, Flags = MouseFlags.Button1Clicked }));
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (new Point (19, 0), _textView.CursorPosition);
@@ -6824,7 +6824,7 @@ This is the second line.
         Assert.Equal ("TAB to jump between", _textView.SelectedText);
 
         Assert.True (
-                     _textView.OnMouseEvent (
+                     _textView.NewMouseEvent (
                                            new MouseEvent { X = 24, Y = 0, Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift }
                                           )
                     );
@@ -6834,14 +6834,14 @@ This is the second line.
         Assert.True (_textView.Selecting);
         Assert.Equal ("TAB to jump between text", _textView.SelectedText);
 
-        Assert.True (_textView.OnMouseEvent (new MouseEvent { X = 24, Y = 0, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (_textView.NewMouseEvent (new MouseEvent { X = 24, Y = 0, Flags = MouseFlags.Button1Clicked }));
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (new Point (24, 0), _textView.CursorPosition);
         Assert.True (_textView.Selecting);
         Assert.Equal ("TAB to jump between text", _textView.SelectedText);
 
-        Assert.True (_textView.OnMouseEvent (new MouseEvent { X = 24, Y = 0, Flags = MouseFlags.Button1Pressed }));
+        Assert.True (_textView.NewMouseEvent (new MouseEvent { X = 24, Y = 0, Flags = MouseFlags.Button1Pressed }));
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (0, _textView.SelectionStartRow);
         Assert.Equal (new Point (24, 0), _textView.CursorPosition);
@@ -7624,12 +7624,12 @@ TAB to jump between text field",
 
         var ev = new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1DoubleClicked };
 
-        tv.OnMouseEvent (ev);
+        tv.NewMouseEvent (ev);
         Assert.Equal (1, tv.SelectedLength);
 
         ev = new MouseEvent { X = 1, Y = 0, Flags = MouseFlags.Button1DoubleClicked };
 
-        tv.OnMouseEvent (ev);
+        tv.NewMouseEvent (ev);
         Assert.Equal (1, tv.SelectedLength);
     }
 
@@ -7744,7 +7744,7 @@ line.
                                                       _output
                                                      );
 
-        Assert.True (tv.OnMouseEvent (new MouseEvent { X = 0, Y = 3, Flags = MouseFlags.Button1Pressed }));
+        Assert.True (tv.NewMouseEvent (new MouseEvent { X = 0, Y = 3, Flags = MouseFlags.Button1Pressed }));
         tv.Draw ();
         Assert.Equal (new Point (0, 3), tv.CursorPosition);
         Assert.Equal (new Point (13, 0), cp);

+ 105 - 416
UnitTests/Views/ToplevelTests.cs

@@ -274,7 +274,7 @@ public class ToplevelTests
         Assert.NotNull (top.MenuBar);
 
         // Application.Top with a menu and without status bar.
-        View.GetLocationEnsuringFullVisibility (top, 2, 2, out nx, out ny,  out sb);
+        View.GetLocationEnsuringFullVisibility (top, 2, 2, out nx, out ny, out sb);
         Assert.Equal (0, nx);
         Assert.Equal (1, ny);
         Assert.Null (sb);
@@ -382,12 +382,12 @@ public class ToplevelTests
         Assert.Equal (new Rectangle (0, 1, 60, 15), win.Frame);
 
         //Assert.Null (Toplevel._dragPosition);
-        win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
-       // Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
-        win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
+        win.NewMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
+        // Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
+        win.NewMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
         //Assert.Null (Toplevel._dragPosition);
         win.CanFocus = false;
-        win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
+        win.NewMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
         //Assert.Null (Toplevel._dragPosition);
     }
 
@@ -875,29 +875,14 @@ public class ToplevelTests
                                      }
                                      else if (iterations == 1)
                                      {
-                                         TestHelpers.AssertDriverContentsWithFrameAre (
-                                                                                       @"
-┌─────────────┐
-│             │
-│ ┌────────┐  │
-│ │Hello   │  │
-│ └────────┘  │
-│             │
-└─────────────┘
-",
-                                                                                       _output
-                                                                                      );
+                                         Assert.Equal(new Point(2,2), Application.Current.Frame.Location);
                                      }
                                      else if (iterations == 2)
                                      {
                                          Assert.Null (Application.MouseGrabView);
 
                                          // Grab the mouse
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent { X = 3, Y = 2, Flags = MouseFlags.Button1Pressed }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new () { X = 3, Y = 2, Flags = MouseFlags.Button1Pressed });
 
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
                                          Assert.Equal (new Rectangle (2, 2, 10, 3), Application.Current.Frame);
@@ -907,17 +892,13 @@ public class ToplevelTests
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
 
                                          // Drag to left
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            {
-                                                                                                X = 2,
-                                                                                                Y = 2,
-                                                                                                Flags = MouseFlags.Button1Pressed
-                                                                                                        | MouseFlags.ReportMousePosition
-                                                                                            }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new ()
+                                         {
+                                             X = 2,
+                                             Y = 2,
+                                             Flags = MouseFlags.Button1Pressed
+                                                     | MouseFlags.ReportMousePosition
+                                         });
                                          Application.Refresh ();
 
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
@@ -926,18 +907,7 @@ public class ToplevelTests
                                      else if (iterations == 4)
                                      {
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
-
-                                         TestHelpers.AssertDriverContentsWithFrameAre (
-                                                                                       @"
-┌─────────────┐
-│             │
-│┌────────┐   │
-││Hello   │   │
-│└────────┘   │
-│             │
-└─────────────┘",
-                                                                                       _output
-                                                                                      );
+                                         Assert.Equal (new Point (1, 2), Application.Current.Frame.Location);
 
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
                                      }
@@ -946,17 +916,13 @@ public class ToplevelTests
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
 
                                          // Drag up
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            {
-                                                                                                X = 2,
-                                                                                                Y = 1,
-                                                                                                Flags = MouseFlags.Button1Pressed
-                                                                                                        | MouseFlags.ReportMousePosition
-                                                                                            }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new ()
+                                         {
+                                             X = 2,
+                                             Y = 1,
+                                             Flags = MouseFlags.Button1Pressed
+                                                     | MouseFlags.ReportMousePosition
+                                         });
                                          Application.Refresh ();
 
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
@@ -965,18 +931,8 @@ public class ToplevelTests
                                      else if (iterations == 6)
                                      {
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
+                                         Assert.Equal (new Point (1, 1), Application.Current.Frame.Location);
 
-                                         TestHelpers.AssertDriverContentsWithFrameAre (
-                                                                                       @"
-┌─────────────┐
-│┌────────┐   │
-││Hello   │   │
-│└────────┘   │
-│             │
-│             │
-└─────────────┘",
-                                                                                       _output
-                                                                                      );
 
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
                                          Assert.Equal (new Rectangle (1, 1, 10, 3), Application.Current.Frame);
@@ -986,11 +942,7 @@ public class ToplevelTests
                                          Assert.Equal (Application.Current.Border, Application.MouseGrabView);
 
                                          // Ungrab the mouse
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent { X = 2, Y = 1, Flags = MouseFlags.Button1Released }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new () { X = 2, Y = 1, Flags = MouseFlags.Button1Released });
                                          Application.Refresh ();
 
                                          Assert.Null (Application.MouseGrabView);
@@ -1038,15 +990,11 @@ public class ToplevelTests
                                          Assert.Null (Application.MouseGrabView);
 
                                          // Grab the mouse
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            {
-                                                                                                X = win.Frame.X, Y = win.Frame.Y,
-                                                                                                Flags = MouseFlags.Button1Pressed
-                                                                                            }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new MouseEvent
+                                         {
+                                             X = win.Frame.X, Y = win.Frame.Y,
+                                             Flags = MouseFlags.Button1Pressed
+                                         });
 
                                          Assert.Equal (win.Border, Application.MouseGrabView);
                                      }
@@ -1058,17 +1006,13 @@ public class ToplevelTests
                                          movex = 1;
                                          movey = 0;
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            {
-                                                                                                X = win.Frame.X + movex,
-                                                                                                Y = win.Frame.Y + movey,
-                                                                                                Flags = MouseFlags.Button1Pressed
-                                                                                                        | MouseFlags.ReportMousePosition
-                                                                                            }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new MouseEvent
+                                         {
+                                             X = win.Frame.X + movex,
+                                             Y = win.Frame.Y + movey,
+                                             Flags = MouseFlags.Button1Pressed
+                                                     | MouseFlags.ReportMousePosition
+                                         });
 
                                          Assert.Equal (win.Border, Application.MouseGrabView);
                                      }
@@ -1087,17 +1031,13 @@ public class ToplevelTests
                                          movex = 0;
                                          movey = -1;
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            {
-                                                                                                X = win.Frame.X + movex,
-                                                                                                Y = win.Frame.Y + movey,
-                                                                                                Flags = MouseFlags.Button1Pressed
-                                                                                                        | MouseFlags.ReportMousePosition
-                                                                                            }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new MouseEvent
+                                         {
+                                             X = win.Frame.X + movex,
+                                             Y = win.Frame.Y + movey,
+                                             Flags = MouseFlags.Button1Pressed
+                                                     | MouseFlags.ReportMousePosition
+                                         });
 
                                          Assert.Equal (win.Border, Application.MouseGrabView);
                                      }
@@ -1116,15 +1056,11 @@ public class ToplevelTests
                                          movex = 0;
                                          movey = 0;
 
-                                         Application.OnMouseEvent (
-                                                                   new MouseEventEventArgs (
-                                                                                            new MouseEvent
-                                                                                            {
-                                                                                                X = win.Frame.X + movex, Y = win.Frame.Y + movey,
-                                                                                                Flags = MouseFlags.Button1Released
-                                                                                            }
-                                                                                           )
-                                                                  );
+                                         Application.OnMouseEvent (new MouseEvent
+                                         {
+                                             X = win.Frame.X + movex, Y = win.Frame.Y + movey,
+                                             Flags = MouseFlags.Button1Released
+                                         });
 
                                          Assert.Null (Application.MouseGrabView);
                                      }
@@ -1406,124 +1342,36 @@ public class ToplevelTests
         Assert.Equal (new (0, 0, 200, 100), scrollView.Subviews [0].Frame);
         Assert.Equal (new (3, 3, 194, 94), win.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-                                          ▲
-                                          ┬
-                                          │
-      ┌───────────────────────────────────┴
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ░
-      │                                   ▼
-   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
-                                                      _output
-                                                     );
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 6, Y = 6, Flags = MouseFlags.Button1Pressed }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 6, Y = 6, Flags = MouseFlags.Button1Pressed });
         Assert.Equal (win.Border, Application.MouseGrabView);
         Assert.Equal (new (3, 3, 194, 94), win.Frame);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 9,
-                                                               Y = 9,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 9, Y = 9, Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
         Assert.Equal (win.Border, Application.MouseGrabView);
         top.SetNeedsLayout ();
         top.LayoutSubviews ();
         Assert.Equal (new Rectangle (6, 6, 191, 91), win.Frame);
         Application.Refresh ();
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-                                          ▲
-                                          ┬
-                                          │
-                                          ┴
-                                          ░
-                                          ░
-         ┌────────────────────────────────░
-         │                                ░
-         │                                ░
-         │                                ░
-         │                                ░
-         │                                ░
-         │                                ░
-         │                                ░
-         │                                ▼
-   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
-                                                      _output
-                                                     );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 5,
-                                                               Y = 5,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = 5,
+            Y = 5,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
         Assert.Equal (win.Border, Application.MouseGrabView);
         top.SetNeedsLayout ();
         top.LayoutSubviews ();
         Assert.Equal (new Rectangle (2, 2, 195, 95), win.Frame);
         Application.Refresh ();
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-                                          ▲
-                                          ┬
-     ┌────────────────────────────────────│
-     │                                    ┴
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ░
-     │                                    ▼
-   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
-                                                      _output
-                                                     );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 5, Y = 5, Flags = MouseFlags.Button1Released }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 5, Y = 5, Flags = MouseFlags.Button1Released });
         // ScrollView always grab the mouse when the container's subview OnMouseEnter don't want grab the mouse
         Assert.Equal (scrollView, Application.MouseGrabView);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 4, Y = 4, Flags = MouseFlags.ReportMousePosition }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 4, Y = 4, Flags = MouseFlags.ReportMousePosition });
         Assert.Equal (scrollView, Application.MouseGrabView);
     }
 
@@ -1540,139 +1388,74 @@ public class ToplevelTests
         Assert.Equal (new Rectangle (0, 0, 40, 10), top.Frame);
         Assert.Equal (new Rectangle (0, 0, 20, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌──────────────────┐
-│                  │
-└──────────────────┘
-",
-                                                      _output
-                                                     );
-
         Assert.Null (Application.MouseGrabView);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed });
 
         Assert.Equal (window.Border, Application.MouseGrabView);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = -11,
-                                                               Y = -4,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = -11,
+            Y = -4,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         Application.Refresh ();
         Assert.Equal (new Rectangle (0, 0, 40, 10), top.Frame);
         Assert.Equal (new Rectangle (0, 0, 20, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌──────────────────┐
-│                  │
-└──────────────────┘
-",
-                                                      _output
-                                                     );
-
         // Changes Top size to same size as Dialog more menu and scroll bar
         ((FakeDriver)Application.Driver).SetBufferSize (20, 3);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = -1,
-                                                               Y = -1,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = -1,
+            Y = -1,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         Application.Refresh ();
         Assert.Equal (new Rectangle (0, 0, 20, 3), top.Frame);
         Assert.Equal (new Rectangle (0, 0, 20, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌──────────────────┐
-│                  │
-└──────────────────┘
-",
-                                                      _output
-                                                     );
-
         // Changes Top size smaller than Dialog size
         ((FakeDriver)Application.Driver).SetBufferSize (19, 2);
 
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = -1,
-                                                               Y = -1,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = -1,
+            Y = -1,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         Application.Refresh ();
         Assert.Equal (new Rectangle (0, 0, 19, 2), top.Frame);
         Assert.Equal (new Rectangle (-1, 0, 20, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-──────────────────┐
-                  │
-",
-                                                      _output
-                                                     );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 18,
-                                                               Y = 1,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = 18,
+            Y = 1,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         Application.Refresh ();
         Assert.Equal (new Rectangle (0, 0, 19, 2), top.Frame);
         Assert.Equal (new Rectangle (18, 1, 20, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-                  ┌",
-                                                      _output
-                                                     );
-
         // On a real app we can't go beyond the SuperView bounds
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 19,
-                                                               Y = 2,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = 19,
+            Y = 2,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         Application.Refresh ();
         Assert.Equal (new Rectangle (0, 0, 19, 2), top.Frame);
@@ -1709,19 +1492,7 @@ public class ToplevelTests
         Assert.Null (Application.MouseGrabView);
         Assert.Equal (new Rectangle (0, 0, 10, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌────────┐
-│  Test  │
-└────────┘",
-                                                      _output
-                                                     );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent { X = 0, Y = 0, Flags = MouseFlags.Button1Pressed });
 
         var firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
@@ -1729,39 +1500,19 @@ public class ToplevelTests
 
         Assert.Equal (new Rectangle (0, 0, 10, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌────────┐
-│  Test  │
-└────────┘",
-                                                      _output
-                                                     );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent
-                                                           {
-                                                               X = 1,
-                                                               Y = 1,
-                                                               Flags = MouseFlags.Button1Pressed
-                                                                       | MouseFlags.ReportMousePosition
-                                                           }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new MouseEvent
+        {
+            X = 1,
+            Y = 1,
+            Flags = MouseFlags.Button1Pressed
+                    | MouseFlags.ReportMousePosition
+        });
 
         firstIteration = false;
         Application.RunIteration (ref rs, ref firstIteration);
         Assert.Equal (window.Border, Application.MouseGrabView);
         Assert.Equal (new Rectangle (1, 1, 10, 3), window.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
- ┌────────┐
- │  Test  │
- └────────┘",
-                                                      _output
-                                                     );
-
         Application.End (rs);
     }
 
@@ -1796,31 +1547,6 @@ public class ToplevelTests
 
         Assert.Equal (new Rectangle (0, 0, 20, 20), win.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌──────────────────┐
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-└──────────────────┘",
-                                                      _output
-                                                     );
-
         var btnPopup = new Button { Text = "Popup" };
         var testWindow = new Window { X = 2, Y = 1, Width = 15, Height = 10 };
         testWindow.Add (btnPopup);
@@ -1864,40 +1590,7 @@ public class ToplevelTests
 
         Assert.Equal (new Rectangle (2, 1, 15, 10), testWindow.Frame);
 
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @$"
-┌──────────────────┐
-│ ┌─────────────┐  │
-│ │{
-    CM.Glyphs.LeftBracket
-} Popup {
-    CM.Glyphs.RightBracket
-}    │  │
-│ │             │  │
-│ │             │  │
-│ │             │  │
-│ │             │  │
-│ │             │  │
-│ │             │  │
-│ │             │  │
-│ └─────────────┘  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-│                  │
-└──────────────────┘",
-                                                      _output
-                                                     );
-
-        Application.OnMouseEvent (
-                                  new MouseEventEventArgs (
-                                                           new MouseEvent { X = 5, Y = 2, Flags = MouseFlags.Button1Clicked }
-                                                          )
-                                 );
+        Application.OnMouseEvent (new () { X = 5, Y = 2, Flags = MouseFlags.Button1Clicked });
         Application.Top.Draw ();
 
         var firstIteration = false;
@@ -1907,11 +1600,7 @@ public class ToplevelTests
                                                       @$"
 ┌──────────────────┐
 │ ┌─────────────┐  │
-│ │{
-    CM.Glyphs.LeftBracket
-} Popup {
-    CM.Glyphs.RightBracket
-}    │  │
+│ │{CM.Glyphs.LeftBracket} Popup {CM.Glyphs.RightBracket}    │  │
 │┌────────────────┐│
 ││viewAddedToTop  ││
 ││                ││

+ 4 - 4
UnitTests/Views/TreeTableSourceTests.cs

@@ -108,7 +108,7 @@ public class TreeTableSourceTests : IDisposable
         Assert.Equal (0, tv.SelectedRow);
         Assert.Equal (0, tv.SelectedColumn);
 
-        Assert.True (tv.OnMouseEvent (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Clicked }));
+        Assert.True (tv.NewMouseEvent (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Clicked }));
 
         tv.Draw ();
 
@@ -125,15 +125,15 @@ public class TreeTableSourceTests : IDisposable
         TestHelpers.AssertDriverContentsAre (expected, _output);
 
         // Clicking to the right/left of the expand/collapse does nothing
-        tv.OnMouseEvent (new MouseEvent { X = 3, Y = 2, Flags = MouseFlags.Button1Clicked });
+        tv.NewMouseEvent (new MouseEvent { X = 3, Y = 2, Flags = MouseFlags.Button1Clicked });
         tv.Draw ();
         TestHelpers.AssertDriverContentsAre (expected, _output);
-        tv.OnMouseEvent (new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked });
+        tv.NewMouseEvent (new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked });
         tv.Draw ();
         TestHelpers.AssertDriverContentsAre (expected, _output);
 
         // Clicking on the + again should collapse
-        tv.OnMouseEvent (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Clicked });
+        tv.NewMouseEvent (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Clicked });
         tv.Draw ();
 
         expected =

+ 4 - 4
UnitTests/Views/TreeViewTests.cs

@@ -453,7 +453,7 @@ public class TreeViewTests
         Assert.False (called);
 
         // double click triggers activation
-        tree.OnMouseEvent (new MouseEvent { Y = 0, Flags = MouseFlags.Button1DoubleClicked });
+        tree.NewMouseEvent (new MouseEvent { Y = 0, Flags = MouseFlags.Button1DoubleClicked });
 
         Assert.True (called);
         Assert.Same (f, activated);
@@ -485,12 +485,12 @@ public class TreeViewTests
         Assert.False (called);
 
         // double click does nothing because we changed button binding to right click
-        tree.OnMouseEvent (new MouseEvent { Y = 1, Flags = MouseFlags.Button1DoubleClicked });
+        tree.NewMouseEvent (new MouseEvent { Y = 1, Flags = MouseFlags.Button1DoubleClicked });
 
         Assert.Null (activated);
         Assert.False (called);
 
-        tree.OnMouseEvent (new MouseEvent { Y = 1, Flags = MouseFlags.Button2Clicked });
+        tree.NewMouseEvent (new MouseEvent { Y = 1, Flags = MouseFlags.Button2Clicked });
 
         Assert.True (called);
         Assert.Same (car1, activated);
@@ -522,7 +522,7 @@ public class TreeViewTests
         Assert.False (called);
 
         // double click does nothing because we changed button to null
-        tree.OnMouseEvent (new MouseEvent { Y = 0, Flags = MouseFlags.Button1DoubleClicked });
+        tree.NewMouseEvent (new MouseEvent { Y = 0, Flags = MouseFlags.Button1DoubleClicked });
 
         Assert.False (called);
         Assert.Null (activated);