Browse Source

Rewrote FocusNearestView to be understandable

Tig 1 year ago
parent
commit
911f2c66de

+ 19 - 17
Terminal.Gui/Application/Application.Navigation.cs

@@ -32,7 +32,7 @@ internal static class ApplicationNavigation
     }
     }
 
 
     /// <summary>
     /// <summary>
-    ///    Sets the focus to the next view in the <see cref="View.TabIndexes"/> list. If the last view is focused, the first view is focused.
+    ///    INTERNAL API that sets the focus to the next view in <paramref name="viewsInTabIndexes"/>. If the last view is focused, the first view is focused.
     /// </summary>
     /// </summary>
     /// <param name="viewsInTabIndexes"></param>
     /// <param name="viewsInTabIndexes"></param>
     /// <param name="direction"></param>
     /// <param name="direction"></param>
@@ -43,39 +43,41 @@ internal static class ApplicationNavigation
             return;
             return;
         }
         }
 
 
-        var found = false;
-        var focusProcessed = false;
-        var idx = 0;
+        bool foundCurrentView = false;
+        bool focusSet = false;
+        IEnumerable<View> indexes = viewsInTabIndexes as View [] ?? viewsInTabIndexes.ToArray ();
+        int viewCount = indexes.Count ();
+        int currentIndex = 0;
 
 
-        foreach (View v in viewsInTabIndexes)
+        foreach (View view in indexes)
         {
         {
-            if (v == Application.Current)
+            if (view == Application.Current)
             {
             {
-                found = true;
+                foundCurrentView = true;
             }
             }
-
-            if (found && v != Application.Current)
+            else if (foundCurrentView && !focusSet)
             {
             {
                 Application.Current!.SuperView?.AdvanceFocus (direction);
                 Application.Current!.SuperView?.AdvanceFocus (direction);
+                focusSet = true;
 
 
-                focusProcessed = true;
-
-                if (Application.Current.SuperView?.Focused is { } && Application.Current.SuperView.Focused != Application.Current)
+                if (Application.Current.SuperView?.Focused != Application.Current)
                 {
                 {
                     return;
                     return;
                 }
                 }
             }
             }
-            else if (found && !focusProcessed && idx == viewsInTabIndexes.Count () - 1)
+
+            currentIndex++;
+
+            if (foundCurrentView && !focusSet && currentIndex == viewCount)
             {
             {
-                viewsInTabIndexes.ToList () [0].SetFocus ();
+                indexes.First ().SetFocus ();
             }
             }
-
-            idx++;
         }
         }
     }
     }
 
 
     /// <summary>
     /// <summary>
-    ///     Moves the focus to the next view. Honors <see cref="ViewArrangement.Overlapped"/> and will only move to the next subview
+    ///     Moves the focus to the next focusable view.
+    ///     Honors <see cref="ViewArrangement.Overlapped"/> and will only move to the next subview
     ///     if the current and next subviews are not overlapped.
     ///     if the current and next subviews are not overlapped.
     /// </summary>
     /// </summary>
     internal static void MoveNextView ()
     internal static void MoveNextView ()

+ 3 - 1
Terminal.Gui/View/View.Navigation.cs

@@ -444,7 +444,6 @@ public partial class View // Focus and cross-view navigation management (TabStop
         }
         }
     }
     }
 
 
-    // TODO: Combine FocusFirst and FocusLast into a single method that takes a direction parameter for less code duplication and easier testing.
     /// <summary>
     /// <summary>
     ///     Focuses the first focusable view in <see cref="View.TabIndexes"/> if one exists. If there are no views in
     ///     Focuses the first focusable view in <see cref="View.TabIndexes"/> if one exists. If there are no views in
     ///     <see cref="View.TabIndexes"/> then the focus is set to the view itself.
     ///     <see cref="View.TabIndexes"/> then the focus is set to the view itself.
@@ -622,7 +621,10 @@ public partial class View // Focus and cross-view navigation management (TabStop
 
 
         if (Focused is { })
         if (Focused is { })
         {
         {
+            // Leave
             Focused.SetHasFocus (false, this);
             Focused.SetHasFocus (false, this);
+
+            // Signal that nothing is focused, and callers should try a peer-subview
             Focused = null;
             Focused = null;
         }
         }