Removed TabIndex etc...

This commit is contained in:
Tig
2024-08-26 13:00:59 -07:00
parent 03f7b687d6
commit 1b1a2524e7
16 changed files with 664 additions and 672 deletions

View File

@@ -505,7 +505,7 @@ public partial class View // Drawing APIs
if (TabStop == TabBehavior.TabGroup && _subviews.Count(v => v.Arrangement.HasFlag (ViewArrangement.Overlapped)) > 0)
{
// TODO: This is a temporary hack to make overlapped non-Toplevels have a zorder. See also View.SetFocus
subviewsNeedingDraw = _tabIndexes.Where (
subviewsNeedingDraw = _subviews.Where (
view => view.Visible
&& (view.NeedsDisplay || view.SubViewNeedsDisplay || view.LayoutNeeded)
).Reverse ();

View File

@@ -52,21 +52,10 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
_subviews = new ();
}
if (_tabIndexes is null)
{
_tabIndexes = new ();
}
Debug.WriteLineIf (_subviews.Contains (view), $"BUGBUG: {view} has already been added to {this}.");
_subviews.Add (view);
_tabIndexes.Add (view);
view._superView = this;
if (view.CanFocus)
{
view._tabIndex = _tabIndexes.IndexOf (view);
}
if (view.Enabled && view.Visible && view.CanFocus)
{
// Add will cause the newly added subview to gain focus if it's focusable
@@ -179,16 +168,14 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
}
Rectangle touched = view.Frame;
_subviews.Remove (view);
_tabIndexes!.Remove (view);
view._superView = null;
//view._tabIndex = -1;
// If a view being removed is focused, it should lose focus.
if (view.HasFocus)
{
view.HasFocus = false;
}
_subviews.Remove (view);
view._superView = null; // Null this AFTER removing focus
SetNeedsLayout ();
SetNeedsDisplay ();

View File

@@ -8,7 +8,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
private bool _canFocus;
/// <summary>
/// Advances the focus to the next or previous view in <see cref="View.TabIndexes"/>, based on
/// Advances the focus to the next or previous view in the focus chain, based on
/// <paramref name="direction"/>.
/// itself.
/// </summary>
@@ -30,11 +30,6 @@ public partial class View // Focus and cross-view navigation management (TabStop
return false;
}
if (TabIndexes is null || TabIndexes.Count == 0)
{
return false;
}
View? focused = Focused;
if (focused is { } && focused.AdvanceFocus (direction, behavior))
@@ -42,14 +37,14 @@ public partial class View // Focus and cross-view navigation management (TabStop
return true;
}
View [] index = GetScopedTabIndexes (direction, behavior);
View [] index = GetSubviewFocusChain (direction, behavior);
if (index.Length == 0)
{
return false;
}
int focusedIndex = index.IndexOf (Focused);
int focusedIndex = index.IndexOf (Focused); // Will return -1 if Focused can't be found or is null
var next = 0;
if (focusedIndex < index.Length - 1)
@@ -69,7 +64,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
//}
// - If we are TabStop and our SuperView has at least one other TabStop subview, move to the SuperView's chain
if (TabStop == TabBehavior.TabStop && SuperView is { } && SuperView.GetScopedTabIndexes (direction, behavior).Length > 1)
if (TabStop == TabBehavior.TabStop && SuperView is { } && SuperView.GetSubviewFocusChain (direction, behavior).Length > 1)
{
return false;
}
@@ -81,7 +76,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
{
// Wrap to first focusable views
// BUGBUG: This should do a Restore Focus instead
index = GetScopedTabIndexes (direction, null);
index = GetSubviewFocusChain (direction, null);
}
}
}
@@ -110,10 +105,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
/// the next focusable view.
/// </para>
/// <para>
/// When set to <see langword="false"/>, the <see cref="TabIndex"/> will be set to -1.
/// </para>
/// <para>
/// When set to <see langword="false"/>, the values of <see cref="CanFocus"/> and <see cref="TabIndex"/> for all
/// When set to <see langword="false"/>, the value of <see cref="CanFocus"/> for all
/// subviews will be cached so that when <see cref="CanFocus"/> is set back to <see langword="true"/>, the subviews
/// will be restored to their previous values.
/// </para>
@@ -163,8 +155,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
public event EventHandler CanFocusChanged;
/// <summary>
/// Focuses the deepest 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.
/// Focuses the deepest focusable Subview if one exists. If there are no focusable Subviews then the focus is set to the view itself.
/// </summary>
/// <param name="direction"></param>
/// <param name="behavior"></param>
@@ -244,15 +235,10 @@ public partial class View // Focus and cross-view navigation management (TabStop
private View? FindDeepestFocusableView (NavigationDirection direction, TabBehavior? behavior)
{
View [] indicies = GetScopedTabIndexes (direction, behavior);
View [] indicies = GetSubviewFocusChain (direction, behavior);
foreach (View v in indicies)
{
if (v.TabIndexes.Count == 0)
{
return v;
}
return v.FindDeepestFocusableView (direction, behavior);
}
@@ -580,6 +566,16 @@ public partial class View // Focus and cross-view navigation management (TabStop
View? focusedPeer = SuperView?.Focused;
_hasFocus = false;
if (Application.Navigation is { })
{
View? appFocused = Application.Navigation.GetFocused ();
if (appFocused is { } || appFocused == this)
{
Application.Navigation.SetFocused (SuperView);
}
}
NotifyFocusChanged (HasFocus, this, newFocusedVew);
if (_hasFocus)
@@ -643,14 +639,6 @@ public partial class View // Focus and cross-view navigation management (TabStop
#region Tab/Focus Handling
private List<View>? _tabIndexes;
// TODO: This should be a get-only property?
// BUGBUG: This returns an AsReadOnly list, but isn't declared as such.
/// <summary>Gets a list of the subviews that are a <see cref="TabStop"/>.</summary>
/// <value>The tabIndexes.</value>
public IList<View> TabIndexes => _tabIndexes?.AsReadOnly () ?? _empty;
/// <summary>
/// Gets TabIndexes that are scoped to the specified behavior and direction. If behavior is null, all TabIndexes are
/// returned.
@@ -659,138 +647,25 @@ public partial class View // Focus and cross-view navigation management (TabStop
/// <param name="behavior"></param>
/// <returns></returns>
/// GetScopedTabIndexes
private View [] GetScopedTabIndexes (NavigationDirection direction, TabBehavior? behavior)
private View [] GetSubviewFocusChain (NavigationDirection direction, TabBehavior? behavior)
{
IEnumerable<View>? indicies;
IEnumerable<View>? fitleredSubviews;
if (behavior.HasValue)
{
indicies = _tabIndexes?.Where (v => v.TabStop == behavior && v is { CanFocus: true, Visible: true, Enabled: true });
fitleredSubviews = _subviews?.Where (v => v.TabStop == behavior && v is { CanFocus: true, Visible: true, Enabled: true });
}
else
{
indicies = _tabIndexes?.Where (v => v is { CanFocus: true, Visible: true, Enabled: true });
fitleredSubviews = _subviews?.Where (v => v is { CanFocus: true, Visible: true, Enabled: true });
}
if (direction == NavigationDirection.Backward)
{
indicies = indicies?.Reverse ();
fitleredSubviews = fitleredSubviews?.Reverse ();
}
return indicies?.ToArray () ?? Array.Empty<View> ();
}
private int? _tabIndex; // null indicates the view has not yet been added to TabIndexes
/// <summary>
/// Indicates the order of the current <see cref="View"/> in <see cref="TabIndexes"/> list.
/// </summary>
/// <remarks>
/// <para>
/// If <see langword="null"/>, the view is not part of the tab order.
/// </para>
/// <para>
/// On set, if <see cref="SuperView"/> is <see langword="null"/> or has not TabStops, <see cref="TabIndex"/> will
/// be set to 0.
/// </para>
/// <para>
/// On set, if <see cref="SuperView"/> has only one TabStop, <see cref="TabIndex"/> will be set to 0.
/// </para>
/// <para>
/// See also <seealso cref="TabStop"/>.
/// </para>
/// </remarks>
public int? TabIndex
{
get => _tabIndex;
// TOOD: This should be a get-only property. Introduce SetTabIndex (int value) (or similar).
set
{
// Once a view is in the tab order, it should not be removed from the tab order; set TabStop to NoStop instead.
Debug.Assert (value >= 0);
Debug.Assert (value is { });
if (SuperView?._tabIndexes is null || SuperView?._tabIndexes.Count == 1)
{
// BUGBUG: Property setters should set the property to the value passed in and not have side effects.
_tabIndex = 0;
return;
}
if (_tabIndex == value && TabIndexes.IndexOf (this) == value)
{
return;
}
_tabIndex = value > SuperView!.TabIndexes.Count - 1 ? SuperView._tabIndexes.Count - 1 :
value < 0 ? 0 : value;
_tabIndex = GetGreatestTabIndexInSuperView ((int)_tabIndex);
if (SuperView._tabIndexes.IndexOf (this) != _tabIndex)
{
// BUGBUG: we have to use _tabIndexes and not TabIndexes because TabIndexes returns is a read-only version of _tabIndexes
SuperView._tabIndexes.Remove (this);
SuperView._tabIndexes.Insert ((int)_tabIndex, this);
UpdatePeerTabIndexes ();
}
return;
// Updates the <see cref="TabIndex"/>s of the views in the <see cref="SuperView"/>'s to match their order in <see cref="TabIndexes"/>.
void UpdatePeerTabIndexes ()
{
if (SuperView is null)
{
return;
}
var i = 0;
foreach (View superViewTabStop in SuperView._tabIndexes)
{
if (superViewTabStop._tabIndex is null)
{
continue;
}
superViewTabStop._tabIndex = i;
i++;
}
}
}
}
/// <summary>
/// Gets the greatest <see cref="TabIndex"/> of the <see cref="SuperView"/>'s <see cref="TabIndexes"/> that is less
/// than or equal to <paramref name="idx"/>.
/// </summary>
/// <param name="idx"></param>
/// <returns>The minimum of <paramref name="idx"/> and the <see cref="SuperView"/>'s <see cref="TabIndexes"/>.</returns>
private int GetGreatestTabIndexInSuperView (int idx)
{
if (SuperView is null)
{
return 0;
}
var i = 0;
if (SuperView._tabIndexes is { })
{
foreach (View superViewTabStop in SuperView._tabIndexes)
{
if (superViewTabStop._tabIndex is null || superViewTabStop == this)
{
continue;
}
i++;
}
}
return Math.Min (i, idx);
return fitleredSubviews?.ToArray () ?? Array.Empty<View> ();
}
private TabBehavior? _tabStop;
@@ -828,17 +703,6 @@ public partial class View // Focus and cross-view navigation management (TabStop
return;
}
Debug.Assert (value is { });
if (_tabStop is null && TabIndex is null)
{
// This view has not yet been added to TabIndexes (TabStop has not been set previously).
if (SuperView?._tabIndexes is { })
{
TabIndex = GetGreatestTabIndexInSuperView (SuperView is { } ? SuperView._tabIndexes.Count : 0);
}
}
_tabStop = value;
}
}

View File

@@ -463,12 +463,12 @@ public class FileDialog : Dialog
_btnCancel.X = Pos.Func (CalculateOkButtonPosX);
_btnOk.X = Pos.Right (_btnCancel) + 1;
// Flip tab order too for consistency
int? p1 = _btnOk.TabIndex;
int? p2 = _btnCancel.TabIndex;
//// Flip tab order too for consistency
//int? p1 = _btnOk.TabIndex;
//int? p2 = _btnCancel.TabIndex;
_btnOk.TabIndex = p2;
_btnCancel.TabIndex = p1;
//_btnOk.TabIndex = p2;
//_btnCancel.TabIndex = p1;
}
_tbPath.Caption = Style.PathCaption;

View File

@@ -311,10 +311,10 @@ public class Dialogs : Scenario
buttons.Add (button);
dialog.AddButton (button);
if (buttons.Count > 1)
{
button.TabIndex = buttons [buttons.Count - 2].TabIndex + 1;
}
//if (buttons.Count > 1)
//{
// button.TabIndex = buttons [buttons.Count - 2].TabIndex + 1;
//}
};
dialog.Add (add);

View File

@@ -640,10 +640,10 @@ public class DynamicMenuBar : Scenario
};
frmMenu.Add (_lstMenus);
lblMenuBar.TabIndex = btnPrevious.TabIndex + 1;
_lstMenus.TabIndex = lblMenuBar.TabIndex + 1;
btnNext.TabIndex = _lstMenus.TabIndex + 1;
btnAdd.TabIndex = btnNext.TabIndex + 1;
//lblMenuBar.TabIndex = btnPrevious.TabIndex + 1;
//_lstMenus.TabIndex = lblMenuBar.TabIndex + 1;
//btnNext.TabIndex = _lstMenus.TabIndex + 1;
//btnAdd.TabIndex = btnNext.TabIndex + 1;
var btnRemove = new Button { X = Pos.Left (btnAdd), Y = Pos.Top (btnAdd) + 1, Text = "Remove" };
frmMenu.Add (btnRemove);

View File

@@ -13,16 +13,16 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
{
bool raised = false;
Application.Navigation = new ApplicationNavigation();
Application.Navigation = new ApplicationNavigation ();
Application.Navigation.FocusedChanged += ApplicationNavigationOnFocusedChanged;
Application.Navigation.SetFocused(new View ());
Application.Navigation.SetFocused (new View ());
Assert.True (raised);
Application.Navigation.GetFocused().Dispose ();
Application.Navigation.SetFocused(null);
Application.Navigation.GetFocused ().Dispose ();
Application.Navigation.SetFocused (null);
Application.Navigation.FocusedChanged -= ApplicationNavigationOnFocusedChanged;
@@ -30,10 +30,7 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
return;
void ApplicationNavigationOnFocusedChanged (object sender, EventArgs e)
{
raised = true;
}
void ApplicationNavigationOnFocusedChanged (object sender, EventArgs e) { raised = true; }
}
[Fact]
@@ -50,7 +47,8 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
public void GetDeepestFocusedSubview_ShouldReturnSameView_WhenNoSubviewsHaveFocus ()
{
// Arrange
var view = new View () { Id = "view", CanFocus = true }; ;
var view = new View () { Id = "view", CanFocus = true };
;
// Act
var result = ApplicationNavigation.GetDeepestFocusedSubview (view);
@@ -63,10 +61,14 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
public void GetDeepestFocusedSubview_ShouldReturnFocusedSubview ()
{
// Arrange
var parentView = new View () { Id = "parentView", CanFocus = true }; ;
var childView1 = new View () { Id = "childView1", CanFocus = true }; ;
var childView2 = new View () { Id = "childView2", CanFocus = true }; ;
var grandChildView = new View () { Id = "grandChildView", CanFocus = true }; ;
var parentView = new View () { Id = "parentView", CanFocus = true };
;
var childView1 = new View () { Id = "childView1", CanFocus = true };
;
var childView2 = new View () { Id = "childView2", CanFocus = true };
;
var grandChildView = new View () { Id = "grandChildView", CanFocus = true };
;
parentView.Add (childView1, childView2);
childView2.Add (grandChildView);
@@ -84,11 +86,16 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
public void GetDeepestFocusedSubview_ShouldReturnDeepestFocusedSubview ()
{
// Arrange
var parentView = new View () { Id = "parentView", CanFocus = true }; ;
var childView1 = new View () { Id = "childView1", CanFocus = true }; ;
var childView2 = new View () { Id = "childView2", CanFocus = true }; ;
var grandChildView = new View () { Id = "grandChildView", CanFocus = true }; ;
var greatGrandChildView = new View () { Id = "greatGrandChildView", CanFocus = true }; ;
var parentView = new View () { Id = "parentView", CanFocus = true };
;
var childView1 = new View () { Id = "childView1", CanFocus = true };
;
var childView2 = new View () { Id = "childView2", CanFocus = true };
;
var grandChildView = new View () { Id = "grandChildView", CanFocus = true };
;
var greatGrandChildView = new View () { Id = "greatGrandChildView", CanFocus = true };
;
parentView.Add (childView1, childView2);
childView2.Add (grandChildView);
@@ -113,48 +120,75 @@ public class ApplicationNavigationTests (ITestOutputHelper output)
Assert.Equal (grandChildView, result);
}
[Fact]
public void GetFocused_Returns_Null_If_No_Focused_View ()
{
Application.Navigation = new ();
//[Fact]
//public void MoveNextViewOrTop_ShouldMoveFocusToNextViewOrTop ()
//{
// // Arrange
// var top = new Toplevel ();
// var view1 = new View () { Id = "view1", CanFocus = true };
// var view2 = new View () { Id = "view2", CanFocus = true };
// top.Add (view1, view2);
// Application.Top = top;
// Application.Current = top;
// view1.SetFocus ();
Application.Current = new Toplevel()
{
Id = "top",
CanFocus = true
};
// // Act
// ApplicationNavigation.MoveNextViewOrTop ();
View subView1 = new View ()
{
Id = "subView1",
CanFocus = true
};
// // Assert
// Assert.True (view2.HasFocus);
Application.Current.Add (subView1);
Assert.False (Application.Current.HasFocus);
// top.Dispose ();
//}
Application.Current.SetFocus ();
Assert.True (subView1.HasFocus);
Assert.Equal (subView1, Application.Navigation.GetFocused ());
subView1.HasFocus = false;
Assert.False (subView1.HasFocus);
Assert.True (Application.Current.HasFocus);
Assert.Equal (Application.Current, Application.Navigation.GetFocused ());
Application.Current.HasFocus = false;
Assert.False (Application.Current.HasFocus);
Assert.Null (Application.Navigation.GetFocused ());
Application.ResetState ();
}
[Fact]
public void GetFocused_Returns_Focused_View ()
{
Application.Navigation = new ();
//[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 ();
Application.Current = new Toplevel ()
{
Id = "top",
CanFocus = true
};
// // Act
// ApplicationNavigation.MovePreviousViewOrTop ();
View subView1 = new View ()
{
Id = "subView1",
CanFocus = true
};
// // Assert
// Assert.True (view1.HasFocus);
View subView2 = new View ()
{
Id = "subView2",
CanFocus = true
};
Application.Current.Add (subView1, subView2);
Assert.False (Application.Current.HasFocus);
// top.Dispose ();
//}
Application.Current.SetFocus ();
Assert.True (subView1.HasFocus);
Assert.Equal(subView1, Application.Navigation.GetFocused());
Application.Current.AdvanceFocus (NavigationDirection.Forward, null);
Assert.Equal (subView2, Application.Navigation.GetFocused ());
Application.ResetState ();
}
}

View File

@@ -98,6 +98,83 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
Assert.True (subSubView.HasFocus);
}
[Fact]
public void Remove_Subview_Raises_HasFocusChanged ()
{
var top = new View
{
Id = "top",
CanFocus = true
};
var subView1 = new View
{
Id = "subView1",
CanFocus = true
};
var subView2 = new View
{
Id = "subView2",
CanFocus = true
};
top.Add (subView1, subView2);
var subView1HasFocusChangedTrueCount = 0;
var subView1HasFocusChangedFalseCount = 0;
subView1.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
subView1HasFocusChangedTrueCount++;
}
else
{
subView1HasFocusChangedFalseCount++;
}
};
var subView2HasFocusChangedTrueCount = 0;
var subView2HasFocusChangedFalseCount = 0;
subView2.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
subView2HasFocusChangedTrueCount++;
}
else
{
subView2HasFocusChangedFalseCount++;
}
};
top.SetFocus ();
Assert.True (top.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangedTrueCount);
Assert.Equal (0, subView1HasFocusChangedFalseCount);
Assert.Equal (0, subView2HasFocusChangedTrueCount);
Assert.Equal (0, subView2HasFocusChangedFalseCount);
top.Remove (subView1); // this should have the same resuilt as top.AdvanceFocus (NavigationDirection.Forward, null);
Assert.False (subView1.HasFocus);
Assert.True (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangedTrueCount);
Assert.Equal (1, subView1HasFocusChangedFalseCount);
Assert.Equal (1, subView2HasFocusChangedTrueCount);
Assert.Equal (0, subView2HasFocusChangedFalseCount);
}
[Fact]
public void Remove_Focused_Subview_Keeps_Focus_And_SubView_Looses_Focus ()
{
@@ -155,6 +232,7 @@ public class AddRemoveNavigationTests (ITestOutputHelper _output) : TestsAllView
Assert.False (subView2.HasFocus);
top.Remove (subView1);
Assert.True (top.HasFocus);
Assert.True (subView2.HasFocus);
Assert.Equal (subView2, top.Focused);

View File

@@ -4,296 +4,6 @@ namespace Terminal.Gui.ViewTests;
public class AdvanceFocusTests (ITestOutputHelper _output)
{
[Fact]
public void Subviews_TabIndexes_AreEqual ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.Subviews.IndexOf (v2) == 1);
Assert.True (r.Subviews.IndexOf (v3) == 2);
Assert.True (r.TabIndexes.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v2) == 1);
Assert.True (r.TabIndexes.IndexOf (v3) == 2);
Assert.Equal (r.Subviews.IndexOf (v1), r.TabIndexes.IndexOf (v1));
Assert.Equal (r.Subviews.IndexOf (v2), r.TabIndexes.IndexOf (v2));
Assert.Equal (r.Subviews.IndexOf (v3), r.TabIndexes.IndexOf (v3));
r.Dispose ();
}
[Fact]
public void TabIndex_Invert_Order ()
{
var r = new View ();
var v1 = new View { Id = "1", CanFocus = true };
var v2 = new View { Id = "2", CanFocus = true };
var v3 = new View { Id = "3", CanFocus = true };
r.Add (v1, v2, v3);
v1.TabIndex = 2;
v2.TabIndex = 1;
v3.TabIndex = 0;
Assert.True (r.TabIndexes.IndexOf (v1) == 2);
Assert.True (r.TabIndexes.IndexOf (v2) == 1);
Assert.True (r.TabIndexes.IndexOf (v3) == 0);
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.Subviews.IndexOf (v2) == 1);
Assert.True (r.Subviews.IndexOf (v3) == 2);
}
[Fact]
public void TabIndex_Invert_Order_Added_One_By_One_Does_Not_Do_What_Is_Expected ()
{
var r = new View ();
var v1 = new View { Id = "1", CanFocus = true };
r.Add (v1);
v1.TabIndex = 2;
var v2 = new View { Id = "2", CanFocus = true };
r.Add (v2);
v2.TabIndex = 1;
var v3 = new View { Id = "3", CanFocus = true };
r.Add (v3);
v3.TabIndex = 0;
Assert.False (r.TabIndexes.IndexOf (v1) == 2);
Assert.True (r.TabIndexes.IndexOf (v1) == 1);
Assert.False (r.TabIndexes.IndexOf (v2) == 1);
Assert.True (r.TabIndexes.IndexOf (v2) == 2);
// Only the last is in the expected index
Assert.True (r.TabIndexes.IndexOf (v3) == 0);
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.Subviews.IndexOf (v2) == 1);
Assert.True (r.Subviews.IndexOf (v3) == 2);
}
[Fact]
public void TabIndex_Invert_Order_Mixed ()
{
var r = new View ();
var vl1 = new View { Id = "vl1" };
var v1 = new View { Id = "v1", CanFocus = true };
var vl2 = new View { Id = "vl2" };
var v2 = new View { Id = "v2", CanFocus = true };
var vl3 = new View { Id = "vl3" };
var v3 = new View { Id = "v3", CanFocus = true };
r.Add (vl1, v1, vl2, v2, vl3, v3);
v1.TabIndex = 2;
v2.TabIndex = 1;
v3.TabIndex = 0;
Assert.True (r.TabIndexes.IndexOf (v1) == 4);
Assert.True (r.TabIndexes.IndexOf (v2) == 2);
Assert.True (r.TabIndexes.IndexOf (v3) == 0);
Assert.True (r.Subviews.IndexOf (v1) == 1);
Assert.True (r.Subviews.IndexOf (v2) == 3);
Assert.True (r.Subviews.IndexOf (v3) == 5);
}
[Fact]
public void TabIndex_Set_CanFocus_False ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
v1.CanFocus = false;
v1.TabIndex = 0;
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v1) == 0);
Assert.NotEqual (-1, v1.TabIndex);
r.Dispose ();
}
[Fact]
public void TabIndex_Set_CanFocus_False_To_True ()
{
var r = new View ();
var v1 = new View ();
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
v1.CanFocus = true;
v1.TabIndex = 1;
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v1) == 1);
r.Dispose ();
}
[Fact]
public void TabIndex_Set_CanFocus_HigherValues ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
v1.TabIndex = 3;
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v1) == 2);
r.Dispose ();
}
[Fact]
public void TabIndex_Set_CanFocus_LowerValues ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
//v1.TabIndex = -1;
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v1) == 0);
r.Dispose ();
}
[Fact]
public void TabIndex_Set_CanFocus_ValidValues ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
v1.TabIndex = 1;
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v1) == 1);
v1.TabIndex = 2;
Assert.True (r.Subviews.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v1) == 2);
r.Dispose ();
}
[Theory]
[CombinatorialData]
public void TabStop_And_CanFocus_Are_Decoupled (bool canFocus, TabBehavior tabStop)
{
var view = new View { CanFocus = canFocus, TabStop = tabStop };
Assert.Equal (canFocus, view.CanFocus);
Assert.Equal (tabStop, view.TabStop);
}
[Fact]
public void AdvanceFocus_Compound_Subview ()
{
var top = new View () { Id = "top", CanFocus = true };
var compoundSubview = new View ()
{
CanFocus = true,
Id = "compoundSubview",
};
var v1 = new View { Id = "v1", CanFocus = true };
var v2 = new View { Id = "v2", CanFocus = true };
var v3 = new View { Id = "v3", CanFocus = false };
compoundSubview.Add (v1, v2, v3);
top.Add (compoundSubview);
// Cycle through v1 & v2
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
// Add another subview
View otherSubview = new ()
{
CanFocus = true,
Id = "otherSubview",
};
top.Add (otherSubview);
// Adding a focusable subview causes advancefocus
Assert.True (otherSubview.HasFocus);
Assert.False (v1.HasFocus);
// Cycle through v1 & v2
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
Assert.True (otherSubview.HasFocus);
// v2 was previously focused down the compoundSubView focus chain
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.Dispose ();
}
[Fact]
public void AdvanceFocus_With_CanFocus_Are_All_True ()
{
var top = new View () { Id = "top", CanFocus = true };
var v1 = new View { Id = "v1", CanFocus = true };
var v2 = new View { Id = "v2", CanFocus = true };
var v3 = new View { Id = "v3", CanFocus = true };
top.Add (v1, v2, v3);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.True (v3.HasFocus);
top.Dispose ();
}
[Fact]
public void AdvanceFocus_CanFocus_Mixed ()
{
@@ -323,7 +33,7 @@ public class AdvanceFocusTests (ITestOutputHelper _output)
[CombinatorialData]
public void AdvanceFocus_Change_CanFocus_Works ([CombinatorialValues (TabBehavior.NoStop, TabBehavior.TabStop, TabBehavior.TabGroup)] TabBehavior behavior)
{
var r = new View () { CanFocus = true };
var r = new View { CanFocus = true };
var v1 = new View ();
var v2 = new View ();
var v3 = new View ();
@@ -362,6 +72,76 @@ public class AdvanceFocusTests (ITestOutputHelper _output)
r.Dispose ();
}
[Fact]
public void AdvanceFocus_Compound_Subview ()
{
var top = new View { Id = "top", CanFocus = true };
var compoundSubview = new View
{
CanFocus = true,
Id = "compoundSubview"
};
var v1 = new View { Id = "v1", CanFocus = true };
var v2 = new View { Id = "v2", CanFocus = true };
var v3 = new View { Id = "v3", CanFocus = false };
compoundSubview.Add (v1, v2, v3);
top.Add (compoundSubview);
// Cycle through v1 & v2
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
// Add another subview
View otherSubview = new ()
{
CanFocus = true,
Id = "otherSubview"
};
top.Add (otherSubview);
// Adding a focusable subview causes advancefocus
Assert.True (otherSubview.HasFocus);
Assert.False (v1.HasFocus);
// Cycle through v1 & v2
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
Assert.True (otherSubview.HasFocus);
// v2 was previously focused down the compoundSubView focus chain
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.Dispose ();
}
[Fact]
public void AdvanceFocus_NoStop_And_CanFocus_True_No_Focus ()
{
@@ -459,4 +239,207 @@ public class AdvanceFocusTests (ITestOutputHelper _output)
Assert.False (v3.HasFocus);
r.Dispose ();
}
[Fact]
public void AdvanceFocus_Subviews_Raises_HasFocusChanged ()
{
var top = new View
{
Id = "top",
CanFocus = true
};
var subView1 = new View
{
Id = "subView1",
CanFocus = true
};
var subView2 = new View
{
Id = "subView2",
CanFocus = true
};
top.Add (subView1, subView2);
var subView1HasFocusChangedTrueCount = 0;
var subView1HasFocusChangedFalseCount = 0;
subView1.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
subView1HasFocusChangedTrueCount++;
}
else
{
subView1HasFocusChangedFalseCount++;
}
};
var subView2HasFocusChangedTrueCount = 0;
var subView2HasFocusChangedFalseCount = 0;
subView2.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
subView2HasFocusChangedTrueCount++;
}
else
{
subView2HasFocusChangedFalseCount++;
}
};
top.SetFocus ();
Assert.True (top.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangedTrueCount);
Assert.Equal (0, subView1HasFocusChangedFalseCount);
Assert.Equal (0, subView2HasFocusChangedTrueCount);
Assert.Equal (0, subView2HasFocusChangedFalseCount);
top.AdvanceFocus (NavigationDirection.Forward, null);
Assert.False (subView1.HasFocus);
Assert.True (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangedTrueCount);
Assert.Equal (1, subView1HasFocusChangedFalseCount);
Assert.Equal (1, subView2HasFocusChangedTrueCount);
Assert.Equal (0, subView2HasFocusChangedFalseCount);
top.AdvanceFocus (NavigationDirection.Forward, null);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.Equal (2, subView1HasFocusChangedTrueCount);
Assert.Equal (1, subView1HasFocusChangedFalseCount);
Assert.Equal (1, subView2HasFocusChangedTrueCount);
Assert.Equal (1, subView2HasFocusChangedFalseCount);
}
[Fact]
public void AdvanceFocus_Subviews_Raises_HasFocusChanging ()
{
var top = new View
{
Id = "top",
CanFocus = true
};
var subView1 = new View
{
Id = "subView1",
CanFocus = true
};
var subView2 = new View
{
Id = "subView2",
CanFocus = true
};
top.Add (subView1, subView2);
var subView1HasFocusChangingTrueCount = 0;
var subView1HasFocusChangingFalseCount = 0;
subView1.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
{
subView1HasFocusChangingTrueCount++;
}
else
{
subView1HasFocusChangingFalseCount++;
}
};
var subView2HasFocusChangingTrueCount = 0;
var subView2HasFocusChangingFalseCount = 0;
subView2.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
{
subView2HasFocusChangingTrueCount++;
}
else
{
subView2HasFocusChangingFalseCount++;
}
};
top.SetFocus ();
Assert.True (top.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangingTrueCount);
Assert.Equal (0, subView1HasFocusChangingFalseCount);
Assert.Equal (0, subView2HasFocusChangingTrueCount);
Assert.Equal (0, subView2HasFocusChangingFalseCount);
top.AdvanceFocus (NavigationDirection.Forward, null);
Assert.False (subView1.HasFocus);
Assert.True (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangingTrueCount);
Assert.Equal (1, subView1HasFocusChangingFalseCount);
Assert.Equal (1, subView2HasFocusChangingTrueCount);
Assert.Equal (0, subView2HasFocusChangingFalseCount);
top.AdvanceFocus (NavigationDirection.Forward, null);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.Equal (2, subView1HasFocusChangingTrueCount);
Assert.Equal (1, subView1HasFocusChangingFalseCount);
Assert.Equal (1, subView2HasFocusChangingTrueCount);
Assert.Equal (1, subView2HasFocusChangingFalseCount);
}
[Fact]
public void AdvanceFocus_With_CanFocus_Are_All_True ()
{
var top = new View { Id = "top", CanFocus = true };
var v1 = new View { Id = "v1", CanFocus = true };
var v2 = new View { Id = "v2", CanFocus = true };
var v3 = new View { Id = "v3", CanFocus = true };
top.Add (v1, v2, v3);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.True (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.True (v2.HasFocus);
Assert.False (v3.HasFocus);
top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Assert.False (v1.HasFocus);
Assert.False (v2.HasFocus);
Assert.True (v3.HasFocus);
top.Dispose ();
}
[Theory]
[CombinatorialData]
public void TabStop_And_CanFocus_Are_Decoupled (bool canFocus, TabBehavior tabStop)
{
var view = new View { CanFocus = canFocus, TabStop = tabStop };
Assert.Equal (canFocus, view.CanFocus);
Assert.Equal (tabStop, view.TabStop);
}
}

View File

@@ -244,48 +244,48 @@ public class CanFocusTests (ITestOutputHelper _output) : TestsAllViews
Application.Shutdown ();
}
[Fact]
public void CanFocus_Set_Changes_TabIndex_And_TabStop ()
{
var r = new View ();
var v1 = new View { Text = "1" };
var v2 = new View { Text = "2" };
var v3 = new View { Text = "3" };
//[Fact]
//public void CanFocus_Set_Changes_TabIndex_And_TabStop ()
//{
// var r = new View ();
// var v1 = new View { Text = "1" };
// var v2 = new View { Text = "2" };
// var v3 = new View { Text = "3" };
r.Add (v1, v2, v3);
// r.Add (v1, v2, v3);
v2.CanFocus = true;
Assert.Equal (r.TabIndexes.IndexOf (v2), v2.TabIndex);
Assert.Equal (0, v2.TabIndex);
Assert.Equal (TabBehavior.TabStop, v2.TabStop);
// v2.CanFocus = true;
// Assert.Equal (r.TabIndexes.IndexOf (v2), v2.TabIndex);
// Assert.Equal (0, v2.TabIndex);
// Assert.Equal (TabBehavior.TabStop, v2.TabStop);
v1.CanFocus = true;
Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
Assert.Equal (1, v1.TabIndex);
Assert.Equal (TabBehavior.TabStop, v1.TabStop);
// v1.CanFocus = true;
// Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
// Assert.Equal (1, v1.TabIndex);
// Assert.Equal (TabBehavior.TabStop, v1.TabStop);
v1.TabIndex = 2;
Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
Assert.Equal (1, v1.TabIndex);
v3.CanFocus = true;
Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
Assert.Equal (1, v1.TabIndex);
Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex);
Assert.Equal (2, v3.TabIndex);
Assert.Equal (TabBehavior.TabStop, v3.TabStop);
// v1.TabIndex = 2;
// Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
// Assert.Equal (1, v1.TabIndex);
// v3.CanFocus = true;
// Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
// Assert.Equal (1, v1.TabIndex);
// Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex);
// Assert.Equal (2, v3.TabIndex);
// Assert.Equal (TabBehavior.TabStop, v3.TabStop);
v2.CanFocus = false;
Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
Assert.Equal (1, v1.TabIndex);
Assert.Equal (TabBehavior.TabStop, v1.TabStop);
Assert.Equal (r.TabIndexes.IndexOf (v2), v2.TabIndex); // TabIndex is not changed
Assert.NotEqual (-1, v2.TabIndex);
Assert.Equal (TabBehavior.TabStop, v2.TabStop); // TabStop is not changed
Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex);
Assert.Equal (2, v3.TabIndex);
Assert.Equal (TabBehavior.TabStop, v3.TabStop);
r.Dispose ();
}
// v2.CanFocus = false;
// Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex);
// Assert.Equal (1, v1.TabIndex);
// Assert.Equal (TabBehavior.TabStop, v1.TabStop);
// Assert.Equal (r.TabIndexes.IndexOf (v2), v2.TabIndex); // TabIndex is not changed
// Assert.NotEqual (-1, v2.TabIndex);
// Assert.Equal (TabBehavior.TabStop, v2.TabStop); // TabStop is not changed
// Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex);
// Assert.Equal (2, v3.TabIndex);
// Assert.Equal (TabBehavior.TabStop, v3.TabStop);
// r.Dispose ();
//}
[Fact]
public void CanFocus_True_Focuses ()

View File

@@ -5,6 +5,7 @@ namespace Terminal.Gui.ViewTests;
public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllViews
{
#region HasFocusChanging_NewValue_True
[Fact]
public void HasFocusChanging_SetFocus_Raises ()
{
@@ -16,6 +17,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -49,6 +51,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -69,17 +72,18 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
{
subviewHasFocusTrueCount++;
}
else
{
subviewHasFocusFalseCount++;
}
};
{
if (e.NewValue)
{
subviewHasFocusTrueCount++;
}
else
{
subviewHasFocusFalseCount++;
}
};
view.Add (subview);
@@ -104,6 +108,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -124,6 +129,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -158,6 +164,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -178,6 +185,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subView",
CanFocus = true
};
subView.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -198,6 +206,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subViewSubView1",
CanFocus = false
};
subViewSubView1.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -218,6 +227,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subViewSubView2",
CanFocus = true
};
subViewSubView2.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -238,6 +248,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subViewSubView3",
CanFocus = false
};
subViewSubView3.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -288,6 +299,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -309,6 +321,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -346,6 +359,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -367,6 +381,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -404,6 +419,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -424,6 +440,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -463,6 +480,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -483,6 +501,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -537,6 +556,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -575,6 +595,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -595,6 +616,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -618,7 +640,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Assert.Equal (0, subviewHasFocusFalseCount);
view.HasFocus = false;
Assert.False(view.HasFocus);
Assert.False (view.HasFocus);
Assert.False (subview.HasFocus);
Assert.Equal (1, hasFocusTrueCount);
Assert.Equal (1, hasFocusFalseCount);
@@ -640,6 +662,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -660,6 +683,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanging += (s, e) =>
{
if (e.NewValue)
@@ -691,6 +715,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Assert.Equal (1, subviewHasFocusFalseCount);
}
#endregion HasFocusChanging_NewValue_False
#region HasFocusChanged
@@ -706,6 +731,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -743,6 +769,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -763,6 +790,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subview",
CanFocus = true
};
subview.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -821,6 +849,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -841,6 +870,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subView",
CanFocus = true
};
subView.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -861,6 +891,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subViewSubView1",
CanFocus = false
};
subViewSubView1.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -881,6 +912,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subViewSubView2",
CanFocus = true
};
subViewSubView2.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -900,6 +932,7 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "subViewSubView3",
CanFocus = false
};
subViewSubView3.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
@@ -967,32 +1000,33 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Id = "view",
CanFocus = true
};
view.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
Assert.True (view.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
{
if (e.NewValue)
{
Assert.True (view.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
subView1.Visible = true;
subView2.Visible = false;
subView1.Visible = true;
subView2.Visible = false;
Assert.True (view.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.True (view.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
}
else
{
Assert.False (view.HasFocus);
Assert.False (subView1.HasFocus);
Assert.False (subView2.HasFocus);
}
else
{
Assert.False (view.HasFocus);
Assert.False (subView1.HasFocus);
Assert.False (subView2.HasFocus);
subView1.Visible = false;
subView2.Visible = true;
}
};
subView1.Visible = false;
subView2.Visible = true;
}
};
view.Add (subView1, subView2);
@@ -1006,5 +1040,6 @@ public class HasFocusChangeEventTests (ITestOutputHelper _output) : TestsAllView
Assert.False (subView1.HasFocus);
Assert.False (subView2.HasFocus);
}
#endregion HasFocusChanged
}

View File

@@ -155,4 +155,79 @@ public class HasFocusTests (ITestOutputHelper _output) : TestsAllViews
Assert.False (subViewSubView2.HasFocus);
Assert.False (subViewSubView3.HasFocus);
}
[Fact]
public void HasFocus_False_Subview_Raises_HasFocusChanged ()
{
var top = new View
{
Id = "top",
CanFocus = true
};
var subView1 = new View
{
Id = "subView1",
CanFocus = true
};
var subView2 = new View
{
Id = "subView2",
CanFocus = true
};
top.Add (subView1, subView2);
var subView1HasFocusChangedTrueCount = 0;
var subView1HasFocusChangedFalseCount = 0;
subView1.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
subView1HasFocusChangedTrueCount++;
}
else
{
subView1HasFocusChangedFalseCount++;
}
};
var subView2HasFocusChangedTrueCount = 0;
var subView2HasFocusChangedFalseCount = 0;
subView2.HasFocusChanged += (s, e) =>
{
if (e.NewValue)
{
subView2HasFocusChangedTrueCount++;
}
else
{
subView2HasFocusChangedFalseCount++;
}
};
top.SetFocus ();
Assert.True (top.HasFocus);
Assert.True (subView1.HasFocus);
Assert.False (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangedTrueCount);
Assert.Equal (0, subView1HasFocusChangedFalseCount);
Assert.Equal (0, subView2HasFocusChangedTrueCount);
Assert.Equal (0, subView2HasFocusChangedFalseCount);
subView1.HasFocus = false; // this should have the same resuilt as top.AdvanceFocus (NavigationDirection.Forward, null);
Assert.False (subView1.HasFocus);
Assert.True (subView2.HasFocus);
Assert.Equal (1, subView1HasFocusChangedTrueCount);
Assert.Equal (1, subView1HasFocusChangedFalseCount);
Assert.Equal (1, subView2HasFocusChangedTrueCount);
Assert.Equal (0, subView2HasFocusChangedFalseCount);
}
}

View File

@@ -313,48 +313,6 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews
}
[Fact]
public void BringSubviewForward_Subviews_vs_TabIndexes ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
r.BringSubviewForward (v1);
Assert.True (r.Subviews.IndexOf (v1) == 1);
Assert.True (r.Subviews.IndexOf (v2) == 0);
Assert.True (r.Subviews.IndexOf (v3) == 2);
Assert.True (r.TabIndexes.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v2) == 1);
Assert.True (r.TabIndexes.IndexOf (v3) == 2);
r.Dispose ();
}
[Fact]
public void BringSubviewToFront_Subviews_vs_TabIndexes ()
{
var r = new View ();
var v1 = new View { CanFocus = true };
var v2 = new View { CanFocus = true };
var v3 = new View { CanFocus = true };
r.Add (v1, v2, v3);
r.BringSubviewToFront (v1);
Assert.True (r.Subviews.IndexOf (v1) == 2);
Assert.True (r.Subviews.IndexOf (v2) == 0);
Assert.True (r.Subviews.IndexOf (v3) == 1);
Assert.True (r.TabIndexes.IndexOf (v1) == 0);
Assert.True (r.TabIndexes.IndexOf (v2) == 1);
Assert.True (r.TabIndexes.IndexOf (v3) == 2);
r.Dispose ();
}
// View.Focused & View.MostFocused tests
// View.Focused - No subviews

View File

@@ -1064,7 +1064,6 @@ At 0,0
Assert.True (win.Visible);
Assert.True (win.CanFocus);
Assert.True (win.HasFocus);
Assert.True (RunesCount () > 0);
win.Visible = false;
Assert.True (button.Visible);
@@ -1073,21 +1072,18 @@ At 0,0
Assert.False (win.Visible);
Assert.True (win.CanFocus);
Assert.False (win.HasFocus);
button.SetFocus ();
Assert.False (button.HasFocus);
Assert.False (win.HasFocus);
win.SetFocus ();
Assert.False (button.HasFocus);
Assert.False (win.HasFocus);
top.Draw ();
Assert.True (RunesCount () == 0);
win.Visible = true;
win.FocusDeepest (NavigationDirection.Forward, null);
Assert.True (button.HasFocus);
Assert.True (win.HasFocus);
top.Draw ();
Assert.True (RunesCount () > 0);
Application.RequestStop ();
};
@@ -1095,25 +1091,6 @@ At 0,0
Application.Run (top);
top.Dispose ();
Assert.Equal (1, iterations);
int RunesCount ()
{
Cell [,] contents = ((FakeDriver)Application.Driver).Contents;
var runesCount = 0;
for (var i = 0; i < Application.Driver!.Rows; i++)
{
for (var j = 0; j < Application.Driver!.Cols; j++)
{
if (contents [i, j].Rune != (Rune)' ')
{
runesCount++;
}
}
}
return runesCount;
}
}
public class DerivedView : View

View File

@@ -506,7 +506,7 @@ public class ComboBoxTests (ITestOutputHelper output)
top.Add (otherView, cb);
Application.Begin (top);
Assert.False (cb.HasFocus);
Assert.True (cb.HasFocus);
Assert.True (cb.HideDropdownListOnClick);
Assert.False (cb.IsShow);
@@ -857,7 +857,7 @@ Three ",
Assert.True (Application.OnKeyDown (Key.CursorDown)); // losing focus
Assert.False (cb.IsShow);
Assert.False (cb.HasFocus);
top.FocusDeepest (NavigationDirection.Forward, null); // Gets focus again
cb.SetFocus ();
Assert.False (cb.IsShow);
Assert.True (cb.HasFocus);
cb.Expand ();
@@ -969,7 +969,8 @@ Three
Assert.False (cb.IsShow);
Assert.Equal (-1, cb.SelectedItem);
Assert.Equal ("One", cb.Text);
top.FocusDeepest (NavigationDirection.Forward, null); // Gets focus again
cb.SetFocus ();
Assert.True (cb.HasFocus);
Assert.False (cb.IsShow);
Assert.Equal (-1, cb.SelectedItem);

View File

@@ -1232,7 +1232,7 @@ public class OverlappedTests
Assert.Equal (superView.MostFocused, current);
// Act
ApplicationOverlapped.SetFocusToNextViewWithWrap (Application.Current.SuperView.TabIndexes, NavigationDirection.Forward);
ApplicationOverlapped.SetFocusToNextViewWithWrap (Application.Current.SuperView.Subviews, NavigationDirection.Forward);
// Assert
Assert.True (view1.HasFocus);