//
// Checkbox.cs: Checkbox control
//
// Authors:
// Miguel de Icaza (miguel@gnome.org)
//
using System;
using NStack;
namespace Terminal.Gui {
///
/// The shows an on/off toggle that the user can set
///
public class CheckBox : View {
Rune charChecked;
Rune charUnChecked;
bool @checked;
///
/// Toggled event, raised when the is toggled.
///
///
/// Client code can hook up to this event, it is
/// raised when the is activated either with
/// the mouse or the keyboard. The passed bool contains the previous state.
///
public event Action Toggled;
///
/// Called when the property changes. Invokes the event.
///
public virtual void OnToggled (bool previousChecked)
{
Toggled?.Invoke (previousChecked);
}
///
/// Initializes a new instance of based on the given text, using layout.
///
public CheckBox () : this (string.Empty) { }
///
/// Initializes a new instance of based on the given text, using layout.
///
/// S.
/// If set to true is checked.
public CheckBox (ustring s, bool is_checked = false) : base ()
{
Initialize (s, is_checked);
}
///
/// Initializes a new instance of using layout.
///
///
/// The size of is computed based on the
/// text length. This is not toggled.
///
public CheckBox (int x, int y, ustring s) : this (x, y, s, false)
{
}
///
/// Initializes a new instance of using layout.
///
///
/// The size of is computed based on the
/// text length.
///
public CheckBox (int x, int y, ustring s, bool is_checked) : base (new Rect (x, y, s.Length, 1))
{
Initialize (s, is_checked);
}
void Initialize (ustring s, bool is_checked)
{
charChecked = new Rune (Driver != null ? Driver.Checked : '√');
charUnChecked = new Rune (Driver != null ? Driver.UnChecked : '╴');
Checked = is_checked;
HotKeySpecifier = new Rune ('_');
CanFocus = true;
AutoSize = true;
Text = s;
UpdateTextFormatterText ();
ProcessResizeView ();
// Things this view knows how to do
AddCommand (Command.ToggleChecked, () => ToggleChecked ());
// Default keybindings for this view
AddKeyBinding ((Key)' ', Command.ToggleChecked);
AddKeyBinding (Key.Space, Command.ToggleChecked);
}
///
protected override void UpdateTextFormatterText ()
{
switch (TextAlignment) {
case TextAlignment.Left:
case TextAlignment.Centered:
case TextAlignment.Justified:
TextFormatter.Text = ustring.Make (Checked ? charChecked : charUnChecked) + " " + GetFormatterText ();
break;
case TextAlignment.Right:
TextFormatter.Text = GetFormatterText () + " " + ustring.Make (Checked ? charChecked : charUnChecked);
break;
}
}
ustring GetFormatterText ()
{
if (AutoSize || ustring.IsNullOrEmpty (Text) || Frame.Width <= 2) {
return Text;
}
return Text.RuneSubstring (0, Math.Min (Frame.Width - 2, Text.RuneCount));
}
///
/// The state of the
///
public bool Checked {
get => @checked;
set {
@checked = value;
UpdateTextFormatterText ();
ProcessResizeView ();
}
}
///
public override void PositionCursor ()
{
Move (0, 0);
}
///
public override bool ProcessKey (KeyEvent kb)
{
var result = InvokeKeybindings (kb);
if (result != null)
return (bool)result;
return base.ProcessKey (kb);
}
///
public override bool ProcessHotKey (KeyEvent kb)
{
if (kb.Key == (Key.AltMask | HotKey))
return ToggleChecked ();
return false;
}
bool ToggleChecked ()
{
if (!HasFocus) {
SetFocus ();
}
var previousChecked = Checked;
Checked = !Checked;
OnToggled (previousChecked);
SetNeedsDisplay ();
return true;
}
///
public override bool MouseEvent (MouseEvent me)
{
if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) || !CanFocus)
return false;
SetFocus ();
var previousChecked = Checked;
Checked = !Checked;
OnToggled (previousChecked);
SetNeedsDisplay ();
return true;
}
///
public override bool OnEnter (View view)
{
Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
return base.OnEnter (view);
}
}
}