From cecfb71ee1834ee69d71f478633a9eee773d8a1b Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Tue, 27 Feb 2024 08:00:59 -0700 Subject: [PATCH] Fixed Visible bug and addd unit tests --- Terminal.Gui/Application.cs | 7 ++ Terminal.Gui/View/Layout/ViewLayout.cs | 15 +++- UnitTests/View/FindDeepestViewTests.cs | 106 +++++++++++++++++++++---- 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index 99edae884..664eb6dd0 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -1376,6 +1376,13 @@ public static partial class Application var view = View.FindDeepestView (Current, a.MouseEvent.X, a.MouseEvent.Y); + // TODO: Remove this temporary filter: + if (view is Adornment adornment) + { + view = adornment.Parent; + } + + if (view is { WantContinuousButtonPressed: true }) { WantContinuousButtonPressedView = view; diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs index 7b7345834..6cbf946aa 100644 --- a/Terminal.Gui/View/Layout/ViewLayout.cs +++ b/Terminal.Gui/View/Layout/ViewLayout.cs @@ -545,20 +545,27 @@ public partial class View } } - #nullable enable +#nullable enable /// Finds which view that belong to the superview at the provided location. /// The superview where to look for. /// The column location in the superview. /// The row location in the superview. + /// TODO: Remove this after unit tests are fixed /// /// The view that was found at the and coordinates. /// if no view was found. /// + // CONCURRENCY: This method is not thread-safe. // Undefined behavior and likely program crashes are exposed by unsynchronized access to InternalSubviews. - public static View? FindDeepestView (View? start, int x, int y) + public static View? FindDeepestView (View? start, int x, int y, bool findAdornments = false) { - if (start is null || !start.Frame.Contains (x, y)) + if (start is null || !start.Visible) + { + return null; + } + + if (!start.Frame.Contains (x, y)) { return null; } @@ -582,7 +589,7 @@ public partial class View } return start; } - #nullable restore +#nullable restore /// Gets the with a screen-relative location. /// The location and size of the view in screen-relative coordinates. diff --git a/UnitTests/View/FindDeepestViewTests.cs b/UnitTests/View/FindDeepestViewTests.cs index 091146f1f..ddf19198c 100644 --- a/UnitTests/View/FindDeepestViewTests.cs +++ b/UnitTests/View/FindDeepestViewTests.cs @@ -16,14 +16,14 @@ public class FindDeepestViewTests (ITestOutputHelper output) [InlineData (2, 2)] public void Returns_Start_If_No_SubViews (int testX, int testY) { - var view = new View () + var start = new View () { Width = 10, Height = 10, }; - Assert.Same (view, View.FindDeepestView (view, testX, testY)); + Assert.Same (start, View.FindDeepestView (start, testX, testY)); } - + // Test that FindDeepestView returns null if the start view has no subviews and coords are outside the view [Theory] [InlineData (0, 0)] @@ -31,13 +31,29 @@ public class FindDeepestViewTests (ITestOutputHelper output) [InlineData (20, 20)] public void Returns_Null_If_No_SubViews_Coords_Outside (int testX, int testY) { - var view = new View () + var start = new View () { X = 1, Y = 2, Width = 10, Height = 10, }; - Assert.Null(View.FindDeepestView (view, testX, testY)); + Assert.Null(View.FindDeepestView (start, testX, testY)); + } + + [Theory] + [InlineData (0, 0)] + [InlineData (2, 1)] + [InlineData (20, 20)] + public void Returns_Null_If_Start_Not_Visible (int testX, int testY) + { + var start = new View () + { + X = 1, Y = 2, + Width = 10, Height = 10, + Visible = false, + }; + + Assert.Null (View.FindDeepestView (start, testX, testY)); } // Test that FindDeepestView returns the correct view if the start view has subviews @@ -52,7 +68,7 @@ public class FindDeepestViewTests (ITestOutputHelper output) [InlineData (5, 6, true)] public void Returns_Correct_If_SubViews (int testX, int testY, bool expectedSubViewFound) { - var view = new View () + var start = new View () { Width = 10, Height = 10, }; @@ -62,13 +78,73 @@ public class FindDeepestViewTests (ITestOutputHelper output) X = 1, Y = 2, Width = 5, Height = 5, }; - view.Add (subview); + start.Add (subview); - var found = View.FindDeepestView (view, testX, testY); + var found = View.FindDeepestView (start, testX, testY); Assert.Equal (expectedSubViewFound, found == subview); } + [Theory] + [InlineData (0, 0, false)] + [InlineData (1, 1, false)] + [InlineData (9, 9, false)] + [InlineData (10, 10, false)] + [InlineData (6, 7, false)] + [InlineData (1, 2, false)] + [InlineData (5, 6, false)] + public void Returns_Null_If_SubView_NotVisible (int testX, int testY, bool expectedSubViewFound) + { + var start = new View () + { + Width = 10, Height = 10, + }; + + var subview = new View () + { + X = 1, Y = 2, + Width = 5, Height = 5, + Visible = false + }; + start.Add (subview); + + var found = View.FindDeepestView (start, testX, testY); + + Assert.Equal (expectedSubViewFound, found == subview); + } + + + [Theory] + [InlineData (0, 0, false)] + [InlineData (1, 1, false)] + [InlineData (9, 9, false)] + [InlineData (10, 10, false)] + [InlineData (6, 7, false)] + [InlineData (1, 2, false)] + [InlineData (5, 6, false)] + public void Returns_Null_If_Not_Visible_And_SubView_Visible (int testX, int testY, bool expectedSubViewFound) + { + var start = new View () + { + Width = 10, Height = 10, + Visible = false + }; + + var subview = new View () + { + X = 1, Y = 2, + Width = 5, Height = 5, + }; + start.Add (subview); + subview.Visible = true; + Assert.True (subview.Visible); + Assert.False (start.Visible); + var found = View.FindDeepestView (start, testX, testY); + + Assert.Equal (expectedSubViewFound, found == subview); + } + + // Test that FindDeepestView works if the start view has positive Adornments [Theory] [InlineData (0, 0, false)] @@ -84,20 +160,20 @@ public class FindDeepestViewTests (ITestOutputHelper output) [InlineData (6, 7, true)] public void Returns_Correct_If_Start_Has_Adornments (int testX, int testY, bool expectedSubViewFound) { - var view = new View () + var start = new View () { Width = 10, Height = 10, }; - view.Margin.Thickness = new Thickness (1); + start.Margin.Thickness = new Thickness (1); var subview = new View () { X = 1, Y = 2, Width = 5, Height = 5, }; - view.Add (subview); + start.Add (subview); - var found = View.FindDeepestView (view, testX, testY); + var found = View.FindDeepestView (start, testX, testY); Assert.Equal (expectedSubViewFound, found == subview); } @@ -117,7 +193,7 @@ public class FindDeepestViewTests (ITestOutputHelper output) [InlineData (2, 3, true)] public void Returns_Correct_If_SubView_Has_Adornments (int testX, int testY, bool expectedSubViewFound) { - var view = new View () + var start = new View () { Width = 10, Height = 10, }; @@ -128,9 +204,9 @@ public class FindDeepestViewTests (ITestOutputHelper output) Width = 5, Height = 5, }; subview.Margin.Thickness = new Thickness (1); - view.Add (subview); + start.Add (subview); - var found = View.FindDeepestView (view, testX, testY); + var found = View.FindDeepestView (start, testX, testY); Assert.Equal (expectedSubViewFound, found == subview); }