mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Done with refactor. Nav unit tests all pass. Fixing View unit tests...
This commit is contained in:
@@ -333,7 +333,7 @@ public static partial class Application // Keyboard handling
|
||||
() =>
|
||||
{
|
||||
View? current = Application.Current;
|
||||
if (current is {})
|
||||
if (current is { })
|
||||
{
|
||||
return current.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
|
||||
}
|
||||
@@ -363,7 +363,7 @@ public static partial class Application // Keyboard handling
|
||||
View? current = Application.Current;
|
||||
if (current is { })
|
||||
{
|
||||
return current.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
|
||||
return current.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -381,9 +381,22 @@ public static partial class Application // Keyboard handling
|
||||
Command.PreviousViewOrTop,
|
||||
() =>
|
||||
{
|
||||
ApplicationNavigation.MovePreviousViewOrTop ();
|
||||
if (ApplicationOverlapped.OverlappedTop is null)
|
||||
{
|
||||
View? current = Application.Current;
|
||||
if (current is { })
|
||||
{
|
||||
return current.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplicationOverlapped.OverlappedMovePrevious();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -186,7 +186,12 @@ public static partial class Application // Run (Begin, Run, End, Stop)
|
||||
|
||||
toplevel.LayoutSubviews ();
|
||||
toplevel.PositionToplevels ();
|
||||
toplevel.AdvanceFocus (NavigationDirection.Forward, null);//.FocusDeepest (null, NavigationDirection.Forward);
|
||||
// Try to set initial focus to any TabGroup
|
||||
if (!toplevel.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup))
|
||||
{
|
||||
// That didn't work. Try TabStop.
|
||||
toplevel.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
|
||||
}
|
||||
ApplicationOverlapped.BringOverlappedTopToFront ();
|
||||
|
||||
if (refreshDriver)
|
||||
|
||||
@@ -107,27 +107,4 @@ public class ApplicationNavigation
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal static void MovePreviousViewOrTop ()
|
||||
{
|
||||
if (ApplicationOverlapped.OverlappedTop is null)
|
||||
{
|
||||
Toplevel? top = Application.Current!.Modal ? Application.Current : Application.Top;
|
||||
top!.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
|
||||
|
||||
if (top.Focused is null)
|
||||
{
|
||||
top.AdvanceFocus (NavigationDirection.Backward, null);
|
||||
}
|
||||
|
||||
top.SetNeedsDisplay ();
|
||||
ApplicationOverlapped.BringOverlappedTopToFront ();
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplicationOverlapped.OverlappedMovePrevious ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
if (value)
|
||||
{
|
||||
// NOTE: If Application.Navigation is null, we pass null to FocusChanging. For unit tests.
|
||||
if (SetHasFocusTrue (Application.Navigation?.GetFocused ()))
|
||||
(bool focusSet, bool _) = SetHasFocusTrue (Application.Navigation?.GetFocused ());
|
||||
if (focusSet)
|
||||
{
|
||||
// The change happened
|
||||
// HasFocus is now true
|
||||
@@ -67,7 +68,8 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
/// </summary>
|
||||
public bool SetFocus ()
|
||||
{
|
||||
return SetHasFocusTrue (Application.Navigation?.GetFocused ());
|
||||
(bool focusSet, bool _) = SetHasFocusTrue (Application.Navigation?.GetFocused ());
|
||||
return focusSet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -78,82 +80,58 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
/// <param name="traversingUp"></param>
|
||||
/// <returns><see langword="true"/> if <see cref="HasFocus"/> was changed to <see langword="true"/>.</returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
private bool SetHasFocusTrue ([CanBeNull] View previousFocusedView, bool traversingUp = false)
|
||||
private (bool focusSet, bool cancelled) SetHasFocusTrue ([CanBeNull] View previousFocusedView, bool traversingUp = false)
|
||||
{
|
||||
Debug.Assert (ApplicationNavigation.IsInHierarchy (SuperView, this));
|
||||
|
||||
// Pre-conditions
|
||||
if (_hasFocus)
|
||||
{
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
if (CanFocus && SuperView is { CanFocus: false })
|
||||
{
|
||||
Debug.WriteLine ($@"WARNING: Attempt to FocusChanging where SuperView.CanFocus == false. {this}");
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
if (!CanBeVisible (this) || !Enabled)
|
||||
{
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
if (!CanFocus)
|
||||
{
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
bool previousValue = HasFocus;
|
||||
|
||||
if (!traversingUp)
|
||||
bool cancelled = NotifyFocusChanging (false, true, previousFocusedView, this);
|
||||
|
||||
if (cancelled)
|
||||
{
|
||||
|
||||
// If we're here, we can be focused. But we may have subviews.
|
||||
|
||||
// Restore focus to the previously most focused subview in the subview-hierarchy
|
||||
if (RestoreFocus (TabStop))
|
||||
{
|
||||
// A subview was focused. We're done because the subview has focus and it recursed up the superview hierarchy.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Couldn't restore focus, so use Advance to navigate to the next focusable subview
|
||||
if (AdvanceFocus (NavigationDirection.Forward, null))
|
||||
{
|
||||
// A subview was focused. We're done because the subview has focus and it recursed up the superview hierarchy.
|
||||
return true;
|
||||
}
|
||||
return (false, true);
|
||||
}
|
||||
|
||||
if (NotifyFocusChanging (false, true, previousFocusedView, this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//// If we previously had a subview with focus (`Focused = subview`), we need to make sure that all subviews down the `subview`-hierarchy LeaveFocus.
|
||||
//// LeaveFocus will recurse down the subview hierarchy and will also set PreviouslyMostFocused
|
||||
//View focused = Focused;
|
||||
//focused?.SetHasFocusFalse (this, true);
|
||||
|
||||
// If we're here, we're the most-focusable view in the application OR we're traversing up the superview hierarchy.
|
||||
|
||||
// If we previously had a subview with focus (`Focused = subview`), we need to make sure that all subviews down the `subview`-hierarchy LeaveFocus.
|
||||
// LeaveFocus will recurse down the subview hierarchy and will also set PreviouslyMostFocused
|
||||
View focused = Focused;
|
||||
focused?.SetHasFocusFalse (this, true);
|
||||
|
||||
// We need to ensure all superviews up the superview hierarchy have focus.
|
||||
// Make sure superviews up the superview hierarchy have focus.
|
||||
// Any of them may cancel gaining focus. In which case we need to back out.
|
||||
if (SuperView is { HasFocus: false } sv)
|
||||
{
|
||||
// Tell SetHasFocusTrue that we're traversing up the superview hierarchy
|
||||
if (!sv.SetHasFocusTrue (previousFocusedView, true))
|
||||
(bool focusSet, bool svCancelled) = sv.SetHasFocusTrue (previousFocusedView, true);
|
||||
if (!focusSet)
|
||||
{
|
||||
// The change didn't happen.
|
||||
return false;
|
||||
return (false, svCancelled);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're here:
|
||||
// - we're the most-focusable view in the application
|
||||
// - all superviews up the superview hierarchy have focus.
|
||||
// - By setting _hasFocus to true we definitively change HasFocus for this view.
|
||||
// By setting _hasFocus to true we definitively change HasFocus for this view.
|
||||
|
||||
// Get whatever peer has focus, if any
|
||||
View focusedPeer = SuperView?.Focused;
|
||||
@@ -163,11 +141,23 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
// Ensure that the peer loses focus
|
||||
focusedPeer?.SetHasFocusFalse (this, true);
|
||||
|
||||
// We're the most focused view in the application, we need to set the focused view to this view.
|
||||
Application.Navigation?.SetFocused (this);
|
||||
if (!traversingUp)
|
||||
{
|
||||
// Restore focus to the previously most focused subview in the subview-hierarchy
|
||||
if (!RestoreFocus (TabStop))
|
||||
{
|
||||
// Couldn't restore focus, so use Advance to navigate to the next focusable subview
|
||||
if (!AdvanceFocus (NavigationDirection.Forward, null))
|
||||
{
|
||||
// Couldn't advance, so we're the most focused view in the application
|
||||
_previouslyMostFocused = null;
|
||||
Application.Navigation?.SetFocused (this);
|
||||
//NotifyFocusChanged (HasFocus, previousFocusedView, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotifyFocusChanged (HasFocus, previousFocusedView, this);
|
||||
|
||||
SetNeedsDisplay ();
|
||||
|
||||
// Post-conditions - prove correctness
|
||||
@@ -176,7 +166,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
throw new InvalidOperationException ($"NotifyFocusChanging was not cancelled and the HasFocus value did not change.");
|
||||
}
|
||||
|
||||
return true;
|
||||
return (true, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,8 +194,13 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
/// <summary>
|
||||
/// Invoked when <see cref="View.HasFocus"/> is about to change. This method is called before the <see cref="HasFocusChanging"/> event is raised.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Use <see cref="OnHasFocusChanged"/> to be notified after the focus has changed.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="currentHasFocus">The current value of <see cref="View.HasFocus"/>.</param>
|
||||
/// <param name="newHasFocus">The value <see cref="View.HasFocus"/> will have if the event is not cancelled.</param>
|
||||
/// <param name="newHasFocus">The value <see cref="View.HasFocus"/> will have if the focus change happens.</param>
|
||||
/// <param name="currentFocused">The view that is currently Focused. May be <see langword="null"/>.</param>
|
||||
/// <param name="newFocused">The view that will be focused. May be <see langword="null"/>.</param>
|
||||
/// <returns> <see langword="true"/>, if the change to <see cref="View.HasFocus"/> is to be cancelled, <see langword="false"/> otherwise.</returns>
|
||||
@@ -214,57 +209,70 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Raised when the view is gaining (entering) focus. Can be cancelled.</summary>
|
||||
/// <summary>
|
||||
/// Raised when <see cref="View.HasFocus"/> is about to change.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Cancel the event to prevent the focus from changing.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Use <see cref="HasFocusChanged"/> to be notified after the focus has changed.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public event EventHandler<HasFocusEventArgs> HasFocusChanging;
|
||||
|
||||
/// <summary>
|
||||
/// Called when focus has changed to another view.
|
||||
/// Called when this view should stop being focused.
|
||||
/// </summary>
|
||||
/// <param name="focusedVew">The view that now has focus. If <see langword="null"/> there is no view that has focus.</param>
|
||||
/// <param name="newFocusedVew">The new focused view. If <see langword="null"/> it is not known which view will be focused.</param>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
private void SetHasFocusFalse ([CanBeNull] View focusedVew, bool traversingDown = false)
|
||||
private void SetHasFocusFalse ([CanBeNull] View newFocusedVew, bool traversingDown = false)
|
||||
{
|
||||
// Pre-conditions
|
||||
if (!_hasFocus)
|
||||
{
|
||||
throw new InvalidOperationException ($"FocusChanged should not be called if the view does not have focus.");
|
||||
throw new InvalidOperationException ($"SetHasFocusFalse should not be called if the view does not have focus.");
|
||||
}
|
||||
|
||||
// If enteringView is null, we need to find the view that should get focus, and SetFocus on it.
|
||||
if (!traversingDown && focusedVew is null)
|
||||
// If newFocusedVew is null, we need to find the view that should get focus, and SetFocus on it.
|
||||
if (!traversingDown && newFocusedVew is null)
|
||||
{
|
||||
if (SuperView?._previouslyMostFocused is { } && SuperView?._previouslyMostFocused != this)
|
||||
{
|
||||
SuperView?._previouslyMostFocused?.SetFocus ();
|
||||
|
||||
// The above will cause FocusChanged, so we can return
|
||||
// The above will cause SetHasFocusFalse, so we can return
|
||||
return;
|
||||
}
|
||||
|
||||
if (SuperView is { } && SuperView.AdvanceFocus (NavigationDirection.Forward, TabStop))
|
||||
{
|
||||
// The above will cause FocusChanged, so we can return
|
||||
// The above will cause SetHasFocusFalse, so we can return
|
||||
return;
|
||||
}
|
||||
|
||||
//if (Application.Navigation is { })
|
||||
//{
|
||||
// // Temporarily ensure this view can't get focus
|
||||
// bool prevCanFocus = _canFocus;
|
||||
// _canFocus = false;
|
||||
// Application.Navigation.;
|
||||
// _canFocus = prevCanFocus;
|
||||
if (Application.Navigation is { })
|
||||
{
|
||||
// Temporarily ensure this view can't get focus
|
||||
bool prevCanFocus = _canFocus;
|
||||
_canFocus = false;
|
||||
bool restoredFocus = Application.Current!.RestoreFocus (null);
|
||||
_canFocus = prevCanFocus;
|
||||
|
||||
// // The above will cause LeaveFocus, so we can return
|
||||
// return;
|
||||
//}
|
||||
if (restoredFocus)
|
||||
{
|
||||
// The above caused SetHasFocusFalse, so we can return
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No other focusable view to be found. Just "leave" us...
|
||||
}
|
||||
|
||||
// Before we can leave focus, we need to make sure that all views down the subview-hierarchy have left focus.
|
||||
View mostFocused = MostFocused;
|
||||
if (mostFocused is { } && (focusedVew is null || mostFocused != focusedVew))
|
||||
if (mostFocused is { } && (newFocusedVew is null || mostFocused != newFocusedVew))
|
||||
{
|
||||
// Start at the bottom and work our way up to us
|
||||
View bottom = mostFocused;
|
||||
@@ -273,7 +281,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
{
|
||||
if (bottom.HasFocus)
|
||||
{
|
||||
bottom.SetHasFocusFalse (focusedVew, true);
|
||||
bottom.SetHasFocusFalse (newFocusedVew, true);
|
||||
}
|
||||
bottom = bottom.SuperView;
|
||||
}
|
||||
@@ -283,26 +291,17 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
bool previousValue = HasFocus;
|
||||
|
||||
// Note, can't be cancelled.
|
||||
NotifyFocusChanging (HasFocus, !HasFocus, focusedVew, this);
|
||||
NotifyFocusChanging (HasFocus, !HasFocus, newFocusedVew, this);
|
||||
|
||||
// Get whatever peer has focus, if any
|
||||
View focusedPeer = SuperView?.Focused;
|
||||
_hasFocus = false;
|
||||
|
||||
NotifyFocusChanged (HasFocus, this, focusedVew);
|
||||
|
||||
if (!traversingDown && CanFocus && Visible && Enabled)
|
||||
{
|
||||
// Now ensure all views up the superview-hierarchy are unfocused
|
||||
if (SuperView is { HasFocus: true } && focusedPeer == this)
|
||||
{
|
||||
SuperView.SetHasFocusFalse (focusedVew);
|
||||
}
|
||||
}
|
||||
NotifyFocusChanged (HasFocus, this, newFocusedVew);
|
||||
|
||||
if (SuperView is { })
|
||||
{
|
||||
SuperView._previouslyMostFocused = this;
|
||||
SuperView._previouslyMostFocused = focusedPeer;
|
||||
}
|
||||
|
||||
// Post-conditions - prove correctness
|
||||
@@ -428,7 +427,9 @@ public partial class View // Focus and cross-view navigation management (TabStop
|
||||
}
|
||||
|
||||
// The subview does not have focus, but at least one other that can. Can this one be focused?
|
||||
return view.SetHasFocusTrue (Focused);
|
||||
(bool focusSet, bool _) = view.SetHasFocusTrue (Focused);
|
||||
|
||||
return focusSet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
@@ -31,7 +32,7 @@ public class ComboBox : View, IDesignable
|
||||
CanFocus = true;
|
||||
_search = new TextField () { CanFocus = true, TabStop = TabBehavior.NoStop };
|
||||
|
||||
_listview = new ComboListView (this, HideDropdownListOnClick) { CanFocus = true, TabStop = TabBehavior.NoStop};
|
||||
_listview = new ComboListView (this, HideDropdownListOnClick) { CanFocus = true, TabStop = TabBehavior.NoStop };
|
||||
|
||||
_search.TextChanged += Search_Changed;
|
||||
_search.Accept += Search_Accept;
|
||||
@@ -299,19 +300,6 @@ public class ComboBox : View, IDesignable
|
||||
Driver.AddRune (Glyphs.DownArrow);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool OnHasFocusChanging (bool currentHasFocus, bool newHasFocus, [CanBeNull] View currentFocused, [CanBeNull] View newFocused)
|
||||
{
|
||||
bool cancel = false;
|
||||
if (!_search.HasFocus && !_listview.HasFocus)
|
||||
{
|
||||
cancel = _search.SetFocus ();
|
||||
}
|
||||
|
||||
_search.CursorPosition = _search.Text.GetRuneCount ();
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/// <summary>Virtual method which invokes the <see cref="Expanded"/> event.</summary>
|
||||
public virtual void OnExpanded () { Expanded?.Invoke (this, EventArgs.Empty); }
|
||||
@@ -319,25 +307,34 @@ public class ComboBox : View, IDesignable
|
||||
/// <inheritdoc/>
|
||||
protected override void OnHasFocusChanged (bool newHasFocus, View previousFocusedView, View view)
|
||||
{
|
||||
if (_source?.Count > 0
|
||||
&& _selectedItem > -1
|
||||
&& _selectedItem < _source.Count - 1
|
||||
&& _text != _source.ToList () [_selectedItem].ToString ())
|
||||
if (newHasFocus)
|
||||
{
|
||||
SetValue (_source.ToList () [_selectedItem].ToString ());
|
||||
if (!_search.HasFocus && !_listview.HasFocus)
|
||||
{
|
||||
_search.SetFocus ();
|
||||
}
|
||||
_search.CursorPosition = _search.Text.GetRuneCount ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_source?.Count > 0
|
||||
&& _selectedItem > -1
|
||||
&& _selectedItem < _source.Count - 1
|
||||
&& _text != _source.ToList () [_selectedItem].ToString ())
|
||||
{
|
||||
SetValue (_source.ToList () [_selectedItem].ToString ());
|
||||
}
|
||||
|
||||
if (_autoHide && IsShow && view != this && view != _search && view != _listview)
|
||||
{
|
||||
IsShow = false;
|
||||
HideList ();
|
||||
if (_autoHide && IsShow && view != this && view != _search && view != _listview)
|
||||
{
|
||||
IsShow = false;
|
||||
HideList ();
|
||||
}
|
||||
else if (_listview.TabStop?.HasFlag (TabBehavior.TabStop) ?? false)
|
||||
{
|
||||
_listview.TabStop = TabBehavior.NoStop;
|
||||
}
|
||||
}
|
||||
else if (_listview.TabStop?.HasFlag (TabBehavior.TabStop) ?? false)
|
||||
{
|
||||
_listview.TabStop = TabBehavior.NoStop;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>Invokes the OnOpenSelectedItem event if it is defined.</summary>
|
||||
@@ -565,7 +562,7 @@ public class ComboBox : View, IDesignable
|
||||
{
|
||||
if (HasItems ())
|
||||
{
|
||||
return _listview.MoveUp ();
|
||||
return _listview.MoveUp ();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -518,7 +518,10 @@ public class FileDialog : Dialog
|
||||
};
|
||||
AllowedTypeMenuClicked (0);
|
||||
|
||||
_allowedTypeMenuBar.HasFocusChanging += (s, e) => { _allowedTypeMenuBar.OpenMenu (0); };
|
||||
_allowedTypeMenuBar.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
_allowedTypeMenuBar.OpenMenu (0);
|
||||
};
|
||||
|
||||
_allowedTypeMenuBar.DrawContentComplete += (s, e) =>
|
||||
{
|
||||
|
||||
@@ -760,6 +760,10 @@ public class HexView : View
|
||||
|
||||
private void RedisplayLine (long pos)
|
||||
{
|
||||
if (bytesPerLine == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var delta = (int)(pos - DisplayStart);
|
||||
int line = delta / bytesPerLine;
|
||||
|
||||
|
||||
@@ -739,14 +739,12 @@ public class ListView : View, IDesignable
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool OnHasFocusChanging (bool currentHasFocus, bool newHasFocus, [CanBeNull] View currentFocused, [CanBeNull] View newFocused)
|
||||
protected override void OnHasFocusChanged (bool newHasFocus, [CanBeNull] View currentFocused, [CanBeNull] View newFocused)
|
||||
{
|
||||
if (_lastSelectedItem != _selected)
|
||||
if (newHasFocus && _lastSelectedItem != _selected)
|
||||
{
|
||||
EnsureSelectedItemVisible ();
|
||||
}
|
||||
|
||||
return false; // Don't cancel the focus switch
|
||||
}
|
||||
|
||||
// TODO: This should be cancelable
|
||||
|
||||
@@ -86,45 +86,10 @@ public class MenuBar : View, IDesignable
|
||||
Added += MenuBar_Added;
|
||||
|
||||
// Things this view knows how to do
|
||||
AddCommand (
|
||||
Command.Left,
|
||||
() =>
|
||||
{
|
||||
MoveLeft ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Right,
|
||||
() =>
|
||||
{
|
||||
MoveRight ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Cancel,
|
||||
() =>
|
||||
{
|
||||
CloseMenuBar ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Accept,
|
||||
() =>
|
||||
{
|
||||
ProcessMenu (_selected, Menus [_selected]);
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
AddCommand (Command.Left, () => MoveLeft ());
|
||||
AddCommand (Command.Right, () => MoveRight ());
|
||||
AddCommand (Command.Cancel, () => CloseMenuBar ());
|
||||
AddCommand (Command.Accept, () => _selected >= 0 && ProcessMenu (_selected, Menus [_selected]));
|
||||
AddCommand (Command.ToggleExpandCollapse, ctx => Select (Menus.IndexOf (ctx.KeyBinding?.Context)));
|
||||
AddCommand (Command.Select, ctx => Run ((ctx.KeyBinding?.Context as MenuItem)?.Action));
|
||||
|
||||
@@ -225,7 +190,6 @@ public class MenuBar : View, IDesignable
|
||||
if (value && UseKeysUpDownAsKeysLeftRight)
|
||||
{
|
||||
_useKeysUpDownAsKeysLeftRight = false;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,7 +339,7 @@ public class MenuBar : View, IDesignable
|
||||
}
|
||||
|
||||
/// <summary>Opens the Menu programatically, as though the F9 key were pressed.</summary>
|
||||
public void OpenMenu ()
|
||||
public bool OpenMenu ()
|
||||
{
|
||||
MenuBar mbar = GetMouseGrabViewInstance (this);
|
||||
|
||||
@@ -386,11 +350,10 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
if (!Enabled || _openMenu is { })
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
_selected = 0;
|
||||
SetNeedsDisplay ();
|
||||
|
||||
_previousFocused = null;//SuperView is null ? Application.Current?.Focused : SuperView.Focused;
|
||||
OpenMenu (_selected);
|
||||
@@ -402,15 +365,17 @@ public class MenuBar : View, IDesignable
|
||||
)
|
||||
&& !CloseMenu (false))
|
||||
{
|
||||
return;
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
if (!OpenCurrentMenu.CheckSubMenu ())
|
||||
{
|
||||
return;
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
Application.GrabMouse (this);
|
||||
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -446,7 +411,7 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
// Activates the menu, handles either first focus, or activating an entry when it was already active
|
||||
// For mouse events.
|
||||
internal void Activate (int idx, int sIdx = -1, MenuBarItem subMenu = null)
|
||||
internal bool Activate (int idx, int sIdx = -1, MenuBarItem subMenu = null)
|
||||
{
|
||||
_selected = idx;
|
||||
_selectedSub = sIdx;
|
||||
@@ -456,8 +421,7 @@ public class MenuBar : View, IDesignable
|
||||
_previousFocused = null;//SuperView is null ? Application.Current?.Focused ?? null : SuperView.Focused;
|
||||
}
|
||||
|
||||
OpenMenu (idx, sIdx, subMenu);
|
||||
SetNeedsDisplay ();
|
||||
return OpenMenu (idx, sIdx, subMenu);
|
||||
}
|
||||
|
||||
internal void CleanUp ()
|
||||
@@ -479,7 +443,6 @@ public class MenuBar : View, IDesignable
|
||||
_lastFocused.SetFocus ();
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
Application.UngrabMouse ();
|
||||
_isCleaning = false;
|
||||
}
|
||||
@@ -550,8 +513,6 @@ public class MenuBar : View, IDesignable
|
||||
Application.Current?.Remove (_openMenu);
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
|
||||
if (_previousFocused is Menu && _openMenu is { } && _previousFocused.ToString () != OpenCurrentMenu.ToString ())
|
||||
{
|
||||
_previousFocused.SetFocus ();
|
||||
@@ -603,7 +564,6 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
case true:
|
||||
_selectedSub = -1;
|
||||
SetNeedsDisplay ();
|
||||
RemoveAllOpensSubMenus ();
|
||||
OpenCurrentMenu?._previousSubFocused.SetFocus ();
|
||||
_openSubMenu = null;
|
||||
@@ -644,7 +604,7 @@ public class MenuBar : View, IDesignable
|
||||
);
|
||||
}
|
||||
|
||||
internal void NextMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false)
|
||||
internal bool NextMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false)
|
||||
{
|
||||
switch (isSubMenu)
|
||||
{
|
||||
@@ -664,7 +624,7 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
if (_selected > -1 && !CloseMenu (true, ignoreUseSubMenusSingleFrame))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenMenu (_selected);
|
||||
@@ -696,7 +656,7 @@ public class MenuBar : View, IDesignable
|
||||
{
|
||||
if (_openSubMenu is { } && !CloseMenu (false, true))
|
||||
{
|
||||
return;
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
NextMenu (false, ignoreUseSubMenusSingleFrame);
|
||||
@@ -714,14 +674,12 @@ public class MenuBar : View, IDesignable
|
||||
{
|
||||
if (CloseMenu (false, true, ignoreUseSubMenusSingleFrame))
|
||||
{
|
||||
NextMenu (false, ignoreUseSubMenusSingleFrame);
|
||||
return NextMenu (false, ignoreUseSubMenusSingleFrame);
|
||||
}
|
||||
|
||||
return;
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
|
||||
if (UseKeysUpDownAsKeysLeftRight)
|
||||
{
|
||||
OpenCurrentMenu.CheckSubMenu ();
|
||||
@@ -730,9 +688,11 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
internal void OpenMenu (int index, int sIndex = -1, MenuBarItem subMenu = null)
|
||||
internal bool OpenMenu (int index, int sIndex = -1, MenuBarItem subMenu = null)
|
||||
{
|
||||
_isMenuOpening = true;
|
||||
MenuOpeningEventArgs newMenu = OnMenuOpening (Menus [index]);
|
||||
@@ -741,7 +701,7 @@ public class MenuBar : View, IDesignable
|
||||
{
|
||||
_isMenuOpening = false;
|
||||
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newMenu.NewMenuBarItem is { })
|
||||
@@ -759,7 +719,7 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
if (_openSubMenu is { } && !CloseMenu (false, true))
|
||||
{
|
||||
return;
|
||||
return IsMenuOpen;
|
||||
}
|
||||
|
||||
if (_openMenu is { })
|
||||
@@ -895,9 +855,11 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
_isMenuOpening = false;
|
||||
IsMenuOpen = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void PreviousMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false)
|
||||
internal bool PreviousMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false)
|
||||
{
|
||||
switch (isSubMenu)
|
||||
{
|
||||
@@ -913,10 +875,10 @@ public class MenuBar : View, IDesignable
|
||||
|
||||
if (_selected > -1 && !CloseMenu (true, false, ignoreUseSubMenusSingleFrame))
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenMenu (_selected);
|
||||
bool opened = OpenMenu (_selected);
|
||||
|
||||
if (!SelectEnabledItem (
|
||||
OpenCurrentMenu.BarItems.Children,
|
||||
@@ -928,21 +890,23 @@ public class MenuBar : View, IDesignable
|
||||
OpenCurrentMenu._currentChild = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
return opened;
|
||||
|
||||
case true:
|
||||
if (_selectedSub > -1)
|
||||
{
|
||||
_selectedSub--;
|
||||
RemoveSubMenu (_selectedSub, ignoreUseSubMenusSingleFrame);
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
else
|
||||
{
|
||||
PreviousMenu ();
|
||||
return PreviousMenu ();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void RemoveAllOpensSubMenus ()
|
||||
@@ -1063,11 +1027,11 @@ public class MenuBar : View, IDesignable
|
||||
return Run (item?.Action);
|
||||
}
|
||||
|
||||
private void CloseMenuBar ()
|
||||
private bool CloseMenuBar ()
|
||||
{
|
||||
if (!CloseMenu (false))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_openedByAltKey)
|
||||
@@ -1076,7 +1040,7 @@ public class MenuBar : View, IDesignable
|
||||
LastFocused?.SetFocus ();
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
return true;
|
||||
}
|
||||
|
||||
private Point GetLocationOffset ()
|
||||
@@ -1095,7 +1059,7 @@ public class MenuBar : View, IDesignable
|
||||
Added -= MenuBar_Added;
|
||||
}
|
||||
|
||||
private void MoveLeft ()
|
||||
private bool MoveLeft ()
|
||||
{
|
||||
_selected--;
|
||||
|
||||
@@ -1104,22 +1068,30 @@ public class MenuBar : View, IDesignable
|
||||
_selected = Menus.Length - 1;
|
||||
}
|
||||
|
||||
OpenMenu (_selected);
|
||||
SetNeedsDisplay ();
|
||||
if (_selected < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OpenMenu (_selected);
|
||||
}
|
||||
|
||||
private void MoveRight ()
|
||||
private bool MoveRight ()
|
||||
{
|
||||
if (Menus.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_selected = (_selected + 1) % Menus.Length;
|
||||
OpenMenu (_selected);
|
||||
SetNeedsDisplay ();
|
||||
|
||||
return OpenMenu (_selected);
|
||||
}
|
||||
|
||||
private void ProcessMenu (int i, MenuBarItem mi)
|
||||
private bool ProcessMenu (int i, MenuBarItem mi)
|
||||
{
|
||||
if (_selected < 0 && IsMenuOpen)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mi.IsTopLevel)
|
||||
@@ -1133,7 +1105,7 @@ public class MenuBar : View, IDesignable
|
||||
{
|
||||
Application.GrabMouse (this);
|
||||
_selected = i;
|
||||
OpenMenu (i);
|
||||
bool opened = OpenMenu (i);
|
||||
|
||||
if (!SelectEnabledItem (
|
||||
OpenCurrentMenu.BarItems.Children,
|
||||
@@ -1142,16 +1114,17 @@ public class MenuBar : View, IDesignable
|
||||
)
|
||||
&& !CloseMenu (false))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!OpenCurrentMenu.CheckSubMenu ())
|
||||
{
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
return opened;
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RemoveSubMenu (int index, bool ignoreUseSubMenusSingleFrame = false)
|
||||
@@ -1256,7 +1229,6 @@ public class MenuBar : View, IDesignable
|
||||
if (value && UseSubMenusSingleFrame)
|
||||
{
|
||||
UseSubMenusSingleFrame = false;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,24 +137,24 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public void MovePreviousViewOrTop_ShouldMoveFocusToPreviousViewOrTop ()
|
||||
{
|
||||
// Arrange
|
||||
var top = new Toplevel ();
|
||||
var view1 = new View () { Id = "view1", CanFocus = true, TabStop = TabBehavior.TabGroup };
|
||||
var view2 = new View () { Id = "view2", CanFocus = true, TabStop = TabBehavior.TabGroup };
|
||||
top.Add (view1, view2);
|
||||
Application.Top = top;
|
||||
Application.Current = top;
|
||||
view2.SetFocus ();
|
||||
//[Fact]
|
||||
//public void MovePreviousViewOrTop_ShouldMoveFocusToPreviousViewOrTop ()
|
||||
//{
|
||||
// // Arrange
|
||||
// var top = new Toplevel ();
|
||||
// var view1 = new View () { Id = "view1", CanFocus = true, TabStop = TabBehavior.TabGroup };
|
||||
// var view2 = new View () { Id = "view2", CanFocus = true, TabStop = TabBehavior.TabGroup };
|
||||
// top.Add (view1, view2);
|
||||
// Application.Top = top;
|
||||
// Application.Current = top;
|
||||
// view2.SetFocus ();
|
||||
|
||||
// Act
|
||||
ApplicationNavigation.MovePreviousViewOrTop ();
|
||||
// // Act
|
||||
// ApplicationNavigation.MovePreviousViewOrTop ();
|
||||
|
||||
// Assert
|
||||
Assert.True (view1.HasFocus);
|
||||
// // Assert
|
||||
// Assert.True (view1.HasFocus);
|
||||
|
||||
top.Dispose ();
|
||||
}
|
||||
// top.Dispose ();
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -75,14 +75,11 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
|
||||
CanFocus = true
|
||||
};
|
||||
|
||||
int nLeave = 0;
|
||||
|
||||
View subView = new View ()
|
||||
{
|
||||
Id = "subView",
|
||||
CanFocus = true
|
||||
};
|
||||
subView.HasFocusChanged += (s, e) => nLeave++;
|
||||
|
||||
top.Add (subView);
|
||||
|
||||
@@ -95,7 +92,6 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
|
||||
Assert.True (top.HasFocus);
|
||||
Assert.Equal (null, top.Focused);
|
||||
Assert.False (subView.HasFocus);
|
||||
Assert.Equal (1, nLeave);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -107,14 +103,11 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
|
||||
CanFocus = true
|
||||
};
|
||||
|
||||
int nLeave1 = 0;
|
||||
|
||||
View subView1 = new View ()
|
||||
{
|
||||
Id = "subView1",
|
||||
CanFocus = true
|
||||
};
|
||||
subView1.HasFocusChanged += (s, e) => nLeave1++;
|
||||
|
||||
View subView2 = new View ()
|
||||
{
|
||||
@@ -134,7 +127,5 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
|
||||
Assert.True (subView2.HasFocus);
|
||||
Assert.Equal (subView2, top.Focused);
|
||||
Assert.False (subView1.HasFocus);
|
||||
Assert.Equal (1, nLeave1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Terminal.Gui.ViewTests;
|
||||
|
||||
public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllViews
|
||||
{
|
||||
#region HasFocusChanging_NewValue_True
|
||||
[Fact]
|
||||
public void HasFocusChanging_SetFocus_Raises ()
|
||||
{
|
||||
@@ -452,7 +453,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
|
||||
|
||||
[Fact]
|
||||
public void HasFocusChanging_SetFocus_On_Subview_SubView_Can_Cancel ()
|
||||
public void HasFocusChanging_SetFocus_On_Subview_If_SubView_Cancels ()
|
||||
{
|
||||
var hasFocusTrueCount = 0;
|
||||
var hasFocusFalseCount = 0;
|
||||
@@ -499,100 +500,318 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
|
||||
subview.SetFocus ();
|
||||
|
||||
Assert.False (view.HasFocus);
|
||||
Assert.False (subview.HasFocus);
|
||||
Assert.False (view.HasFocus); // Never had focus
|
||||
Assert.False (subview.HasFocus); // Cancelled
|
||||
|
||||
Assert.Equal (0, hasFocusTrueCount);
|
||||
Assert.Equal (0, hasFocusFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewHasFocusTrueCount);
|
||||
Assert.Equal (0, subviewHasFocusFalseCount);
|
||||
|
||||
// Now set focus on the view
|
||||
view.SetFocus ();
|
||||
|
||||
Assert.True (view.HasFocus);
|
||||
Assert.False (subview.HasFocus); // Cancelled
|
||||
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (0, hasFocusFalseCount);
|
||||
|
||||
Assert.Equal (2, subviewHasFocusTrueCount);
|
||||
Assert.Equal (0, subviewHasFocusFalseCount);
|
||||
}
|
||||
|
||||
#endregion HasFocusChanging_NewValue_True
|
||||
|
||||
#region HasFocusChanging_NewValue_False
|
||||
|
||||
[Fact]
|
||||
public void RemoveFocus_Raises_HasFocusChanged ()
|
||||
public void HasFocusChanging_RemoveFocus_Raises ()
|
||||
{
|
||||
var nEnter = 0;
|
||||
var nLeave = 0;
|
||||
var hasFocusTrueCount = 0;
|
||||
var hasFocusFalseCount = 0;
|
||||
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
view.HasFocusChanging += (s, e) => nEnter++;
|
||||
view.HasFocusChanged += (s, e) => nLeave++;
|
||||
view.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
hasFocusTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasFocusFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.True (view.CanFocus);
|
||||
Assert.False (view.HasFocus);
|
||||
|
||||
view.SetFocus ();
|
||||
Assert.True (view.HasFocus);
|
||||
Assert.Equal (1, nEnter);
|
||||
Assert.Equal (0, nLeave);
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (0, hasFocusFalseCount);
|
||||
|
||||
view.HasFocus = false;
|
||||
Assert.Equal (1, nEnter);
|
||||
Assert.Equal (1, nLeave);
|
||||
Assert.False (view.HasFocus);
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (1, hasFocusFalseCount);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void RemoveFocus_SubView_Raises_HasFocusChanged ()
|
||||
public void HasFocusChanging_RemoveFocus_SubView_SetFocus_Raises ()
|
||||
{
|
||||
var viewEnterCount = 0;
|
||||
var viewLeaveCount = 0;
|
||||
var hasFocusTrueCount = 0;
|
||||
var hasFocusFalseCount = 0;
|
||||
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
view.HasFocusChanging += (s, e) => viewEnterCount++;
|
||||
view.HasFocusChanged += (s, e) => viewLeaveCount++;
|
||||
view.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
hasFocusTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasFocusFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
var subviewEnterCount = 0;
|
||||
var subviewLeaveCount = 0;
|
||||
var subviewHasFocusTrueCount = 0;
|
||||
var subviewHasFocusFalseCount = 0;
|
||||
|
||||
var subview = new View
|
||||
{
|
||||
Id = "subview",
|
||||
CanFocus = true
|
||||
};
|
||||
subview.HasFocusChanging += (s, e) => subviewEnterCount++;
|
||||
subview.HasFocusChanged += (s, e) => subviewLeaveCount++;
|
||||
subview.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subviewHasFocusTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewHasFocusFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
view.Add (subview);
|
||||
|
||||
view.SetFocus ();
|
||||
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (0, hasFocusFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewHasFocusTrueCount);
|
||||
Assert.Equal (0, subviewHasFocusFalseCount);
|
||||
|
||||
view.HasFocus = false;
|
||||
Assert.False(view.HasFocus);
|
||||
Assert.False (subview.HasFocus);
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (1, hasFocusFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewHasFocusTrueCount);
|
||||
Assert.Equal (1, subviewHasFocusFalseCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public void HasFocusChanging_RemoveFocus_On_SubView_SubView_SetFocus_Raises ()
|
||||
{
|
||||
var hasFocusTrueCount = 0;
|
||||
var hasFocusFalseCount = 0;
|
||||
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
view.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
hasFocusTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasFocusFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
var subviewHasFocusTrueCount = 0;
|
||||
var subviewHasFocusFalseCount = 0;
|
||||
|
||||
var subview = new View
|
||||
{
|
||||
Id = "subview",
|
||||
CanFocus = true
|
||||
};
|
||||
subview.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subviewHasFocusTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewHasFocusFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
view.Add (subview);
|
||||
|
||||
subview.SetFocus ();
|
||||
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (0, hasFocusFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewHasFocusTrueCount);
|
||||
Assert.Equal (0, subviewHasFocusFalseCount);
|
||||
|
||||
subview.HasFocus = false;
|
||||
Assert.False (subview.HasFocus);
|
||||
Assert.Equal (1, hasFocusTrueCount);
|
||||
Assert.Equal (0, hasFocusFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewHasFocusTrueCount);
|
||||
Assert.Equal (1, subviewHasFocusFalseCount);
|
||||
|
||||
}
|
||||
#endregion HasFocusChanging_NewValue_False
|
||||
|
||||
#region HasFocusChanged
|
||||
|
||||
[Fact]
|
||||
public void HasFocusChanged_RemoveFocus_Raises ()
|
||||
{
|
||||
var newValueTrueCount = 0;
|
||||
var newValueFalseCount = 0;
|
||||
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
view.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
newValueTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValueFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
Assert.True (view.CanFocus);
|
||||
Assert.False (view.HasFocus);
|
||||
|
||||
view.SetFocus ();
|
||||
Assert.True (view.HasFocus);
|
||||
Assert.Equal (1, newValueTrueCount);
|
||||
Assert.Equal (0, newValueFalseCount);
|
||||
|
||||
view.HasFocus = false;
|
||||
Assert.Equal (1, newValueTrueCount);
|
||||
Assert.Equal (1, newValueFalseCount);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void HasFocusChanged_With_SubView_Raises ()
|
||||
{
|
||||
var newValueTrueCount = 0;
|
||||
var newValueFalseCount = 0;
|
||||
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
view.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
newValueTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValueFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
var subviewNewValueTrueCount = 0;
|
||||
var subviewNewValueFalseCount = 0;
|
||||
|
||||
var subview = new View
|
||||
{
|
||||
Id = "subview",
|
||||
CanFocus = true
|
||||
};
|
||||
subview.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subviewNewValueTrueCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewNewValueFalseCount++;
|
||||
}
|
||||
};
|
||||
|
||||
view.Add (subview);
|
||||
|
||||
view.SetFocus ();
|
||||
Assert.Equal (1, newValueTrueCount);
|
||||
Assert.Equal (0, newValueFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewNewValueTrueCount);
|
||||
Assert.Equal (0, subviewNewValueFalseCount);
|
||||
|
||||
view.HasFocus = false;
|
||||
|
||||
Assert.Equal (1, viewEnterCount);
|
||||
Assert.Equal (1, viewLeaveCount);
|
||||
Assert.Equal (1, newValueTrueCount);
|
||||
Assert.Equal (1, newValueFalseCount);
|
||||
|
||||
Assert.Equal (1, subviewEnterCount);
|
||||
Assert.Equal (1, subviewLeaveCount);
|
||||
Assert.Equal (1, subviewNewValueTrueCount);
|
||||
Assert.Equal (1, subviewNewValueFalseCount);
|
||||
|
||||
view.SetFocus ();
|
||||
|
||||
Assert.Equal (2, viewEnterCount);
|
||||
Assert.Equal (1, viewLeaveCount);
|
||||
Assert.Equal (2, newValueTrueCount);
|
||||
Assert.Equal (1, newValueFalseCount);
|
||||
|
||||
Assert.Equal (2, subviewEnterCount);
|
||||
Assert.Equal (1, subviewLeaveCount);
|
||||
Assert.Equal (2, subviewNewValueTrueCount);
|
||||
Assert.Equal (1, subviewNewValueFalseCount);
|
||||
|
||||
subview.HasFocus = false;
|
||||
|
||||
Assert.Equal (2, viewEnterCount);
|
||||
Assert.Equal (2, viewLeaveCount);
|
||||
Assert.Equal (2, newValueTrueCount);
|
||||
Assert.Equal (1, newValueFalseCount);
|
||||
|
||||
Assert.Equal (2, subviewEnterCount);
|
||||
Assert.Equal (2, subviewLeaveCount);
|
||||
Assert.Equal (2, subviewNewValueTrueCount);
|
||||
Assert.Equal (2, subviewNewValueFalseCount);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void RemoveFocus_CompoundSubView_Raises_HasFocusChanged ()
|
||||
public void HasFocusChanged_CompoundSubView_Raises ()
|
||||
{
|
||||
var viewEnterCount = 0;
|
||||
var viewLeaveCount = 0;
|
||||
@@ -602,8 +821,17 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
view.HasFocusChanging += (s, e) => viewEnterCount++;
|
||||
view.HasFocusChanged += (s, e) => viewLeaveCount++;
|
||||
view.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
viewEnterCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewLeaveCount++;
|
||||
}
|
||||
};
|
||||
|
||||
var subViewEnterCount = 0;
|
||||
var subViewLeaveCount = 0;
|
||||
@@ -613,8 +841,17 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
Id = "subView",
|
||||
CanFocus = true
|
||||
};
|
||||
subView.HasFocusChanging += (s, e) => subViewEnterCount++;
|
||||
subView.HasFocusChanged += (s, e) => subViewLeaveCount++;
|
||||
subView.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subViewEnterCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subViewLeaveCount++;
|
||||
}
|
||||
};
|
||||
|
||||
var subviewSubView1EnterCount = 0;
|
||||
var subviewSubView1LeaveCount = 0;
|
||||
@@ -624,8 +861,17 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
Id = "subViewSubView1",
|
||||
CanFocus = false
|
||||
};
|
||||
subViewSubView1.HasFocusChanging += (s, e) => subviewSubView1EnterCount++;
|
||||
subViewSubView1.HasFocusChanged += (s, e) => subviewSubView1LeaveCount++;
|
||||
subViewSubView1.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subviewSubView1EnterCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewSubView1LeaveCount++;
|
||||
}
|
||||
};
|
||||
|
||||
var subviewSubView2EnterCount = 0;
|
||||
var subviewSubView2LeaveCount = 0;
|
||||
@@ -635,9 +881,17 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
Id = "subViewSubView2",
|
||||
CanFocus = true
|
||||
};
|
||||
subViewSubView2.HasFocusChanging += (s, e) => subviewSubView2EnterCount++;
|
||||
subViewSubView2.HasFocusChanged += (s, e) => subviewSubView2LeaveCount++;
|
||||
|
||||
subViewSubView2.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subviewSubView2EnterCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewSubView2LeaveCount++;
|
||||
}
|
||||
};
|
||||
var subviewSubView3EnterCount = 0;
|
||||
var subviewSubView3LeaveCount = 0;
|
||||
|
||||
@@ -646,8 +900,17 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
Id = "subViewSubView3",
|
||||
CanFocus = false
|
||||
};
|
||||
subViewSubView3.HasFocusChanging += (s, e) => subviewSubView3EnterCount++;
|
||||
subViewSubView3.HasFocusChanged += (s, e) => subviewSubView3LeaveCount++;
|
||||
subViewSubView3.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
if (e.NewValue)
|
||||
{
|
||||
subviewSubView3EnterCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewSubView3LeaveCount++;
|
||||
}
|
||||
};
|
||||
|
||||
subView.Add (subViewSubView1, subViewSubView2, subViewSubView3);
|
||||
|
||||
@@ -682,59 +945,5 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
|
||||
Assert.Equal (0, subviewSubView3EnterCount);
|
||||
Assert.Equal (0, subviewSubView3LeaveCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasFocus_False_Leave_Raised ()
|
||||
{
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
Assert.True (view.CanFocus);
|
||||
Assert.False (view.HasFocus);
|
||||
|
||||
var leaveInvoked = 0;
|
||||
|
||||
view.HasFocusChanged += (s, e) => leaveInvoked++;
|
||||
|
||||
view.SetFocus ();
|
||||
Assert.True (view.HasFocus);
|
||||
Assert.Equal (0, leaveInvoked);
|
||||
|
||||
view.HasFocus = false;
|
||||
Assert.False (view.HasFocus);
|
||||
Assert.Equal (1, leaveInvoked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasFocus_False_Leave_Raised_ForAllSubViews ()
|
||||
{
|
||||
var view = new View
|
||||
{
|
||||
Id = "view",
|
||||
CanFocus = true
|
||||
};
|
||||
|
||||
var subview = new View
|
||||
{
|
||||
Id = "subview",
|
||||
CanFocus = true
|
||||
};
|
||||
view.Add (subview);
|
||||
|
||||
var leaveInvoked = 0;
|
||||
|
||||
view.HasFocusChanged += (s, e) => leaveInvoked++;
|
||||
subview.HasFocusChanged += (s, e) => leaveInvoked++;
|
||||
|
||||
view.SetFocus ();
|
||||
Assert.True (view.HasFocus);
|
||||
Assert.Equal (0, leaveInvoked);
|
||||
|
||||
view.HasFocus = false;
|
||||
Assert.False (view.HasFocus);
|
||||
Assert.False (subview.HasFocus);
|
||||
Assert.Equal (2, leaveInvoked);
|
||||
}
|
||||
#endregion HasFocusChanged
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ public class HasFocusTests (ITestOutputHelper _output) : TestsAllViews
|
||||
{
|
||||
|
||||
[Fact]
|
||||
public void HasFocus_False_Leaves ()
|
||||
public void HasFocus_False ()
|
||||
{
|
||||
var view = new View ()
|
||||
{
|
||||
@@ -22,7 +22,7 @@ public class HasFocusTests (ITestOutputHelper _output) : TestsAllViews
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasFocus_False_WithSuperView_Leaves_All ()
|
||||
public void HasFocus_False_WithSuperView_Does_Not_Change_SuperView ()
|
||||
{
|
||||
var view = new View ()
|
||||
{
|
||||
@@ -42,8 +42,8 @@ public class HasFocusTests (ITestOutputHelper _output) : TestsAllViews
|
||||
Assert.True (subview.HasFocus);
|
||||
|
||||
subview.HasFocus = false;
|
||||
Assert.False (view.HasFocus);
|
||||
Assert.False (subview.HasFocus);
|
||||
Assert.True (view.HasFocus);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -8,7 +8,8 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
{
|
||||
[Theory]
|
||||
[MemberData (nameof (AllViewTypes))]
|
||||
public void AllViews_AtLeastOneNavKey_Leaves (Type viewType)
|
||||
[SetupFakeDriver] // SetupFakeDriver resets app state; helps to avoid test pollution
|
||||
public void AllViews_AtLeastOneNavKey_Advances (Type viewType)
|
||||
{
|
||||
View view = CreateInstanceIfNotGeneric (viewType);
|
||||
|
||||
@@ -26,9 +27,10 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
return;
|
||||
}
|
||||
|
||||
Application.Init (new FakeDriver ());
|
||||
|
||||
Toplevel top = new ();
|
||||
Application.Current = top;
|
||||
Application.Navigation = new ApplicationNavigation ();
|
||||
|
||||
View otherView = new ()
|
||||
{
|
||||
@@ -38,12 +40,11 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
};
|
||||
|
||||
top.Add (view, otherView);
|
||||
Application.Begin (top);
|
||||
|
||||
// Start with the focus on our test view
|
||||
view.SetFocus ();
|
||||
|
||||
Key [] navKeys = { Key.Tab, Key.Tab.WithShift, Key.CursorUp, Key.CursorDown, Key.CursorLeft, Key.CursorRight };
|
||||
Key [] navKeys = [Key.Tab, Key.Tab.WithShift, Key.CursorUp, Key.CursorDown, Key.CursorLeft, Key.CursorRight];
|
||||
|
||||
if (view.TabStop == TabBehavior.TabGroup)
|
||||
{
|
||||
@@ -81,14 +82,14 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
}
|
||||
|
||||
top.Dispose ();
|
||||
Application.Shutdown ();
|
||||
Application.ResetState ();
|
||||
|
||||
Assert.True (left);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData (nameof (AllViewTypes))]
|
||||
[SetupFakeDriver]
|
||||
[SetupFakeDriver] // SetupFakeDriver resets app state; helps to avoid test pollution
|
||||
public void AllViews_HasFocus_Changed_Event (Type viewType)
|
||||
{
|
||||
View view = CreateInstanceIfNotGeneric (viewType);
|
||||
@@ -114,29 +115,17 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
return;
|
||||
}
|
||||
|
||||
Toplevel top = new ()
|
||||
{
|
||||
Height = 10,
|
||||
Width = 10
|
||||
};
|
||||
Toplevel top = new ();
|
||||
Application.Current = top;
|
||||
Application.Navigation = new ApplicationNavigation();
|
||||
Application.Navigation = new ApplicationNavigation ();
|
||||
|
||||
View otherView = new ()
|
||||
{
|
||||
Id = "otherView",
|
||||
X = 0, Y = 0,
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
CanFocus = true,
|
||||
TabStop = view.TabStop == TabBehavior.NoStop ? TabBehavior.TabStop : view.TabStop
|
||||
};
|
||||
|
||||
view.X = Pos.Right (otherView);
|
||||
view.Y = 0;
|
||||
view.Width = 10;
|
||||
view.Height = 1;
|
||||
|
||||
var hasFocusTrue = 0;
|
||||
var hasFocusFalse = 0;
|
||||
|
||||
@@ -256,7 +245,8 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
|
||||
[Theory]
|
||||
[MemberData (nameof (AllViewTypes))]
|
||||
public void AllViews_Enter_Leave_Events_Visible_False (Type viewType)
|
||||
[SetupFakeDriver] // SetupFakeDriver resets app state; helps to avoid test pollution
|
||||
public void AllViews_Visible_False_No_HasFocus_Events (Type viewType)
|
||||
{
|
||||
View view = CreateInstanceIfNotGeneric (viewType);
|
||||
|
||||
@@ -281,70 +271,46 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
return;
|
||||
}
|
||||
|
||||
Application.Init (new FakeDriver ());
|
||||
Toplevel top = new ();
|
||||
|
||||
Toplevel top = new ()
|
||||
{
|
||||
Height = 10,
|
||||
Width = 10
|
||||
};
|
||||
Application.Current = top;
|
||||
Application.Navigation = new ApplicationNavigation ();
|
||||
|
||||
View otherView = new ()
|
||||
{
|
||||
X = 0, Y = 0,
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
CanFocus = true
|
||||
};
|
||||
|
||||
view.Visible = false;
|
||||
view.X = Pos.Right (otherView);
|
||||
view.Y = 0;
|
||||
view.Width = 10;
|
||||
view.Height = 1;
|
||||
|
||||
var nEnter = 0;
|
||||
var nLeave = 0;
|
||||
var hasFocusChangingCount = 0;
|
||||
var hasFocusChangedCount = 0;
|
||||
|
||||
view.HasFocusChanging += (s, e) => nEnter++;
|
||||
view.HasFocusChanged += (s, e) => nLeave++;
|
||||
view.HasFocusChanging += (s, e) => hasFocusChangingCount++;
|
||||
view.HasFocusChanged += (s, e) => hasFocusChangedCount++;
|
||||
|
||||
top.Add (view, otherView);
|
||||
Application.Begin (top);
|
||||
|
||||
// Start with the focus on our test view
|
||||
view.SetFocus ();
|
||||
|
||||
Assert.Equal (0, nEnter);
|
||||
Assert.Equal (0, nLeave);
|
||||
Assert.Equal (0, hasFocusChangingCount);
|
||||
Assert.Equal (0, hasFocusChangedCount);
|
||||
|
||||
// Use keyboard to navigate to next view (otherView).
|
||||
if (view is TextView)
|
||||
{
|
||||
Application.OnKeyDown (Key.F6);
|
||||
}
|
||||
else if (view is DatePicker)
|
||||
{
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
Application.OnKeyDown (Key.F6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.OnKeyDown (Key.Tab);
|
||||
}
|
||||
Application.OnKeyDown (Key.Tab);
|
||||
|
||||
Assert.Equal (0, nEnter);
|
||||
Assert.Equal (0, nLeave);
|
||||
Assert.Equal (0, hasFocusChangingCount);
|
||||
Assert.Equal (0, hasFocusChangedCount);
|
||||
|
||||
top.NewKeyDownEvent (Key.Tab);
|
||||
Application.OnKeyDown (Key.F6);
|
||||
|
||||
Assert.Equal (0, nEnter);
|
||||
Assert.Equal (0, nLeave);
|
||||
Assert.Equal (0, hasFocusChangingCount);
|
||||
Assert.Equal (0, hasFocusChangedCount);
|
||||
|
||||
top.Dispose ();
|
||||
Application.Shutdown ();
|
||||
|
||||
Application.ResetState ();
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -444,67 +410,6 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
|
||||
Application.Current.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void FocusNext_Does_Not_Throws_If_A_View_Was_Removed_From_The_Collection ()
|
||||
{
|
||||
Toplevel top1 = new ();
|
||||
var view1 = new View { Id = "view1", Width = 10, Height = 5, CanFocus = true };
|
||||
var top2 = new Toplevel { Id = "top2", Y = 1, Width = 10, Height = 5 };
|
||||
|
||||
var view2 = new View
|
||||
{
|
||||
Id = "view2",
|
||||
Y = 1,
|
||||
Width = 10,
|
||||
Height = 5,
|
||||
CanFocus = true
|
||||
};
|
||||
View view3 = null;
|
||||
var removed = false;
|
||||
|
||||
view2.HasFocusChanging += (s, e) =>
|
||||
{
|
||||
if (!removed)
|
||||
{
|
||||
removed = true;
|
||||
view3 = new () { Id = "view3", Y = 1, Width = 10, Height = 5 };
|
||||
Application.Current.Add (view3);
|
||||
Application.Current.BringSubviewToFront (view3);
|
||||
Assert.False (view3.HasFocus);
|
||||
}
|
||||
};
|
||||
|
||||
view2.HasFocusChanged += (s, e) =>
|
||||
{
|
||||
Application.Current.Remove (view3);
|
||||
view3.Dispose ();
|
||||
view3 = null;
|
||||
};
|
||||
top2.Add (view2);
|
||||
top1.Add (view1, top2);
|
||||
Application.Begin (top1);
|
||||
|
||||
Assert.True (top1.HasFocus);
|
||||
Assert.True (view1.HasFocus);
|
||||
Assert.False (view2.HasFocus);
|
||||
Assert.False (removed);
|
||||
Assert.Null (view3);
|
||||
|
||||
Assert.True (Application.OnKeyDown (Key.F6));
|
||||
Assert.True (top1.HasFocus);
|
||||
Assert.False (view1.HasFocus);
|
||||
Assert.True (view2.HasFocus);
|
||||
Assert.True (removed);
|
||||
Assert.NotNull (view3);
|
||||
|
||||
Exception exception = Record.Exception (() => Application.OnKeyDown (Key.F6));
|
||||
Assert.Null (exception);
|
||||
Assert.True (removed);
|
||||
//Assert.Null (view3);
|
||||
top1.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMostFocused_NoSubviews_Returns_Null ()
|
||||
{
|
||||
|
||||
@@ -224,7 +224,7 @@ public class SetFocusTests (ITestOutputHelper _output) : TestsAllViews
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetFocus_Peer_LeavesOthers_Subviews ()
|
||||
public void SetFocus_On_Peer_Moves_Focus_To_Peer ()
|
||||
{
|
||||
var top = new View
|
||||
{
|
||||
|
||||
@@ -2560,7 +2560,7 @@ Edit
|
||||
top.Draw ();
|
||||
TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output);
|
||||
|
||||
Assert.True (menu.NewKeyDownEvent (menu.Key));
|
||||
Assert.True (Application.OnKeyDown(menu.Key));
|
||||
Assert.False (menu.IsMenuOpen);
|
||||
Assert.True (tf.HasFocus);
|
||||
top.Draw ();
|
||||
|
||||
@@ -611,7 +611,7 @@ public class ShortcutTests
|
||||
|
||||
shortcut.HasFocus = true;
|
||||
|
||||
Assert.Null (shortcut.ColorScheme);
|
||||
Assert.NotNull (shortcut.ColorScheme);
|
||||
|
||||
Application.Current.Dispose ();
|
||||
Application.ResetState ();
|
||||
|
||||
Reference in New Issue
Block a user