From cc7aca4e50fa972b20bf70cfbfa659f9649ec5bc Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 7 Jul 2020 15:00:36 +0100 Subject: [PATCH] Setting CanFocus also sets TabIndex and TabStop accordingly. --- Terminal.Gui/Core/View.cs | 50 +++++++++++++++++++++++++++++++++------ UnitTests/ViewTests.cs | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 55f7e3040..4ad5e6081 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -217,12 +217,46 @@ namespace Terminal.Gui { public int TabIndex { get { return tabIndex; } set { - if (!CanFocus || SuperView?.tabIndexes == null || SuperView?.tabIndexes.Count == 1 || tabIndex == value) { + if (!CanFocus) { + tabIndex = -1; + return; + } else if (SuperView?.tabIndexes == null || SuperView?.tabIndexes.Count == 1) { + tabIndex = 0; + return; + } else if (tabIndex == value) { return; } tabIndex = value > SuperView.tabIndexes.Count - 1 ? SuperView.tabIndexes.Count - 1 : value < 0 ? 0 : value; - SuperView.tabIndexes.Remove (this); - SuperView.tabIndexes.Insert (tabIndex, this); + tabIndex = GetTabIndex (tabIndex); + if (SuperView.tabIndexes.IndexOf (this) != tabIndex) { + SuperView.tabIndexes.Remove (this); + SuperView.tabIndexes.Insert (tabIndex, this); + SetTabIndex (); + } + } + } + + private int GetTabIndex (int idx) + { + int i = 0; + foreach (var v in SuperView.tabIndexes) { + if (v.tabIndex == -1 || v == this) { + continue; + } + i++; + } + return Math.Min (i, idx); + } + + private void SetTabIndex () + { + int i = 0; + foreach (var v in SuperView.tabIndexes) { + if (v.tabIndex == -1) { + continue; + } + v.tabIndex = i; + i++; } } @@ -248,11 +282,11 @@ namespace Terminal.Gui { if (base.CanFocus != value) { base.CanFocus = value; if (!value && tabIndex > -1) { - tabIndex = -1; - } - if (!value && tabStop) { - tabStop = false; + TabIndex = -1; + } else if (value && tabIndex == -1) { + TabIndex = SuperView != null ? SuperView.tabIndexes.IndexOf (this) : -1; } + TabStop = value; } } } @@ -535,6 +569,8 @@ namespace Terminal.Gui { this.Text = text; CanFocus = false; + TabIndex = -1; + TabStop = false; LayoutStyle = LayoutStyle.Computed; // BUGBUG: CalcRect doesn't account for line wrapping var r = TextFormatter.CalcRect (0, 0, text); diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index a37bf5d81..3bceac0fb 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -501,5 +501,47 @@ namespace Terminal.Gui { Assert.False (v2.HasFocus); Assert.True (v3.HasFocus); } + + [Fact] + public void CanFocus_Set_Changes_TabIndex_And_TabStop () + { + var r = new View (); + var v1 = new View ("1"); + var v2 = new View ("2"); + var v3 = new View ("3"); + + r.Add (v1, v2, v3); + + v2.CanFocus = true; + Assert.Equal (r.TabIndexes.IndexOf (v2), v2.TabIndex); + Assert.Equal (0, v2.TabIndex); + Assert.True (v2.TabStop); + + v1.CanFocus = true; + Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex); + Assert.Equal (1, v1.TabIndex); + Assert.True (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.True (v3.TabStop); + + v2.CanFocus = false; + Assert.Equal (r.TabIndexes.IndexOf (v1), v1.TabIndex); + Assert.Equal (1, v1.TabIndex); + Assert.True (v1.TabStop); + Assert.NotEqual (r.TabIndexes.IndexOf (v2), v2.TabIndex); + Assert.Equal (-1, v2.TabIndex); + Assert.False (v2.TabStop); + Assert.Equal (r.TabIndexes.IndexOf (v3), v3.TabIndex); + Assert.Equal (2, v3.TabIndex); + Assert.True (v3.TabStop); + } } }