mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Changed Button Text property to use override instead of new. (#1622)
* Changed Button Text property to use override instead of new. * Fixing HotKey behavior.
This commit is contained in:
@@ -186,12 +186,12 @@ namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// Gets or sets the HotKey defined for this view. A user pressing HotKey on the keyboard while this view has focus will cause the Clicked event to fire.
|
||||
/// </summary>
|
||||
public Key HotKey { get => textFormatter.HotKey; set => textFormatter.HotKey = value; }
|
||||
public virtual Key HotKey { get => textFormatter.HotKey; set => textFormatter.HotKey = value; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the specifier character for the hotkey (e.g. '_'). Set to '\xffff' to disable hotkey support for this View instance. The default is '\xffff'.
|
||||
/// </summary>
|
||||
public Rune HotKeySpecifier { get => textFormatter.HotKeySpecifier; set => textFormatter.HotKeySpecifier = value; }
|
||||
public virtual Rune HotKeySpecifier { get => textFormatter.HotKeySpecifier; set => textFormatter.HotKeySpecifier = value; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the global setting that can be used as a global shortcut to invoke an action if provided.
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Terminal.Gui {
|
||||
public class Button : View {
|
||||
ustring text;
|
||||
bool is_default;
|
||||
TextFormatter textFormatter = new TextFormatter ();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Computed"/> layout.
|
||||
@@ -96,6 +97,8 @@ namespace Terminal.Gui {
|
||||
Rune _rightBracket;
|
||||
Rune _leftDefault;
|
||||
Rune _rightDefault;
|
||||
private Key hotKey = Key.Null;
|
||||
private Rune hotKeySpecifier;
|
||||
|
||||
void Initialize (ustring text, bool is_default)
|
||||
{
|
||||
@@ -113,8 +116,6 @@ namespace Terminal.Gui {
|
||||
this.text = text ?? string.Empty;
|
||||
Update ();
|
||||
|
||||
HotKeyChanged += Button_HotKeyChanged;
|
||||
|
||||
// Things this view knows how to do
|
||||
AddCommand (Command.Accept, () => AcceptKey ());
|
||||
|
||||
@@ -126,27 +127,17 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_HotKeyChanged (Key obj)
|
||||
{
|
||||
if (HotKey != Key.Null) {
|
||||
if (ContainsKeyBinding (obj)) {
|
||||
ReplaceKeyBinding (Key.Space | obj, Key.Space | HotKey);
|
||||
} else {
|
||||
AddKeyBinding (Key.Space | HotKey, Command.Accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The text displayed by this <see cref="Button"/>.
|
||||
/// </summary>
|
||||
public new ustring Text {
|
||||
/// <inheritdoc/>>
|
||||
public override ustring Text {
|
||||
get {
|
||||
return text;
|
||||
}
|
||||
|
||||
set {
|
||||
text = value;
|
||||
TextFormatter.FindHotKey (text, HotKeySpecifier, true, out _, out Key hk);
|
||||
if (hotKey != hk) {
|
||||
HotKey = hk;
|
||||
}
|
||||
Update ();
|
||||
}
|
||||
}
|
||||
@@ -163,14 +154,51 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Key HotKey {
|
||||
get => hotKey;
|
||||
set {
|
||||
if (hotKey != value) {
|
||||
var v = value == Key.Unknown ? Key.Null : value;
|
||||
if (ContainsKeyBinding (Key.Space | hotKey)) {
|
||||
if (v == Key.Null) {
|
||||
ClearKeybinding (Key.Space | hotKey);
|
||||
} else {
|
||||
ReplaceKeyBinding (Key.Space | hotKey, Key.Space | v);
|
||||
}
|
||||
} else if (v != Key.Null) {
|
||||
AddKeyBinding (Key.Space | v, Command.Accept);
|
||||
}
|
||||
hotKey = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Rune HotKeySpecifier {
|
||||
get => hotKeySpecifier;
|
||||
set {
|
||||
hotKeySpecifier = textFormatter.HotKeySpecifier = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool AutoSize {
|
||||
get => base.AutoSize;
|
||||
set {
|
||||
base.AutoSize = value;
|
||||
Update ();
|
||||
}
|
||||
}
|
||||
|
||||
internal void Update ()
|
||||
{
|
||||
if (IsDefault)
|
||||
base.Text = ustring.Make (_leftBracket) + ustring.Make (_leftDefault) + " " + text + " " + ustring.Make (_rightDefault) + ustring.Make (_rightBracket);
|
||||
textFormatter.Text = ustring.Make (_leftBracket) + ustring.Make (_leftDefault) + " " + text + " " + ustring.Make (_rightDefault) + ustring.Make (_rightBracket);
|
||||
else
|
||||
base.Text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket);
|
||||
textFormatter.Text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket);
|
||||
|
||||
int w = base.Text.RuneCount - (base.Text.Contains (HotKeySpecifier) ? 1 : 0);
|
||||
int w = textFormatter.Text.RuneCount - (textFormatter.Text.Contains (HotKeySpecifier) ? 1 : 0);
|
||||
GetCurrentWidth (out int cWidth);
|
||||
var canSetWidth = SetWidth (w, out int rWidth);
|
||||
if (canSetWidth && (cWidth < rWidth || AutoSize)) {
|
||||
@@ -194,6 +222,25 @@ namespace Terminal.Gui {
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Redraw (Rect bounds)
|
||||
{
|
||||
if (ColorScheme != null) {
|
||||
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
|
||||
}
|
||||
|
||||
if (Border != null) {
|
||||
Border.DrawContent (this);
|
||||
}
|
||||
|
||||
if (!ustring.IsNullOrEmpty (textFormatter.Text)) {
|
||||
Clear ();
|
||||
textFormatter.NeedsFormat = true;
|
||||
textFormatter?.Draw (ViewToScreen (Bounds), HasFocus ? ColorScheme.Focus : GetNormalColor (),
|
||||
HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled);
|
||||
}
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override bool ProcessHotKey (KeyEvent kb)
|
||||
{
|
||||
@@ -294,8 +341,8 @@ namespace Terminal.Gui {
|
||||
public override void PositionCursor ()
|
||||
{
|
||||
if (HotKey == Key.Unknown && text != "") {
|
||||
for (int i = 0; i < base.Text.RuneCount; i++) {
|
||||
if (base.Text [i] == text [0]) {
|
||||
for (int i = 0; i < textFormatter.Text.RuneCount; i++) {
|
||||
if (textFormatter.Text [i] == text [0]) {
|
||||
Move (i, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@ using Xunit;
|
||||
|
||||
namespace Terminal.Gui.Views {
|
||||
public class ButtonTests {
|
||||
[Fact]
|
||||
[Fact, AutoInitShutdown]
|
||||
public void Constructors_Defaults ()
|
||||
{
|
||||
var btn = new Button ();
|
||||
Assert.Equal (string.Empty, btn.Text);
|
||||
Assert.Equal ("[ ]", btn.GetType ().BaseType.GetProperty ("Text").GetValue (btn).ToString ());
|
||||
Application.Top.Add (btn);
|
||||
btn.Redraw (btn.Bounds);
|
||||
Assert.Equal ("[ ]", GetContents (btn.Bounds.Width));
|
||||
Assert.False (btn.IsDefault);
|
||||
Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
|
||||
Assert.Equal ('_', btn.HotKeySpecifier);
|
||||
@@ -22,23 +24,36 @@ namespace Terminal.Gui.Views {
|
||||
|
||||
btn = new Button ("Test", true);
|
||||
Assert.Equal ("Test", btn.Text);
|
||||
Assert.Equal ("[< Test >]", btn.GetType ().BaseType.GetProperty ("Text").GetValue (btn).ToString ());
|
||||
Application.Top.Add (btn);
|
||||
btn.Redraw (btn.Bounds);
|
||||
Assert.Equal ("[◦ Test ◦]", GetContents (btn.Bounds.Width));
|
||||
Assert.True (btn.IsDefault);
|
||||
Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
|
||||
Assert.Equal ('_', btn.HotKeySpecifier);
|
||||
Assert.True (btn.CanFocus);
|
||||
Assert.Equal (new Rect (0, 0, 10, 1), btn.Frame);
|
||||
Assert.Equal (Key.Null, btn.HotKey);
|
||||
Assert.Equal (Key.T, btn.HotKey);
|
||||
|
||||
btn = new Button (3, 4, "Test", true);
|
||||
Assert.Equal ("Test", btn.Text);
|
||||
Assert.Equal ("[< Test >]", btn.GetType ().BaseType.GetProperty ("Text").GetValue (btn).ToString ());
|
||||
Application.Top.Add (btn);
|
||||
btn.Redraw (btn.Bounds);
|
||||
Assert.Equal ("[◦ Test ◦]", GetContents (btn.Bounds.Width));
|
||||
Assert.True (btn.IsDefault);
|
||||
Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
|
||||
Assert.Equal ('_', btn.HotKeySpecifier);
|
||||
Assert.True (btn.CanFocus);
|
||||
Assert.Equal (new Rect (3, 4, 10, 1), btn.Frame);
|
||||
Assert.Equal (Key.Null, btn.HotKey);
|
||||
Assert.Equal (Key.T, btn.HotKey);
|
||||
}
|
||||
|
||||
private string GetContents (int width)
|
||||
{
|
||||
string output = "";
|
||||
for (int i = 0; i < width; i++) {
|
||||
output += (char)Application.Driver.Contents [0, i, 0];
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -75,9 +90,15 @@ namespace Terminal.Gui.Views {
|
||||
clicked = false;
|
||||
Assert.True (btn.ProcessKey (new KeyEvent ((Key)'t', new KeyModifiers ())));
|
||||
Assert.True (clicked);
|
||||
clicked = false;
|
||||
Assert.True (btn.ProcessKey (new KeyEvent (Key.Space | btn.HotKey, new KeyModifiers ())));
|
||||
Assert.True (clicked);
|
||||
btn.Text = "Te_st";
|
||||
clicked = false;
|
||||
Assert.True (btn.ProcessKey (new KeyEvent (Key.Space | btn.HotKey, new KeyModifiers ())));
|
||||
Assert.True (clicked);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void ChangeHotKey ()
|
||||
@@ -114,18 +135,18 @@ namespace Terminal.Gui.Views {
|
||||
btn.Clicked += () => pressed++;
|
||||
|
||||
// The Button class supports the Accept command
|
||||
Assert.Contains(Command.Accept,btn.GetSupportedCommands ());
|
||||
Assert.Contains (Command.Accept, btn.GetSupportedCommands ());
|
||||
|
||||
Application.Top.Add (btn);
|
||||
Application.Begin (Application.Top);
|
||||
|
||||
// default keybinding is Enter which results in keypress
|
||||
Application.Driver.SendKeys ('\n',ConsoleKey.Enter,false,false,false);
|
||||
Application.Driver.SendKeys ('\n', ConsoleKey.Enter, false, false, false);
|
||||
Assert.Equal (1, pressed);
|
||||
|
||||
// remove the default keybinding (Enter)
|
||||
btn.ClearKeybinding (Command.Accept);
|
||||
|
||||
|
||||
// After clearing the default keystroke the Enter button no longer does anything for the Button
|
||||
Application.Driver.SendKeys ('\n', ConsoleKey.Enter, false, false, false);
|
||||
Assert.Equal (1, pressed);
|
||||
@@ -137,5 +158,32 @@ namespace Terminal.Gui.Views {
|
||||
Application.Driver.SendKeys ('b', ConsoleKey.B, false, false, false);
|
||||
Assert.Equal (2, pressed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestAssignTextToButton ()
|
||||
{
|
||||
View b = new Button ();
|
||||
b.Text = "heya";
|
||||
Assert.Equal ("heya", b.Text);
|
||||
|
||||
// with cast
|
||||
Assert.Equal ("heya", ((Button)b).Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Setting_Empty_Text_Sets_HoKey_To_KeyNull ()
|
||||
{
|
||||
var btn = new Button ("Test");
|
||||
Assert.Equal ("Test", btn.Text);
|
||||
Assert.Equal (Key.T, btn.HotKey);
|
||||
|
||||
btn.Text = string.Empty;
|
||||
Assert.Equal ("", btn.Text);
|
||||
Assert.Equal (Key.Null, btn.HotKey);
|
||||
|
||||
btn.Text = "Te_st";
|
||||
Assert.Equal ("Te_st", btn.Text);
|
||||
Assert.Equal (Key.S, btn.HotKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user