Skip to content

Commit fe98ce6

Browse files
committed
Added AdvancingFocus events.
1 parent 37e983a commit fe98ce6

File tree

4 files changed

+45
-34
lines changed

4 files changed

+45
-34
lines changed

Terminal.Gui/View/Navigation/AdvanceFocusEventArgs.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,4 @@ public AdvanceFocusEventArgs (NavigationDirection direction, TabBehavior? behavi
1515

1616
/// <summary>Gets or sets the view that is gaining focus.</summary>
1717
public TabBehavior? Behavior { get; set; }
18-
1918
}

Terminal.Gui/View/View.Navigation.cs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#nullable enable
22
using System.Diagnostics;
3-
using System.Reflection.PortableExecutable;
43

54
namespace Terminal.Gui;
65

@@ -18,7 +17,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
1817
/// If there is no next/previous view to advance to, the focus is set to the view itself.
1918
/// </para>
2019
/// <para>
21-
/// See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
20+
/// See the View Navigation Deep Dive for more information:
21+
/// <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
2222
/// </para>
2323
/// </remarks>
2424
/// <param name="direction"></param>
@@ -136,8 +136,11 @@ public bool AdvanceFocus (NavigationDirection direction, TabBehavior? behavior)
136136
if (view != this)
137137
{
138138
// Tell it to try the other way.
139-
return view.RaiseAdvancingFocus (direction == NavigationDirection.Forward ? NavigationDirection.Backward : NavigationDirection.Forward, behavior);
139+
return view.RaiseAdvancingFocus (
140+
direction == NavigationDirection.Forward ? NavigationDirection.Backward : NavigationDirection.Forward,
141+
behavior);
140142
}
143+
141144
return view == this;
142145
}
143146

@@ -172,6 +175,10 @@ private bool RaiseAdvancingFocus (NavigationDirection direction, TabBehavior? be
172175
/// Called when <see cref="View.AdvanceFocus"/> is about to advance focus.
173176
/// </summary>
174177
/// <remarks>
178+
/// <para>
179+
/// If a view cancels the event and the focus could not otherwise advance, the Navigation direction will be
180+
/// reversed and the event will be raised again.
181+
/// </para>
175182
/// </remarks>
176183
/// <returns>
177184
/// <see langword="true"/>, if the focus advance is to be cancelled, <see langword="false"/>
@@ -187,16 +194,17 @@ private bool RaiseAdvancingFocus (NavigationDirection direction, TabBehavior? be
187194
/// Cancel the event to prevent the focus from advancing.
188195
/// </para>
189196
/// <para>
190-
/// Use <see cref="HasFocusChanged"/> to be notified after the focus has changed.
197+
/// If a view cancels the event and the focus could not otherwise advance, the Navigation direction will be
198+
/// reversed and the event will be raised again.
191199
/// </para>
192200
/// </remarks>
193201
public event EventHandler<AdvanceFocusEventArgs>? AdvancingFocus;
194202

195-
196203
/// <summary>Gets or sets a value indicating whether this <see cref="View"/> can be focused.</summary>
197204
/// <remarks>
198205
/// <para>
199-
/// See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
206+
/// See the View Navigation Deep Dive for more information:
207+
/// <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
200208
/// </para>
201209
/// <para>
202210
/// <see cref="SuperView"/> must also have <see cref="CanFocus"/> set to <see langword="true"/>.
@@ -235,13 +243,9 @@ public bool CanFocus
235243

236244
if (!_canFocus && HasFocus)
237245
{
238-
if (Title == "AdornmentsEditor")
239-
{
240-
241-
}
242246
// If CanFocus is set to false and this view has focus, make it leave focus
243-
// Set traverssingdown so we don't go back up the hierachy...
244-
SetHasFocusFalse (null, traversingDown: false);
247+
// Set transversing down so we don't go back up the hierarchy...
248+
SetHasFocusFalse (null, false);
245249
}
246250

247251
if (_canFocus && !HasFocus && Visible && SuperView is { Focused: null })
@@ -390,7 +394,8 @@ internal bool RestoreFocus ()
390394
/// </summary>
391395
/// <remarks>
392396
/// <para>
393-
/// See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
397+
/// See the View Navigation Deep Dive for more information:
398+
/// <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
394399
/// </para>
395400
/// <para>
396401
/// Only Views that are visible, enabled, and have <see cref="CanFocus"/> set to <see langword="true"/> are
@@ -442,6 +447,7 @@ public bool HasFocus
442447
SetHasFocusFalse (null);
443448

444449
Debug.Assert (!_hasFocus);
450+
445451
if (_hasFocus)
446452
{
447453
// force it.
@@ -458,7 +464,8 @@ public bool HasFocus
458464
/// </summary>
459465
/// <remarks>
460466
/// <para>
461-
/// See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
467+
/// See the View Navigation Deep Dive for more information:
468+
/// <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
462469
/// </para>
463470
/// </remarks>
464471
/// <returns><see langword="true"/> if the focus changed; <see langword="true"/> false otherwise.</returns>
@@ -677,7 +684,8 @@ private bool RaiseFocusChanging (bool currentHasFocus, bool newHasFocus, View? c
677684
/// </param>
678685
/// <param name="traversingDown">
679686
/// Set to true to traverse down the focus
680-
/// chain only. If false, the method will attempt to AdvanceFocus on the superview or restorefocus on Application.Navigation.GetFocused().
687+
/// chain only. If false, the method will attempt to AdvanceFocus on the superview or restorefocus on
688+
/// Application.Navigation.GetFocused().
681689
/// </param>
682690
/// <exception cref="InvalidOperationException"></exception>
683691
private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false)
@@ -707,6 +715,7 @@ private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false
707715
{
708716
// The above will cause SetHasFocusFalse, so we can return
709717
Debug.Assert (!_hasFocus);
718+
710719
return;
711720
}
712721
}
@@ -744,6 +753,7 @@ private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false
744753
{
745754
// The above caused SetHasFocusFalse, so we can return
746755
Debug.Assert (!_hasFocus);
756+
747757
return;
748758
}
749759
}
@@ -765,9 +775,11 @@ private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false
765775
{
766776
// The above caused SetHasFocusFalse, so we can return
767777
Debug.Assert (!_hasFocus);
778+
768779
return;
769780
}
770781
}
782+
771783
// No other focusable view to be found. Just "leave" us...
772784
}
773785

@@ -880,7 +892,8 @@ protected virtual void OnHasFocusChanged (bool newHasFocus, View? previousFocuse
880892
#region Tab/Focus Handling
881893

882894
/// <summary>
883-
/// 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
895+
/// Gets the subviews and Adornments of this view that are scoped to the specified behavior and direction. If behavior
896+
/// is null, all focusable subviews and
884897
/// Adornments are returned.
885898
/// </summary>
886899
/// <param name="direction"></param>
@@ -899,7 +912,6 @@ internal View [] GetFocusChain (NavigationDirection direction, TabBehavior? beha
899912
filteredSubviews = _subviews?.Where (v => v is { CanFocus: true, Visible: true, Enabled: true });
900913
}
901914

902-
903915
// How about in Adornments?
904916
if (Padding is { CanFocus: true, Visible: true, Enabled: true } && Padding.TabStop == behavior)
905917
{
@@ -930,11 +942,14 @@ internal View [] GetFocusChain (NavigationDirection direction, TabBehavior? beha
930942
/// Gets or sets the behavior of <see cref="AdvanceFocus"/> for keyboard navigation.
931943
/// </summary>
932944
/// <remarks>
933-
/// <remarks>
945+
/// <remarks>
946+
/// <para>
947+
/// See the View Navigation Deep Dive for more information:
948+
/// <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
949+
/// </para>
950+
/// </remarks>
951+
/// ///
934952
/// <para>
935-
/// See the View Navigation Deep Dive for more information: <see href="https://gui-cs.github.io/Terminal.GuiV2Docs/docs/navigation.html"/>
936-
/// </para>
937-
/// </remarks> /// <para>
938953
/// If <see langword="null"/> the tab stop has not been set and setting <see cref="CanFocus"/> to true will set it
939954
/// to
940955
/// <see cref="TabBehavior.TabStop"/>.

Terminal.Gui/Views/HexView.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,11 @@ private void RedisplayLine (long pos)
947947
/// <inheritdoc />
948948
protected override bool OnAdvancingFocus (NavigationDirection direction, TabBehavior? behavior)
949949
{
950+
if (behavior is { } && behavior != TabStop)
951+
{
952+
return false;
953+
}
954+
950955
if (direction == NavigationDirection.Forward && _leftSideHasFocus)
951956
{
952957
_leftSideHasFocus = !_leftSideHasFocus;

UnitTests/View/Navigation/NavigationTests.cs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,6 @@ public void AllViews_AtLeastOneNavKey_Advances (Type viewType)
6060
case TabBehavior.NoStop:
6161
case TabBehavior.TabGroup:
6262
Application.OnKeyDown (key);
63-
64-
if (view.HasFocus)
65-
{
66-
// Try once more (HexView)
67-
Application.OnKeyDown (key);
68-
}
69-
7063
break;
7164
default:
7265
Application.OnKeyDown (Key.Tab);
@@ -78,12 +71,11 @@ public void AllViews_AtLeastOneNavKey_Advances (Type viewType)
7871
{
7972
left = true;
8073
_output.WriteLine ($"{view.GetType ().Name} - {key} Left.");
81-
view.SetFocus ();
82-
}
83-
else
84-
{
85-
_output.WriteLine ($"{view.GetType ().Name} - {key} did not Leave.");
74+
75+
break;
8676
}
77+
78+
_output.WriteLine ($"{view.GetType ().Name} - {key} did not Leave.");
8779
}
8880

8981
top.Dispose ();

0 commit comments

Comments
 (0)