Tig 1 år sedan
förälder
incheckning
5c7a177bdd
2 ändrade filer med 323 tillägg och 356 borttagningar
  1. 286 319
      Terminal.Gui/View/ViewMouse.cs
  2. 37 37
      UnitTests/View/TitleTests.cs

+ 286 - 319
Terminal.Gui/View/ViewMouse.cs

@@ -2,207 +2,45 @@
 
 namespace Terminal.Gui;
 
-/// <summary>
-/// Describes the highlight style of a view.
-/// </summary>
-[Flags]
-public enum HighlightStyle
+public partial class View
 {
-    /// <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.Viewport"/>.
-    /// </summary>
-    Pressed = 2,
+    [CanBeNull]
+    private ColorScheme _savedHighlightColorScheme;
 
     /// <summary>
-    /// The mouse is pressed but moved outside the <see cref="View.Viewport"/>.
+    ///     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>
-    PressedOutside = 4
-}
-
-/// <summary>
-/// Event arguments for the <see cref="View.Highlight"/> event.
-/// </summary>
-public class HighlightEventArgs : CancelEventArgs<HighlightStyle>
-{
-    /// <inheritdoc />
-    public HighlightEventArgs (HighlightStyle currentValue, HighlightStyle newValue) : base (currentValue, newValue) { }
-}
+    public event EventHandler<HighlightEventArgs> Highlight;
 
-public partial class View
-{
     /// <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 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>
-    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse enters <see cref="Viewport"/>. The view will
-    ///     then receive mouse events until <see cref="NewMouseLeaveEvent"/> is called indicating the mouse has left
-    ///     the view.
-    /// </summary>
+    /// <summary>Event fired when a mouse click occurs.</summary>
     /// <remarks>
     ///     <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.
+    ///         Fired when the mouse is either clicked or double-clicked. Check
+    ///         <see cref="MouseEvent.Flags"/> to see which button was clicked.
     ///     </para>
     ///     <para>
-    ///         See <see cref="SetHighlight"/> for more information.
+    ///         The coordinates are relative to <see cref="View.Viewport"/>.
     ///     </para>
     /// </remarks>
-    /// <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;
-        }
-
-        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="Viewport"/>. The view will
-    ///     then receive mouse events until <see cref="OnMouseLeave"/> is called indicating the mouse has left
-    ///     the view.
-    /// </summary>
-    /// <remarks>
-    /// <para>
-    /// 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.Viewport"/>.
-    /// </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)
-    {
-
-        var args = new MouseEventEventArgs (mouseEvent);
-        MouseEnter?.Invoke (this, args);
-
-        return args.Handled;
-    }
+    public event EventHandler<MouseEventEventArgs> MouseClick;
 
     /// <summary>Event fired when the mouse moves into the View's <see cref="Viewport"/>.</summary>
     public event EventHandler<MouseEventEventArgs> MouseEnter;
 
-
-    /// <summary>
-    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse leaves <see cref="Viewport"/>. The view will
-    ///     then no longer receive mouse events.
-    /// </summary>
+    /// <summary>Event fired when a mouse event occurs.</summary>
     /// <remarks>
     ///     <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.
+    ///         The coordinates are relative to <see cref="View.Viewport"/>.
     ///     </para>
     /// </remarks>
-    /// <param name="mouseEvent"></param>
-    /// <returns><see langword="true"/> if the event was handled, <see langword="false"/> otherwise.</returns>
-    internal bool? NewMouseLeaveEvent (MouseEvent mouseEvent)
-    {
-        if (!Enabled)
-        {
-            return true;
-        }
-
-        if (!CanBeVisible (this))
-        {
-            return false;
-        }
-
-        if (OnMouseLeave (mouseEvent) == true)
-        {
-            return true;
-        }
-#if HOVER
-        if (HighlightStyle.HasFlag (HighlightStyle.Hover))
-        {
-            SetHighlight (HighlightStyle.None);
-        }
-#endif
-
-        return false;
-    }
-    /// <summary>
-    ///     Called by <see cref="NewMouseEvent"/> when a mouse leaves <see cref="Viewport"/>. The view will
-    ///     no longer receive mouse events.
-    /// </summary>
-    /// <remarks>
-    /// <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.Viewport"/>.
-    /// </para>
-    /// </remarks>
-    /// <param name="mouseEvent"></param>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    protected internal virtual bool OnMouseLeave (MouseEvent mouseEvent)
-    {
-        if (!Enabled)
-        {
-            return true;
-        }
-
-        if (!CanBeVisible (this))
-        {
-            return false;
-        }
-
-        var args = new MouseEventEventArgs (mouseEvent);
-        MouseLeave?.Invoke (this, args);
-
-        return args.Handled;
-    }
+    public event EventHandler<MouseEventEventArgs> MouseEvent;
 
     /// <summary>Event fired when the mouse leaves the View's <see cref="Viewport"/>.</summary>
     public event EventHandler<MouseEventEventArgs> MouseLeave;
@@ -249,7 +87,7 @@ public partial class View
             return mouseEvent.Handled = true;
         }
 
-        if (HighlightStyle != Gui.HighlightStyle.None || WantContinuousButtonPressed)
+        if (HighlightStyle != HighlightStyle.None || WantContinuousButtonPressed)
         {
             if (HandlePressed (mouseEvent))
             {
@@ -290,58 +128,169 @@ public partial class View
         return false;
     }
 
+    /// <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 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>
-    ///     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).
+    ///     Called by <see cref="NewMouseEvent"/> when the mouse enters <see cref="Viewport"/>. The view will
+    ///     then receive mouse events until <see cref="OnMouseLeave"/> is called indicating the mouse has left
+    ///     the view.
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         Marked internal just to support unit tests
+    ///         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.Viewport"/>.
     ///     </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)
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    protected internal virtual bool? OnMouseEnter (MouseEvent mouseEvent)
     {
-        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed)
-            || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed))
+        var args = new MouseEventEventArgs (mouseEvent);
+        MouseEnter?.Invoke (this, args);
+
+        return args.Handled;
+    }
+
+    /// <summary>Called when a mouse event occurs within the view's <see cref="Viewport"/>.</summary>
+    /// <remarks>
+    ///     <para>
+    ///         The coordinates are relative to <see cref="View.Viewport"/>.
+    ///     </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;
+    }
+
+    /// <summary>
+    ///     Called by <see cref="NewMouseEvent"/> when a mouse leaves <see cref="Viewport"/>. The view will
+    ///     no longer receive mouse events.
+    /// </summary>
+    /// <remarks>
+    ///     <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.Viewport"/>.
+    ///     </para>
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    protected internal virtual bool OnMouseLeave (MouseEvent mouseEvent)
+    {
+        if (!Enabled)
         {
-            // The first time we get pressed event, grab the mouse and set focus
-            if (Application.MouseGrabView != this)
-            {
-                Application.GrabMouse (this);
+            return true;
+        }
 
-                if (!HasFocus && CanFocus)
-                {
-                    // Set the focus, but don't invoke Accept
-                    SetFocus ();
-                }
+        if (!CanBeVisible (this))
+        {
+            return false;
+        }
+
+        var args = new MouseEventEventArgs (mouseEvent);
+        MouseLeave?.Invoke (this, args);
+
+        return args.Handled;
+    }
+
+    /// <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 (HighlightEventArgs args)
+    {
+        Highlight?.Invoke (this, args);
+
+        if (args.Cancel)
+        {
+            return true;
+        }
+
+        Margin?.Highlight?.Invoke (this, args);
+
+        //args = new (highlight);
+        //Border?.Highlight?.Invoke (this, args);
+
+        //args = new (highlight);
+        //Padding?.Highlight?.Invoke (this, args);
+
+        return args.Cancel;
+    }
+
+    /// <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>
+    /// </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?
+            return args.Handled = true;
+        }
+
+        MouseClick?.Invoke (this, args);
+
+        if (args.Handled)
+        {
+            return true;
+        }
+
+        if (!HasFocus && CanFocus)
+        {
+            args.Handled = true;
+            SetFocus ();
+        }
+
+        return args.Handled;
+    }
 
-                mouseEvent.Handled = true;
-            }
+    /// <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 (Viewport.Contains (mouseEvent.Position))
-            {
-                if (this is not Adornment && SetHighlight (new (HighlightStyle,
-                                                                HighlightStyle.HasFlag (HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None)) == true)
-                {
-                    return true;
-                }
-            }
-            else
+            if (SetHighlight (new (HighlightStyle, HighlightStyle.None)))
             {
-                if (this is not Adornment && SetHighlight (new (HighlightStyle, HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None)) == true)
-
-                {
-                    return true;
-                }
+                return true;
             }
 
-            if (WantContinuousButtonPressed && Application.MouseGrabView == this)
+            // If mouse is still in bounds, click
+            if (!WantContinuousButtonPressed && Viewport.Contains (mouseEvent.Position))
             {
-                // If this is not the first pressed event, click
                 return OnMouseClick (new (mouseEvent));
             }
 
@@ -379,45 +328,95 @@ public partial class View
     }
 
     /// <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).
+    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse enters <see cref="Viewport"/>. The view will
+    ///     then receive mouse events until <see cref="NewMouseLeaveEvent"/> is called indicating the mouse has left
+    ///     the view.
     /// </summary>
     /// <remarks>
-    ///     Marked internal just to support unit tests
+    ///     <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>
     /// <param name="mouseEvent"></param>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    internal bool HandleClicked (MouseEvent mouseEvent)
+    /// <returns><see langword="true"/> if the event was handled, <see langword="false"/> otherwise.</returns>
+    internal bool? NewMouseEnterEvent (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)))
+        if (!Enabled)
         {
-            // We're grabbed. Clicked event comes after the last Release. This is our signal to ungrab
-            Application.UngrabMouse ();
+            return true;
+        }
 
-            if (SetHighlight (new (HighlightStyle, HighlightStyle.None)))
+        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;
+    }
 
-            // If mouse is still in bounds, click
-            if (!WantContinuousButtonPressed && Viewport.Contains (mouseEvent.Position))
-            {
-                return OnMouseClick (new (mouseEvent));
-            }
+    /// <summary>
+    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse leaves <see cref="Viewport"/>. The view will
+    ///     then no longer receive mouse events.
+    /// </summary>
+    /// <remarks>
+    ///     <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>
+    internal bool? NewMouseLeaveEvent (MouseEvent mouseEvent)
+    {
+        if (!Enabled)
+        {
+            return true;
+        }
 
-            return mouseEvent.Handled = true;
+        if (!CanBeVisible (this))
+        {
+            return false;
+        }
+
+        if (OnMouseLeave (mouseEvent))
+        {
+            return true;
+        }
+#if HOVER
+        if (HighlightStyle.HasFlag (HighlightStyle.Hover))
+        {
+            SetHighlight (HighlightStyle.None);
         }
+#endif
 
         return false;
     }
 
-    [CanBeNull]
-    private ColorScheme _savedHighlightColorScheme;
-
     /// <summary>
     ///     Enables the highlight for the view when the mouse is pressed. Called from OnMouseEvent.
     /// </summary>
@@ -433,7 +432,6 @@ public partial class View
     ///     </para>
     /// </remarks>
     /// <returns><see langword="true"/>, if the Highlight event was handled, <see langword="false"/> otherwise.</returns>
-
     internal bool SetHighlight (HighlightEventArgs args)
     {
         // TODO: Make the highlight colors configurable
@@ -464,7 +462,7 @@ public partial class View
 
             return true;
         }
-#endif 
+#endif
         if (args.NewValue.HasFlag (HighlightStyle.Pressed) || args.NewValue.HasFlag (HighlightStyle.PressedOutside))
         {
             if (_savedHighlightColorScheme is null && ColorScheme is { })
@@ -476,7 +474,7 @@ public partial class View
                     var cs = new ColorScheme (ColorScheme)
                     {
                         // Highlight the foreground focus color
-                        Focus = new (ColorScheme.Focus.Foreground.GetHighlightColor (), ColorScheme.Focus.Background.GetHighlightColor ()),
+                        Focus = new (ColorScheme.Focus.Foreground.GetHighlightColor (), ColorScheme.Focus.Background.GetHighlightColor ())
                     };
                     ColorScheme = cs;
                 }
@@ -490,11 +488,11 @@ public partial class View
                     ColorScheme = cs;
                 }
             }
+
             // Return false since we don't want to eat the event
             return false;
         }
 
-
         if (args.NewValue == HighlightStyle.None)
         {
             // Unhighlight
@@ -509,101 +507,70 @@ public partial class View
     }
 
     /// <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.
+    ///     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>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    protected virtual bool? OnHighlight (HighlightEventArgs args)
-    {
-        Highlight?.Invoke (this, args);
-
-        if (args.Cancel)
-        {
-            return true;
-        }
-
-        Margin?.Highlight?.Invoke (this, args);
-
-        //args = new (highlight);
-        //Border?.Highlight?.Invoke (this, args);
-
-        //args = new (highlight);
-        //Padding?.Highlight?.Invoke (this, args);
-
-        return args.Cancel;
-    }
-
-    /// <summary>Called when a mouse event occurs within the view's <see cref="Viewport"/>.</summary>
     /// <remarks>
     ///     <para>
-    ///         The coordinates are relative to <see cref="View.Viewport"/>.
+    ///         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>
-    protected internal virtual bool OnMouseEvent (MouseEvent mouseEvent)
+    private bool HandlePressed (MouseEvent mouseEvent)
     {
-        var args = new MouseEventEventArgs (mouseEvent);
-
-        MouseEvent?.Invoke (this, args);
+        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed)
+            || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed))
+        {
+            // The first time we get pressed event, grab the mouse and set focus
+            if (Application.MouseGrabView != this)
+            {
+                Application.GrabMouse (this);
 
-        return args.Handled;
-    }
+                if (!HasFocus && CanFocus)
+                {
+                    // Set the focus, but don't invoke Accept
+                    SetFocus ();
+                }
 
-    /// <summary>Event fired when a mouse event occurs.</summary>
-    /// <remarks>
-    ///     <para>
-    ///         The coordinates are relative to <see cref="View.Viewport"/>.
-    ///     </para>
-    /// </remarks>
-    public event EventHandler<MouseEventEventArgs> MouseEvent;
+                mouseEvent.Handled = true;
+            }
 
-    /// <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>
-    /// </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?
-            return args.Handled = true;
-        }
+            if (Viewport.Contains (mouseEvent.Position))
+            {
+                if (this is not Adornment
+                    && SetHighlight (
+                                     new (
+                                          HighlightStyle,
+                                          HighlightStyle.HasFlag (HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None)))
+                {
+                    return true;
+                }
+            }
+            else
+            {
+                if (this is not Adornment
+                    && SetHighlight (
+                                     new (
+                                          HighlightStyle,
+                                          HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None)))
 
-        MouseClick?.Invoke (this, args);
+                {
+                    return true;
+                }
+            }
 
-        if (args.Handled)
-        {
-            return true;
-        }
+            if (WantContinuousButtonPressed && Application.MouseGrabView == this)
+            {
+                // If this is not the first pressed event, click
+                return OnMouseClick (new (mouseEvent));
+            }
 
-        if (!HasFocus && CanFocus)
-        {
-            args.Handled = true;
-            SetFocus ();
+            return mouseEvent.Handled = true;
         }
 
-        return args.Handled;
+        return false;
     }
-
-    /// <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.Viewport"/>.
-    ///     </para>
-    /// </remarks>
-    public event EventHandler<MouseEventEventArgs> MouseClick;
 }

+ 37 - 37
UnitTests/View/TitleTests.cs

@@ -5,6 +5,43 @@ namespace Terminal.Gui.ViewTests;
 
 public class TitleTests (ITestOutputHelper output)
 {
+    [SetupFakeDriver]
+    [Fact]
+    public void Change_View_Size_Update_Title_Size ()
+    {
+        var view = new View
+        {
+            Title = "_Hello World",
+            Width = Dim.Auto (),
+            Height = Dim.Auto (),
+            BorderStyle = LineStyle.Single
+        };
+        var top = new Toplevel ();
+        top.Add (view);
+        top.BeginInit ();
+        top.EndInit ();
+
+        Assert.Equal (string.Empty, view.Text);
+        Assert.Equal (new (2, 2), view.Frame.Size);
+        top.Draw ();
+
+        TestHelpers.AssertDriverContentsWithFrameAre (
+                                                      @"
+┌┐
+└┘",
+                                                      output);
+
+        var text = "This text will increment the view size and display the title.";
+        view.Text = text;
+        top.Draw ();
+        Assert.Equal (text, view.Text);
+
+        // SetupFakeDriver only create a screen with 25 cols and 25 rows
+        Assert.Equal (new (text.Length, 1), view.GetContentSize ());
+
+        top.Dispose ();
+    }
+
     [Fact]
     public void Set_Title_Fires_TitleChanged ()
     {
@@ -69,41 +106,4 @@ public class TitleTests (ITestOutputHelper output)
 
         Assert.Equal (Key.H, view.HotKey);
     }
-
-    [SetupFakeDriver]
-    [Fact]
-    public void Change_View_Size_Update_Title_Size ()
-    {
-        var view = new View
-        {
-            Title = "_Hello World",
-            Width = Dim.Auto (),
-            Height = Dim.Auto (),
-            BorderStyle = LineStyle.Single
-        };
-        var top = new Toplevel ();
-        top.Add (view);
-        top.BeginInit ();
-        top.EndInit ();
-
-        Assert.Equal (string.Empty, view.Text);
-        Assert.Equal (new (2, 2), view.Frame.Size);
-        top.Draw ();
-
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @"
-┌┐
-└┘",
-                                                      output);
-
-        var text = "This text will increment the view size and display the title.";
-        view.Text = text;
-        top.Draw ();
-        Assert.Equal (text, view.Text);
-
-        // SetupFakeDriver only create a screen with 25 cols and 25 rows
-        Assert.Equal (new (text.Length, 1), view.GetContentSize ());
-
-        top.Dispose ();
-    }
 }