Browse Source

Reapply "Reapply "Rewrote FindDeepestView to be clearer and more performant""

This reverts commit 0983c6997d57401f6c4ee9bf777e857621572d8b.
Tig 1 year ago
parent
commit
d8043cdbc4
1 changed files with 44 additions and 34 deletions
  1. 44 34
      Terminal.Gui/View/Layout/ViewLayout.cs

+ 44 - 34
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -605,53 +605,63 @@ public partial class View
     // CONCURRENCY: This method is not thread-safe. Undefined behavior and likely program crashes are exposed by unsynchronized access to InternalSubviews.
     // CONCURRENCY: This method is not thread-safe. Undefined behavior and likely program crashes are exposed by unsynchronized access to InternalSubviews.
     internal static View? FindDeepestView (View? start, int x, int y)
     internal static View? FindDeepestView (View? start, int x, int y)
     {
     {
-        if (start is null || !start.Visible || !start.Contains (x, y))
+        while (start is { Visible: true } && start.Contains (x, y))
         {
         {
-            return null;
-        }
-
-        Adornment? found = null;
+            Adornment? found = null;
 
 
-        if (start.Margin.Contains (x, y))
-        {
-            found = start.Margin;
-        }
-        else if (start.Border.Contains (x, y))
-        {
-            found = start.Border;
-        }
-        else if (start.Padding.Contains (x, y))
-        {
-            found = start.Padding;
-        }
+            if (start.Margin.Contains (x, y))
+            {
+                found = start.Margin;
+            }
+            else if (start.Border.Contains (x, y))
+            {
+                found = start.Border;
+            }
+            else if (start.Padding.Contains (x, y))
+            {
+                found = start.Padding;
+            }
 
 
-        Point viewportOffset = start.GetViewportOffsetFromFrame ();
+            Point viewportOffset = start.GetViewportOffsetFromFrame ();
 
 
-        if (found is { })
-        {
-            start = found;
-            viewportOffset = found.Parent.Frame.Location;
-        }
-
-        if (start.InternalSubviews is { Count: > 0 })
-        {
-            int startOffsetX = x - (start.Frame.X + viewportOffset.X);
-            int startOffsetY = y - (start.Frame.Y + viewportOffset.Y);
+            if (found is { })
+            {
+                start = found;
+                viewportOffset = found.Parent.Frame.Location;
+            }
 
 
-            for (int i = start.InternalSubviews.Count - 1; i >= 0; i--)
+            if (start.InternalSubviews is { Count: > 0 })
             {
             {
-                View nextStart = start.InternalSubviews [i];
+                int startOffsetX = x - (start.Frame.X + viewportOffset.X);
+                int startOffsetY = y - (start.Frame.Y + viewportOffset.Y);
 
 
-                if (nextStart.Visible && nextStart.Contains (startOffsetX + start.Viewport.X, startOffsetY + start.Viewport.Y))
+                for (int i = start.InternalSubviews.Count - 1; i >= 0; i--)
                 {
                 {
-                    // TODO: Remove recursion
-                    return FindDeepestView (nextStart, startOffsetX + start.Viewport.X, startOffsetY + start.Viewport.Y) ?? nextStart;
+                    View nextStart = start.InternalSubviews [i];
+
+                    if (nextStart.Visible && nextStart.Contains (startOffsetX + start.Viewport.X, startOffsetY + start.Viewport.Y))
+                    {
+                        start = nextStart;
+                        x = startOffsetX + start.Viewport.X;
+                        y = startOffsetY + start.Viewport.Y;
+                        break;
+                    }
+
+                    if (i == 0)
+                    {
+                        return start; // If no visible subview is found, return the current start view
+                    }
                 }
                 }
             }
             }
+            else
+            {
+                return start;
+            }
         }
         }
 
 
-        return start;
+        return null;
     }
     }
+
 #nullable restore
 #nullable restore
 
 
     /// <summary>
     /// <summary>