mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 16:59:35 +01:00
Remove TextField.Caption property; use Title with hotkey navigation support (#4352)
* Initial plan * Initial exploration - understanding TextField Caption and Title Co-authored-by: tig <585482+tig@users.noreply.github.com> * Remove TextField.Caption and use Title instead with hotkey support Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add defensive check to ensure TitleTextFormatter.Text is set Co-authored-by: tig <585482+tig@users.noreply.github.com> * Final changes - all tests passing Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fixed bugs. * Add comprehensive tests for caption rendering with attributes validation Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fix: Disable TextField hotkey functionality to prevent input interception TextField's Title is used as a caption/placeholder, not for hotkey navigation. Hotkey visual formatting (underline) is still rendered in the caption, but hotkey functionality is disabled to prevent keys like 'E' and 'F' from being intercepted when typing in the field. Updated test to expect "_Find" instead of "Find" to match resource change. Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fix: Support Alt+key hotkey navigation while allowing normal typing Override AddKeyBindingsForHotKey to only bind Alt+key combinations (e.g., Alt+F for "_Find"), not the bare keys. This allows: - Alt+F to navigate to the TextField with Title="_Find" - Normal typing of 'F', 'E', etc. without interception Previously, both bare key and Alt+key were bound, causing typing issues. Now TextField properly supports hotkey navigation without interfering with text input. Co-authored-by: tig <585482+tig@users.noreply.github.com> * Changes before error encountered Co-authored-by: tig <585482+tig@users.noreply.github.com> * Refactor hotkey handling to support command context Refactored `RaiseHandlingHotKey` to accept an `ICommandContext? ctx` parameter, enabling context-aware hotkey handling. Updated `Command.HotKey` definitions across multiple classes (`View`, `CheckBox`, `Label`, `MenuBarv2`, `RadioGroup`, `TextField`) to utilize the new context parameter. Enhanced XML documentation for `RaiseHandlingHotKey` to clarify its usage and return values. Added a context-aware hotkey handler to `TextField` with additional logic for focus handling. Refactored attribute initialization and improved code readability in `TextField` by aligning parameters and removing unused `HotKeySpecifier` initialization. These changes improve flexibility, maintainability, and consistency across the codebase. * Remove TextField.Caption property; use Title with hotkey navigation support Co-authored-by: tig <585482+tig@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tig <585482+tig@users.noreply.github.com> Co-authored-by: Tig <tig@users.noreply.github.com>
This commit is contained in:
@@ -145,7 +145,7 @@ public class TextFieldTests (ITestOutputHelper output)
|
||||
TextField tf = GetTextFieldsInView ();
|
||||
|
||||
// Caption has no effect when focused
|
||||
tf.Caption = caption;
|
||||
tf.Title = caption;
|
||||
Application.RaiseKeyDownEvent ('\t');
|
||||
Assert.False (tf.HasFocus);
|
||||
|
||||
@@ -165,7 +165,7 @@ public class TextFieldTests (ITestOutputHelper output)
|
||||
|
||||
TextField tf = GetTextFieldsInView ();
|
||||
|
||||
tf.Caption = caption;
|
||||
tf.Title = caption;
|
||||
Application.RaiseKeyDownEvent ('\t');
|
||||
Assert.False (tf.HasFocus);
|
||||
|
||||
@@ -185,7 +185,7 @@ public class TextFieldTests (ITestOutputHelper output)
|
||||
tf.Draw ();
|
||||
DriverAssert.AssertDriverContentsAre ("", output);
|
||||
|
||||
tf.Caption = "Enter txt";
|
||||
tf.Title = "Enter txt";
|
||||
Application.RaiseKeyDownEvent ('\t');
|
||||
|
||||
// Caption should appear when not focused and no text
|
||||
@@ -212,7 +212,7 @@ public class TextFieldTests (ITestOutputHelper output)
|
||||
DriverAssert.AssertDriverContentsAre ("", output);
|
||||
|
||||
// Caption has no effect when focused
|
||||
tf.Caption = "Enter txt";
|
||||
tf.Title = "Enter txt";
|
||||
Assert.True (tf.HasFocus);
|
||||
View.SetClipToScreen ();
|
||||
tf.Draw ();
|
||||
@@ -227,6 +227,104 @@ public class TextFieldTests (ITestOutputHelper output)
|
||||
Application.Top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Title_RendersAsCaption_WithCorrectAttributes ()
|
||||
{
|
||||
TextField tf = GetTextFieldsInView ();
|
||||
|
||||
// Set a title (caption)
|
||||
tf.Title = "Enter text";
|
||||
|
||||
// Remove focus so caption appears
|
||||
Application.RaiseKeyDownEvent ('\t');
|
||||
Assert.False (tf.HasFocus);
|
||||
|
||||
View.SetClipToScreen ();
|
||||
tf.Draw ();
|
||||
|
||||
// Verify the caption text is rendered
|
||||
DriverAssert.AssertDriverContentsAre ("Enter text", output);
|
||||
|
||||
// Verify the caption uses dimmed color attribute
|
||||
Attribute captionAttr = new Attribute (
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Foreground.GetDimColor (),
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Background);
|
||||
|
||||
// All characters in "Enter text" should have the caption attribute
|
||||
DriverAssert.AssertDriverAttributesAre ("0000000000", output, Application.Driver, captionAttr);
|
||||
|
||||
Application.Top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Title_WithHotkey_RendersUnderlined ()
|
||||
{
|
||||
TextField tf = GetTextFieldsInView ();
|
||||
|
||||
// Title with hotkey should be rendered with the hotkey underlined when not focused
|
||||
tf.Title = "_Find";
|
||||
|
||||
// Remove focus so caption appears
|
||||
Application.RaiseKeyDownEvent ('\t');
|
||||
Assert.False (tf.HasFocus);
|
||||
|
||||
View.SetClipToScreen ();
|
||||
tf.Draw ();
|
||||
|
||||
// The hotkey character 'F' should be rendered (without the underscore in the actual text)
|
||||
DriverAssert.AssertDriverContentsAre ("Find", output);
|
||||
|
||||
// Verify the hotkey character 'F' has underline style
|
||||
Attribute captionAttr = new Attribute (
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Foreground.GetDimColor (),
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Background);
|
||||
Attribute hotkeyAttr = new Attribute (
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Foreground.GetDimColor (),
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Background,
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Style | TextStyle.Underline);
|
||||
|
||||
// F is underlined (index 1), remaining characters use normal caption attribute (index 0)
|
||||
DriverAssert.AssertDriverAttributesAre ("1000", output, Application.Driver, captionAttr, hotkeyAttr);
|
||||
|
||||
Application.Top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Title_WithHotkey_MiddleCharacter_RendersUnderlined ()
|
||||
{
|
||||
TextField tf = GetTextFieldsInView ();
|
||||
|
||||
// Title with hotkey in middle of text
|
||||
tf.Title = "Enter _Text";
|
||||
|
||||
// Remove focus so caption appears
|
||||
Application.RaiseKeyDownEvent ('\t');
|
||||
Assert.False (tf.HasFocus);
|
||||
|
||||
View.SetClipToScreen ();
|
||||
tf.Draw ();
|
||||
|
||||
// The underscore should not be rendered, 'T' should be underlined
|
||||
DriverAssert.AssertDriverContentsAre ("Enter Text", output);
|
||||
|
||||
// Verify the hotkey character 'T' has underline style
|
||||
Attribute captionAttr = new Attribute (
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Foreground.GetDimColor (),
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Background);
|
||||
Attribute hotkeyAttr = new Attribute (
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Foreground.GetDimColor (),
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Background,
|
||||
tf.GetAttributeForRole (VisualRole.Editable).Style | TextStyle.Underline);
|
||||
|
||||
// "Enter " (6 chars) + "T" (underlined) + "ext" (3 chars)
|
||||
DriverAssert.AssertDriverAttributesAre ("0000001000", output, Application.Driver, captionAttr, hotkeyAttr);
|
||||
|
||||
Application.Top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[TextFieldTestsAutoInitShutdown]
|
||||
public void Changing_SelectedStart_Or_CursorPosition_Update_SelectedLength_And_SelectedText ()
|
||||
|
||||
Reference in New Issue
Block a user