Browse Source

Added AdvancingFocus events.

Tig 9 months ago
parent
commit
fe98ce6bda

+ 0 - 1
Terminal.Gui/View/Navigation/AdvanceFocusEventArgs.cs

@@ -15,5 +15,4 @@ public class AdvanceFocusEventArgs : CancelEventArgs<bool>
 
     /// <summary>Gets or sets the view that is gaining focus.</summary>
     public TabBehavior? Behavior { get; set; }
-
 }

+ 36 - 21
Terminal.Gui/View/View.Navigation.cs

@@ -1,6 +1,5 @@
 #nullable enable
 using System.Diagnostics;
-using System.Reflection.PortableExecutable;
 
 namespace Terminal.Gui;
 
@@ -18,7 +17,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///         If there is no next/previous view to advance to, the focus is set to the view itself.
     ///     </para>
     ///     <para>
-    ///         See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
+    ///         See the View Navigation Deep Dive for more information:
+    ///         <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
     ///     </para>
     /// </remarks>
     /// <param name="direction"></param>
@@ -136,8 +136,11 @@ public partial class View // Focus and cross-view navigation management (TabStop
             if (view != this)
             {
                 // Tell it to try the other way.
-                return view.RaiseAdvancingFocus (direction == NavigationDirection.Forward ? NavigationDirection.Backward : NavigationDirection.Forward, behavior);
+                return view.RaiseAdvancingFocus (
+                                                 direction == NavigationDirection.Forward ? NavigationDirection.Backward : NavigationDirection.Forward,
+                                                 behavior);
             }
+
             return view == this;
         }
 
@@ -172,6 +175,10 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///     Called when <see cref="View.AdvanceFocus"/> is about to advance focus.
     /// </summary>
     /// <remarks>
+    ///     <para>
+    ///         If a view cancels the event and the focus could not otherwise advance, the Navigation direction will be
+    ///         reversed and the event will be raised again.
+    ///     </para>
     /// </remarks>
     /// <returns>
     ///     <see langword="true"/>, if the focus advance is to be cancelled, <see langword="false"/>
@@ -187,16 +194,17 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///         Cancel the event to prevent the focus from advancing.
     ///     </para>
     ///     <para>
-    ///         Use <see cref="HasFocusChanged"/> to be notified after the focus has changed.
+    ///         If a view cancels the event and the focus could not otherwise advance, the Navigation direction will be
+    ///         reversed and the event will be raised again.
     ///     </para>
     /// </remarks>
     public event EventHandler<AdvanceFocusEventArgs>? AdvancingFocus;
 
-
     /// <summary>Gets or sets a value indicating whether this <see cref="View"/> can be focused.</summary>
     /// <remarks>
     ///     <para>
-    ///         See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
+    ///         See the View Navigation Deep Dive for more information:
+    ///         <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
     ///     </para>
     ///     <para>
     ///         <see cref="SuperView"/> must also have <see cref="CanFocus"/> set to <see langword="true"/>.
@@ -235,13 +243,9 @@ public partial class View // Focus and cross-view navigation management (TabStop
 
             if (!_canFocus && HasFocus)
             {
-                if (Title == "AdornmentsEditor")
-                {
-
-                }
                 // If CanFocus is set to false and this view has focus, make it leave focus
-                // Set traverssingdown so we don't go back up the hierachy...
-                SetHasFocusFalse (null, traversingDown: false);
+                // Set transversing down so we don't go back up the hierarchy...
+                SetHasFocusFalse (null, false);
             }
 
             if (_canFocus && !HasFocus && Visible && SuperView is { Focused: null })
@@ -390,7 +394,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
+    ///         See the View Navigation Deep Dive for more information:
+    ///         <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
     ///     </para>
     ///     <para>
     ///         Only Views that are visible, enabled, and have <see cref="CanFocus"/> set to <see langword="true"/> are
@@ -442,6 +447,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
                 SetHasFocusFalse (null);
 
                 Debug.Assert (!_hasFocus);
+
                 if (_hasFocus)
                 {
                     // force it.
@@ -458,7 +464,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     /// </summary>
     /// <remarks>
     ///     <para>
-    ///         See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
+    ///         See the View Navigation Deep Dive for more information:
+    ///         <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
     ///     </para>
     /// </remarks>
     /// <returns><see langword="true"/> if the focus changed; <see langword="true"/> false otherwise.</returns>
@@ -677,7 +684,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     /// </param>
     /// <param name="traversingDown">
     ///     Set to true to traverse down the focus
-    ///     chain only. If false, the method will attempt to AdvanceFocus on the superview or restorefocus on Application.Navigation.GetFocused().
+    ///     chain only. If false, the method will attempt to AdvanceFocus on the superview or restorefocus on
+    ///     Application.Navigation.GetFocused().
     /// </param>
     /// <exception cref="InvalidOperationException"></exception>
     private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false)
@@ -707,6 +715,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
                 {
                     // The above will cause SetHasFocusFalse, so we can return
                     Debug.Assert (!_hasFocus);
+
                     return;
                 }
             }
@@ -744,6 +753,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
                 {
                     // The above caused SetHasFocusFalse, so we can return
                     Debug.Assert (!_hasFocus);
+
                     return;
                 }
             }
@@ -765,9 +775,11 @@ public partial class View // Focus and cross-view navigation management (TabStop
                 {
                     // The above caused SetHasFocusFalse, so we can return
                     Debug.Assert (!_hasFocus);
+
                     return;
                 }
             }
+
             // No other focusable view to be found. Just "leave" us...
         }
 
@@ -880,7 +892,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
     #region Tab/Focus Handling
 
     /// <summary>
-    ///     Gets the subviews and Adornments of this view that are scoped to the specified behavior and direction. If behavior is null, all focusable subviews and
+    ///     Gets the subviews and Adornments of this view that are scoped to the specified behavior and direction. If behavior
+    ///     is null, all focusable subviews and
     ///     Adornments are returned.
     /// </summary>
     /// <param name="direction"></param>
@@ -899,7 +912,6 @@ public partial class View // Focus and cross-view navigation management (TabStop
             filteredSubviews = _subviews?.Where (v => v is { CanFocus: true, Visible: true, Enabled: true });
         }
 
-
         // How about in Adornments? 
         if (Padding is { CanFocus: true, Visible: true, Enabled: true } && Padding.TabStop == behavior)
         {
@@ -930,11 +942,14 @@ public partial class View // Focus and cross-view navigation management (TabStop
     ///     Gets or sets the behavior of <see cref="AdvanceFocus"/> for keyboard navigation.
     /// </summary>
     /// <remarks>
-    /// <remarks>
+    ///     <remarks>
+    ///         <para>
+    ///             See the View Navigation Deep Dive for more information:
+    ///             <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
+    ///         </para>
+    ///     </remarks>
+    ///     ///
     ///     <para>
-    ///         See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
-    ///     </para>
-    /// </remarks>    ///     <para>
     ///         If <see langword="null"/> the tab stop has not been set and setting <see cref="CanFocus"/> to true will set it
     ///         to
     ///         <see cref="TabBehavior.TabStop"/>.

+ 5 - 0
Terminal.Gui/Views/HexView.cs

@@ -947,6 +947,11 @@ public class HexView : View, IDesignable
     /// <inheritdoc />
     protected override bool OnAdvancingFocus (NavigationDirection direction, TabBehavior? behavior)
     {
+        if (behavior is { } && behavior != TabStop)
+        {
+            return false;
+        }
+
         if (direction == NavigationDirection.Forward && _leftSideHasFocus)
         {
             _leftSideHasFocus = !_leftSideHasFocus;

+ 4 - 12
UnitTests/View/Navigation/NavigationTests.cs

@@ -60,13 +60,6 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
                 case TabBehavior.NoStop:
                 case TabBehavior.TabGroup:
                     Application.OnKeyDown (key);
-
-                    if (view.HasFocus)
-                    {
-                        // Try once more (HexView)
-                        Application.OnKeyDown (key);
-                    }
-
                     break;
                 default:
                     Application.OnKeyDown (Key.Tab);
@@ -78,12 +71,11 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
             {
                 left = true;
                 _output.WriteLine ($"{view.GetType ().Name} - {key} Left.");
-                view.SetFocus ();
-            }
-            else
-            {
-                _output.WriteLine ($"{view.GetType ().Name} - {key} did not Leave.");
+
+                break;
             }
+
+            _output.WriteLine ($"{view.GetType ().Name} - {key} did not Leave.");
         }
 
         top.Dispose ();