From 2ed6ed52c75342f55c9184f0ad64b9a3f4924163 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 2 Apr 2024 16:38:42 -0600 Subject: [PATCH] beefed up unit tests --- Terminal.Gui/View/ViewMouse.cs | 103 ++++++++++++++++----------------- UnitTests/View/MouseTests.cs | 70 ++++++++++++---------- 2 files changed, 90 insertions(+), 83 deletions(-) diff --git a/Terminal.Gui/View/ViewMouse.cs b/Terminal.Gui/View/ViewMouse.cs index 21091d172..f06c0615c 100644 --- a/Terminal.Gui/View/ViewMouse.cs +++ b/Terminal.Gui/View/ViewMouse.cs @@ -3,7 +3,8 @@ public partial class View { /// - /// Gets or sets whether the will highlight the view visually when the mouse button is pressed/released. + /// Gets or sets whether the will highlight the view visually when the mouse button is + /// pressed/released. /// public bool HighlightOnPress { get; set; } @@ -16,21 +17,21 @@ public partial class View /// Event fired when a mouse event occurs. /// - /// - /// The coordinates are relative to . - /// + /// + /// The coordinates are relative to . + /// /// public event EventHandler MouseEvent; /// Event fired when a mouse click occurs. /// - /// - /// Fired when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. - /// - /// - /// The coordinates are relative to . - /// + /// + /// Fired when the mouse is either clicked or double-clicked. Check + /// to see which button was clicked. + /// + /// + /// The coordinates are relative to . + /// /// public event EventHandler MouseClick; @@ -42,11 +43,12 @@ public partial class View // TODO: OnMouseEnter should not be public virtual, but protected. /// - /// Called when the mouse enters the View's . The view will now receive mouse events until the mouse leaves + /// Called when the mouse enters the View's . The view will now receive mouse events until the + /// mouse leaves /// the view. At which time, will be called. /// /// - /// The coordinates are relative to . + /// The coordinates are relative to . /// /// /// , if the event was handled, otherwise. @@ -70,11 +72,12 @@ public partial class View // TODO: OnMouseLeave should not be public virtual, but protected. /// - /// Called when the mouse has moved out of the View's . The view will no longer receive mouse events (until the + /// Called when the mouse has moved out of the View's . The view will no longer receive mouse + /// events (until the /// mouse moves within the view again and is called). /// /// - /// The coordinates are relative to . + /// The coordinates are relative to . /// /// /// , if the event was handled, otherwise. @@ -102,9 +105,9 @@ public partial class View // TODO: OnMouseEvent should not be public virtual, but protected. /// Called when a mouse event occurs within the view's . /// - /// - /// The coordinates are relative to . - /// + /// + /// The coordinates are relative to . + /// /// /// /// , if the event was handled, otherwise. @@ -123,19 +126,21 @@ public partial class View var args = new MouseEventEventArgs (mouseEvent); - // Default behavior is to invoke Accept (via HotKey) on clicked. - if ((!WantContinuousButtonPressed && - Application.MouseGrabView != this && - mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked)) + if (!WantContinuousButtonPressed + && Application.MouseGrabView != this + && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) + || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) + || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked) + || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked))) { return OnMouseClick (args); } - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) + if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) + || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed) + || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed) + || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed)) { // If WantContinuousButtonPressed is true, and this is not the first pressed event, // invoke Accept (via HotKey) @@ -157,7 +162,7 @@ public partial class View // TODO: Make the inverted color configurable var cs = new ColorScheme (ColorScheme) { - Focus = new Attribute (ColorScheme.Normal.Foreground, ColorScheme.Focus.Background) + Focus = new (ColorScheme.Normal.Foreground, ColorScheme.Focus.Background) }; ColorScheme = cs; } @@ -165,20 +170,24 @@ public partial class View { var cs = new ColorScheme (ColorScheme) { - Normal = new Attribute (ColorScheme.Focus.Background, ColorScheme.Normal.Foreground) + Normal = new (ColorScheme.Focus.Background, ColorScheme.Normal.Foreground) }; ColorScheme = cs; } } - if (CanFocus){ - // Set the focus, but don't invoke Accept - SetFocus (); + if (CanFocus) + { + // Set the focus, but don't invoke Accept + SetFocus (); } } } - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released)) + if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) + || mouseEvent.Flags.HasFlag (MouseFlags.Button2Released) + || mouseEvent.Flags.HasFlag (MouseFlags.Button3Released) + || mouseEvent.Flags.HasFlag (MouseFlags.Button4Released)) { // When the mouse is released, if WantContinuousButtonPressed is set, invoke Accept one last time. if (WantContinuousButtonPressed) @@ -189,6 +198,7 @@ public partial class View if (Application.MouseGrabView == this) { Application.UngrabMouse (); + if (HighlightOnPress && _savedColorScheme is { }) { ColorScheme = _savedColorScheme; @@ -197,37 +207,20 @@ public partial class View } } - //// 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)) - //{ - // OnMouseClick (args); - //} - - //if (mouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - // || mouseEvent.Flags.HasFlag (MouseFlags.Button2DoubleClicked) - // || mouseEvent.Flags.HasFlag (MouseFlags.Button3DoubleClicked) - // || mouseEvent.Flags.HasFlag (MouseFlags.Button4DoubleClicked)) - //{ - // OnMouseClick (args); - //} - if (args.Handled != true) { MouseEvent?.Invoke (this, args); } - return args.Handled == true; + return args.Handled; } /// Invokes the MouseClick event. /// - /// - /// Called when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. - /// + /// + /// Called when the mouse is either clicked or double-clicked. Check + /// to see which button was clicked. + /// /// protected bool OnMouseClick (MouseEventEventArgs args) { @@ -235,10 +228,12 @@ public partial class View { // 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; diff --git a/UnitTests/View/MouseTests.cs b/UnitTests/View/MouseTests.cs index 1e56e679f..12a81e210 100644 --- a/UnitTests/View/MouseTests.cs +++ b/UnitTests/View/MouseTests.cs @@ -317,73 +317,85 @@ public class MouseTests (ITestOutputHelper output) view.Dispose (); } - [Fact] - public void WantContinuousButtonPressed_False_Button1Press_Release_DoesNotClick () + [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_Button1Press_Release_DoesNotClick (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { + var me = new MouseEvent () + { + Flags = pressed + }; + var view = new View () { WantContinuousButtonPressed = false }; - var clicked = 0; + var clickedCount = 0; - view.MouseClick += (s, e) => clicked++; + view.MouseClick += (s, e) => clickedCount++; - var me = new MouseEvent () - { - Flags = MouseFlags.Button1Pressed - }; view.OnMouseEvent (me); - Assert.Equal (0, clicked); + Assert.Equal (0, clickedCount); me.Handled = false; view.OnMouseEvent (me); - Assert.Equal (0, clicked); + Assert.Equal (0, clickedCount); me.Handled = false; - me.Flags = MouseFlags.Button1Released; + me.Flags = released; view.OnMouseEvent (me); - Assert.Equal (0, clicked); + Assert.Equal (0, clickedCount); + me.Handled = false; - me.Flags = MouseFlags.Button1Clicked; + me.Flags =clicked; view.OnMouseEvent (me); - Assert.Equal (1, clicked); + Assert.Equal (1, clickedCount); view.Dispose (); } - [Fact] - public void WantContinuousButtonPressed_True_Button1Press_Release_Repeats () + + [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_Button1Press_Release_Clicks_Repeatedly (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { + var me = new MouseEvent () + { + Flags = pressed + }; + var view = new View () { WantContinuousButtonPressed = true }; - var clicked = 0; + var clickedCount = 0; - view.MouseClick += (s, e) => clicked++; - - var me = new MouseEvent () - { - Flags = MouseFlags.Button1Pressed - }; + view.MouseClick += (s, e) => clickedCount++; view.OnMouseEvent (me); - Assert.Equal (0, clicked); + Assert.Equal (0, clickedCount); me.Handled = false; view.OnMouseEvent (me); - Assert.Equal (1, clicked); + Assert.Equal (1, clickedCount); me.Handled = false; - me.Flags = MouseFlags.Button1Released; + me.Flags = released; view.OnMouseEvent (me); - Assert.Equal (2, clicked); + Assert.Equal (2, clickedCount); + me.Handled = false; - me.Flags = MouseFlags.Button1Clicked; + me.Flags = clicked; view.OnMouseEvent (me); - Assert.Equal (2, clicked); + Assert.Equal (2, clickedCount); view.Dispose (); }