diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index 9a5bde98d..dff7d8133 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -64,6 +64,7 @@ public class ColorPicker : View Width = textFieldWidth }; tfValue.HasFocusChanged += UpdateSingleBarValueFromTextField; + tfValue.Accept += (s, _)=>UpdateSingleBarValueFromTextField(s); _textFields.Add (bar, tfValue); } @@ -153,6 +154,7 @@ public class ColorPicker : View _tfName.Autocomplete = auto; _tfName.HasFocusChanged += UpdateValueFromName; + _tfName.Accept += (_s, _) => UpdateValueFromName (); } private void CreateTextField () @@ -182,6 +184,7 @@ public class ColorPicker : View Add (_tfHex); _tfHex.HasFocusChanged += UpdateValueFromTextField; + _tfHex.Accept += (_,_)=> UpdateValueFromTextField(); } private void DisposeOldViews () @@ -192,7 +195,6 @@ public class ColorPicker : View if (_textFields.TryGetValue (bar, out TextField? tf)) { - tf.HasFocusChanged -= UpdateSingleBarValueFromTextField; Remove (tf); tf.Dispose (); } @@ -214,7 +216,6 @@ public class ColorPicker : View if (_tfHex != null) { Remove (_tfHex); - _tfHex.HasFocusChanged -= UpdateValueFromTextField; _tfHex.Dispose (); _tfHex = null; } @@ -229,7 +230,6 @@ public class ColorPicker : View if (_tfName != null) { Remove (_tfName); - _tfName.HasFocusChanged -= UpdateValueFromName; _tfName.Dispose (); _tfName = null; } @@ -279,11 +279,18 @@ public class ColorPicker : View private void UpdateSingleBarValueFromTextField (object? sender, HasFocusEventArgs e) { + // if the new value of Focused is true then it is an enter event so ignore if (e.NewValue) { return; } + // it is a leave event so update + UpdateSingleBarValueFromTextField (sender); + } + private void UpdateSingleBarValueFromTextField (object? sender) + { + foreach (KeyValuePair kvp in _textFields) { if (kvp.Value == sender) @@ -296,13 +303,19 @@ public class ColorPicker : View } } - private void UpdateValueFromName (object? sender, HasFocusEventArgs e) + private void UpdateValueFromName (object sender, HasFocusEventArgs e) { + // if the new value of Focused is true then it is an enter event so ignore if (e.NewValue) { return; } + // it is a leave event so update + UpdateValueFromName(); + } + private void UpdateValueFromName () + { if (_tfName == null) { return; @@ -321,11 +334,17 @@ public class ColorPicker : View private void UpdateValueFromTextField (object? sender, HasFocusEventArgs e) { - if (e.NewValue) + // if the new value of Focused is true then it is an enter event so ignore + if (e.NewValue) { return; } + // it is a leave event so update + UpdateValueFromTextField (); + } + private void UpdateValueFromTextField () + { if (_tfHex == null) { return; diff --git a/UnitTests/Views/ColorPickerTests.cs b/UnitTests/Views/ColorPickerTests.cs index a55c92b7c..57a87733d 100644 --- a/UnitTests/Views/ColorPickerTests.cs +++ b/UnitTests/Views/ColorPickerTests.cs @@ -790,6 +790,64 @@ public class ColorPickerTests Application.ResetState (); } + /// + /// In this version we use the Enter button to accept the typed text instead + /// of tabbing to the next view. + /// + [Fact] + [SetupFakeDriver] + public void ColorPicker_EnterHexFor_ColorName_AcceptVariation () + { + var cp = GetColorPicker (ColorModel.RGB, true, true); + Application.Navigation = new (); + Application.Current = new (); + Application.Current.Add (cp); + + cp.Draw (); + + var name = GetTextField (cp, ColorPickerPart.ColorName); + var hex = GetTextField (cp, ColorPickerPart.Hex); + + hex.SetFocus (); + + Assert.True (hex.HasFocus); + Assert.Same (hex, cp.Focused); + + hex.Text = ""; + name.Text = ""; + + Assert.Empty (hex.Text); + Assert.Empty (name.Text); + + Application.OnKeyDown ('#'); + Assert.Empty (name.Text); + //7FFFD4 + + Assert.Equal ("#", hex.Text); + Application.OnKeyDown ('7'); + Application.OnKeyDown ('F'); + Application.OnKeyDown ('F'); + Application.OnKeyDown ('F'); + Application.OnKeyDown ('D'); + Assert.Empty (name.Text); + + Application.OnKeyDown ('4'); + + Assert.True (hex.HasFocus); + + // Should stay in the hex field (because accept not tab) + Application.OnKeyDown (Key.Enter); + Assert.True (hex.HasFocus); + Assert.Same (hex, cp.Focused); + + // But still, Color name should be recognised as a known string and populated + Assert.Equal ("#7FFFD4", hex.Text); + Assert.Equal ("Aquamarine", name.Text); + + Application.Current?.Dispose (); + Application.ResetState (); + } + [Fact] public void TestColorNames () {