|
@@ -1,4 +1,8 @@
|
|
|
-using System;
|
|
|
+using NStack;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+
|
|
|
namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// <see cref="RadioGroup"/> shows a group of radio labels, only one of those can be selected at a given time
|
|
@@ -6,113 +10,137 @@ namespace Terminal.Gui {
|
|
|
public class RadioGroup : View {
|
|
|
int selected, cursor;
|
|
|
|
|
|
+ void Init(Rect rect, ustring [] radioLabels, int selected)
|
|
|
+ {
|
|
|
+ if (radioLabels == null) {
|
|
|
+ this.radioLabels = new List<ustring>();
|
|
|
+ } else {
|
|
|
+ this.radioLabels = radioLabels.ToList ();
|
|
|
+ }
|
|
|
+
|
|
|
+ this.selected = selected;
|
|
|
+ SetWidthHeight (this.radioLabels);
|
|
|
+ CanFocus = true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
|
|
|
/// </summary>
|
|
|
+ public RadioGroup () : this (radioLabels: new ustring [] { }) { }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
|
|
|
+ /// <param name="selected">The index of the item to be selected, the value is clamped to the number of items.</param>
|
|
|
+ public RadioGroup (ustring [] radioLabels, int selected = 0) : base ()
|
|
|
+ {
|
|
|
+ Init (Rect.Empty, radioLabels, selected);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Absolute"/> layout.
|
|
|
+ /// </summary>
|
|
|
/// <param name="rect">Boundaries for the radio group.</param>
|
|
|
/// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
|
|
|
/// <param name="selected">The index of item to be selected, the value is clamped to the number of items.</param>
|
|
|
- public RadioGroup (Rect rect, string [] radioLabels, int selected = 0) : base (rect)
|
|
|
+ public RadioGroup (Rect rect, ustring [] radioLabels, int selected = 0) : base (rect)
|
|
|
{
|
|
|
- this.selected = selected;
|
|
|
- this.radioLabels = radioLabels;
|
|
|
- CanFocus = true;
|
|
|
+ Init (rect, radioLabels, selected);
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Absolute"/> layout.
|
|
|
+ /// The <see cref="View"/> frame is computed from the provided radio labels.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="x">The x coordinate.</param>
|
|
|
+ /// <param name="y">The y coordinate.</param>
|
|
|
+ /// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
|
|
|
+ /// <param name="selected">The item to be selected, the value is clamped to the number of items.</param>
|
|
|
+ public RadioGroup (int x, int y, ustring [] radioLabels, int selected = 0) :
|
|
|
+ this (MakeRect (x, y, radioLabels != null ? radioLabels.ToList() : null), radioLabels, selected) { }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// The location of the cursor in the <see cref="RadioGroup"/>
|
|
|
/// </summary>
|
|
|
public int Cursor {
|
|
|
get => cursor;
|
|
|
set {
|
|
|
- if (cursor < 0 || cursor >= radioLabels.Length)
|
|
|
+ if (cursor < 0 || cursor >= radioLabels.Count)
|
|
|
return;
|
|
|
cursor = value;
|
|
|
SetNeedsDisplay ();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
|
|
|
- /// </summary>
|
|
|
- public RadioGroup () : this (radioLabels: new string [] { }) { }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
|
|
|
- /// </summary>
|
|
|
- /// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
|
|
|
- /// <param name="selected">The index of the item to be selected, the value is clamped to the number of items.</param>
|
|
|
- public RadioGroup (string [] radioLabels, int selected = 0) : base ()
|
|
|
- {
|
|
|
- SetWidthHeight(radioLabels);
|
|
|
-
|
|
|
- this.selected = selected;
|
|
|
- this.radioLabels = radioLabels;
|
|
|
- CanFocus = true;
|
|
|
- }
|
|
|
-
|
|
|
- void SetWidthHeight(string[] radioLabels)
|
|
|
+ void SetWidthHeight (List<ustring> radioLabels)
|
|
|
{
|
|
|
var r = MakeRect(0, 0, radioLabels);
|
|
|
- Width = r.Width;
|
|
|
- Height = radioLabels.Length;
|
|
|
+ if (LayoutStyle == LayoutStyle.Computed) {
|
|
|
+ Width = r.Width;
|
|
|
+ Height = radioLabels.Count;
|
|
|
+ } else {
|
|
|
+ Frame = new Rect (Frame.Location, new Size (r.Width, radioLabels.Count));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- static Rect MakeRect (int x, int y, string [] radioLabels)
|
|
|
+ static Rect MakeRect (int x, int y, List<ustring> radioLabels)
|
|
|
{
|
|
|
int width = 0;
|
|
|
|
|
|
+ if (radioLabels == null) {
|
|
|
+ return new Rect (x, y, width, 0);
|
|
|
+ }
|
|
|
+
|
|
|
foreach (var s in radioLabels)
|
|
|
- width = Math.Max (s.Length + 4, width);
|
|
|
- return new Rect (x, y, width, radioLabels.Length);
|
|
|
+ width = Math.Max (s.Length + 3, width);
|
|
|
+ return new Rect (x, y, width, radioLabels.Count);
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Absolute"/> layout.
|
|
|
- /// The <see cref="View"/> frame is computed from the provided radio labels.
|
|
|
- /// </summary>
|
|
|
- /// <param name="x">The x coordinate.</param>
|
|
|
- /// <param name="y">The y coordinate.</param>
|
|
|
- /// <param name="radioLabels">The radio labels; an array of strings that can contain hotkeys using an underscore before the letter.</param>
|
|
|
- /// <param name="selected">The item to be selected, the value is clamped to the number of items.</param>
|
|
|
- public RadioGroup (int x, int y, string [] radioLabels, int selected = 0) : this (MakeRect (x, y, radioLabels), radioLabels, selected) { }
|
|
|
|
|
|
- string [] radioLabels;
|
|
|
+ List<ustring> radioLabels = new List<ustring> ();
|
|
|
|
|
|
/// <summary>
|
|
|
/// The radio labels to display
|
|
|
/// </summary>
|
|
|
/// <value>The radio labels.</value>
|
|
|
- public string [] RadioLabels {
|
|
|
- get => radioLabels;
|
|
|
+ public ustring [] RadioLabels {
|
|
|
+ get => radioLabels.ToArray();
|
|
|
set {
|
|
|
- Update(value);
|
|
|
- radioLabels = value;
|
|
|
- selected = 0;
|
|
|
+ var prevCount = radioLabels.Count;
|
|
|
+ radioLabels = value.ToList ();
|
|
|
+ if (prevCount != radioLabels.Count) {
|
|
|
+ SetWidthHeight (radioLabels);
|
|
|
+ }
|
|
|
+ Selected = 0;
|
|
|
cursor = 0;
|
|
|
SetNeedsDisplay ();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- void Update(string [] newRadioLabels)
|
|
|
- {
|
|
|
- for (int i = 0; i < radioLabels.Length; i++) {
|
|
|
- Move(0, i);
|
|
|
- Driver.SetAttribute(ColorScheme.Normal);
|
|
|
- Driver.AddStr(new string(' ', radioLabels[i].Length + 4));
|
|
|
- }
|
|
|
- if (newRadioLabels.Length != radioLabels.Length) {
|
|
|
- SetWidthHeight(newRadioLabels);
|
|
|
- }
|
|
|
- }
|
|
|
+ //// Redraws the RadioGroup
|
|
|
+ //void Update(List<ustring> newRadioLabels)
|
|
|
+ //{
|
|
|
+ // for (int i = 0; i < radioLabels.Count; i++) {
|
|
|
+ // Move(0, i);
|
|
|
+ // Driver.SetAttribute(ColorScheme.Normal);
|
|
|
+ // Driver.AddStr(ustring.Make(new string (' ', radioLabels[i].Length + 4)));
|
|
|
+ // }
|
|
|
+ // if (newRadioLabels.Count != radioLabels.Count) {
|
|
|
+ // SetWidthHeight(newRadioLabels);
|
|
|
+ // }
|
|
|
+ //}
|
|
|
|
|
|
///<inheritdoc/>
|
|
|
public override void Redraw (Rect bounds)
|
|
|
{
|
|
|
- for (int i = 0; i < radioLabels.Length; i++) {
|
|
|
+ Driver.SetAttribute (ColorScheme.Normal);
|
|
|
+ Clear ();
|
|
|
+ for (int i = 0; i < radioLabels.Count; i++) {
|
|
|
Move (0, i);
|
|
|
Driver.SetAttribute (ColorScheme.Normal);
|
|
|
- Driver.AddStr (i == selected ? "(o) " : "( ) ");
|
|
|
+ Driver.AddStr (ustring.Make(new Rune[] { (i == selected ? Driver.Selected : Driver.UnSelected), ' '}));
|
|
|
DrawHotString (radioLabels [i], HasFocus && i == cursor, ColorScheme);
|
|
|
}
|
|
|
base.Redraw (bounds);
|
|
@@ -121,11 +149,11 @@ namespace Terminal.Gui {
|
|
|
///<inheritdoc/>
|
|
|
public override void PositionCursor ()
|
|
|
{
|
|
|
- Move (1, cursor);
|
|
|
+ Move (0, cursor);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Invoked when the selected radio label has changed
|
|
|
+ /// Invoked when the selected radio label has changed. The passed <c>int</c> indicates the newly selected item.
|
|
|
/// </summary>
|
|
|
public Action<int> SelectedItemChanged;
|
|
|
|
|
@@ -183,7 +211,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
break;
|
|
|
case Key.CursorDown:
|
|
|
- if (cursor + 1 < radioLabels.Length) {
|
|
|
+ if (cursor + 1 < radioLabels.Count) {
|
|
|
cursor++;
|
|
|
SetNeedsDisplay ();
|
|
|
return true;
|
|
@@ -204,7 +232,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
SuperView.SetFocus (this);
|
|
|
|
|
|
- if (me.Y < radioLabels.Length) {
|
|
|
+ if (me.Y < radioLabels.Count) {
|
|
|
cursor = Selected = me.Y;
|
|
|
SetNeedsDisplay ();
|
|
|
}
|