// // Button.cs: Button control // // Authors: // Miguel de Icaza (miguel@gnome.org) // using System; using NStack; namespace Terminal.Gui { /// /// Button is a that provides an item that invokes an when activated by the user. /// /// /// /// Provides a button showing text invokes an when clicked on with a mouse /// or when the user presses SPACE, ENTER, or hotkey. The hotkey is specified by the first uppercase /// letter in the button. /// /// /// When the button is configured as the default () and the user presses /// the ENTER key, if no other processes the , the 's /// will be invoked. /// /// public class Button : View { ustring text; bool is_default; /// /// Initializes a new instance of using layout. /// /// /// The width of the is computed based on the /// text length. The height will always be 1. /// public Button () : this (text: string.Empty, is_default: false) { } /// /// Initializes a new instance of using layout. /// /// /// The width of the is computed based on the /// text length. The height will always be 1. /// /// The button's text /// /// If true, a special decoration is used, and the user pressing the enter key /// in a will implicitly activate this button. /// public Button (ustring text, bool is_default = false) : base () { Init (text, is_default); } /// /// Initializes a new instance of using layout, based on the given text /// /// /// The width of the is computed based on the /// text length. The height will always be 1. /// /// X position where the button will be shown. /// Y position where the button will be shown. /// The button's text public Button (int x, int y, ustring text) : this (x, y, text, false) { } /// /// Initializes a new instance of using layout, based on the given text. /// /// /// The width of the is computed based on the /// text length. The height will always be 1. /// /// X position where the button will be shown. /// Y position where the button will be shown. /// The button's text /// /// If true, a special decoration is used, and the user pressing the enter key /// in a will implicitly activate this button. /// public Button (int x, int y, ustring text, bool is_default) : base (new Rect (x, y, text.RuneCount + 4 + (is_default ? 2 : 0), 1)) { Init (text, is_default); } Rune _leftBracket; Rune _rightBracket; Rune _leftDefault; Rune _rightDefault; void Init (ustring text, bool is_default) { HotKeySpecifier = new Rune ('_'); _leftBracket = new Rune (Driver != null ? Driver.LeftBracket : '['); _rightBracket = new Rune (Driver != null ? Driver.RightBracket : ']'); _leftDefault = new Rune (Driver != null ? Driver.LeftDefaultIndicator : '<'); _rightDefault = new Rune (Driver != null ? Driver.RightDefaultIndicator : '>'); CanFocus = true; this.IsDefault = is_default; Text = text ?? string.Empty; //int w = SetWidthHeight (text, is_default); //Frame = new Rect (Frame.Location, new Size (w, 1)); } //int SetWidthHeight (ustring text, bool is_default) //{ // int w = text.RuneCount;// + 4 + (is_default ? 2 : 0); // Width = w; // Height = 1; // Frame = new Rect (Frame.Location, new Size (w, 1)); // return w; //} /// /// The text displayed by this . /// public new ustring Text { get { return text; } set { text = value; Update (); } } /// /// Gets or sets whether the is the default action to activate in a dialog. /// /// true if is default; otherwise, false. public bool IsDefault { get => is_default; set { is_default = value; Update (); } } internal void Update () { if (IsDefault) base.Text = ustring.Make (_leftBracket) + ustring.Make (_leftDefault) + " " + text + " " + ustring.Make (_rightDefault) + ustring.Make (_rightBracket); else base.Text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket); int w = base.Text.RuneCount - (base.Text.Contains (HotKeySpecifier) ? 1 : 0); Width = w; Height = 1; Frame = new Rect (Frame.Location, new Size (w, 1)); SetNeedsDisplay (); } bool CheckKey (KeyEvent key) { if (key.Key == HotKey) { this.SuperView.SetFocus (this); Clicked?.Invoke (); return true; } return false; } /// public override bool ProcessHotKey (KeyEvent kb) { if (kb.IsAlt) return CheckKey (kb); return false; } /// public override bool ProcessColdKey (KeyEvent kb) { if (IsDefault && kb.KeyValue == '\n') { Clicked?.Invoke (); return true; } return CheckKey (kb); } /// public override bool ProcessKey (KeyEvent kb) { var c = kb.KeyValue; if (c == '\n' || c == ' ' || kb.Key == HotKey) { Clicked?.Invoke (); return true; } return base.ProcessKey (kb); } } }