enabled better characters

This commit is contained in:
Charlie Kindel
2020-06-07 15:12:25 -06:00
parent f888d4de25
commit dc878b899c
15 changed files with 227 additions and 118 deletions

View File

@@ -168,7 +168,7 @@ static class Demo {
passText,
new FrameView (new Rect (3, 10, 25, 6), "Options"){
new CheckBox (1, 0, "Remember me"),
new RadioGroup (1, 2, new [] { "_Personal", "_Company" }),
new RadioGroup (1, 2, new ustring [] { "_Personal", "_Company" }),
},
new ListView (new Rect (59, 6, 16, 4), new string [] {
"First row",

View File

@@ -531,6 +531,20 @@ namespace Terminal.Gui {
RightTee = Curses.ACS_RTEE;
TopTee = Curses.ACS_TTEE;
BottomTee = Curses.ACS_BTEE;
Checked = '\u221a';
UnChecked = ' ';
Selected = '\u25cf';
UnSelected = '\u25cc';
RightArrow = Curses.ACS_RARROW;
LeftArrow = Curses.ACS_LARROW;
UpArrow = Curses.ACS_UARROW;
DownArrow = Curses.ACS_DARROW;
LeftDefaultIndicator = '\u25e6';
RightDefaultIndicator = '\u25e6';
LeftBracket = '[';
RightBracket = ']';
OnMeterSegment = '\u258c';
OffMeterSegement = ' ';
Colors.TopLevel = new ColorScheme ();
Colors.Base = new ColorScheme ();

View File

@@ -164,6 +164,20 @@ namespace Terminal.Gui {
RightTee = '\u2524';
TopTee = '\u22a4';
BottomTee = '\u22a5';
Checked = '\u221a';
UnChecked = ' ';
Selected = '\u25cf';
UnSelected = '\u25cc';
RightArrow = '\u25ba';
LeftArrow = '\u25c4';
UpArrow = '\u25b2';
DownArrow = '\u25bc';
LeftDefaultIndicator = '\u25e6';
RightDefaultIndicator = '\u25e6';
LeftBracket = '[';
RightBracket = ']';
OnMeterSegment = '\u258c';
OffMeterSegement = ' ';
}
public override Attribute MakeAttribute (Color fore, Color back)

View File

@@ -497,6 +497,20 @@ namespace Terminal.Gui {
RightTee = '\u2524';
TopTee = '\u22a4';
BottomTee = '\u22a5';
Checked = '\u221a';
UnChecked = ' ';
Selected = '\u25cf';
UnSelected = '\u25cc';
RightArrow = '\u25ba';
LeftArrow = '\u25c4';
UpArrow = '\u25b2';
DownArrow = '\u25bc';
LeftDefaultIndicator = '\u25e6';
RightDefaultIndicator = '\u25e6';
LeftBracket = '[';
RightBracket = ']';
OnMeterSegment = '\u258c';
OffMeterSegement = ' ';
}
[StructLayout (LayoutKind.Sequential)]

View File

@@ -948,6 +948,40 @@ namespace Terminal.Gui {
/// </summary>
public Rune BottomTee;
/// <summary>
/// Checkmark.
/// </summary>
public Rune Checked;
/// <summary>
/// Un-checked checkmark.
/// </summary>
public Rune UnChecked;
/// <summary>
/// Selected mark.
/// </summary>
public Rune Selected;
/// <summary>
/// Un-selected selected mark.
/// </summary>
public Rune UnSelected;
public Rune RightArrow;
public Rune LeftArrow;
public Rune DownArrow;
public Rune UpArrow;
public Rune LeftDefaultIndicator;
public Rune RightDefaultIndicator;
public Rune LeftBracket;
public Rune RightBracket;
public Rune OnMeterSegment;
public Rune OffMeterSegement;
/// <summary>
/// Make the attribute for the foreground and background colors.
/// </summary>

View File

@@ -960,7 +960,7 @@ namespace Terminal.Gui {
Application.CurrentView = view;
// Clip the sub-view
var savedClip = ClipToBounds ();
var savedClip = view.ClipToBounds ();
// Draw the subview
// Use the view's bounds (view-relative; Location will always be (0,0) because

View File

@@ -329,7 +329,7 @@ namespace Terminal.Gui {
if (item == null)
Driver.AddRune (Driver.HLine);
else if (p == Frame.Width - 3 && barItems.Children [i].SubMenu != null)
Driver.AddRune ('>');
Driver.AddRune (Driver.RightArrow);
else
Driver.AddRune (' ');
@@ -340,20 +340,20 @@ namespace Terminal.Gui {
}
ustring textToDraw;
var checkChar = (char)0x25cf;
var uncheckedChar = (char)0x25cc;
var checkChar = Driver.Selected;
var uncheckedChar = Driver.UnSelected;
if (item.CheckType.HasFlag (MenuItemCheckStyle.Checked)) {
checkChar = (char)0x221a;
uncheckedChar = ' ';
checkChar = Driver.Checked;
uncheckedChar = Driver.UnChecked;
}
// Support Checked even though CHeckType wasn't set
if (item.Checked) {
textToDraw = checkChar + " " + item.Title;
textToDraw = ustring.Make(new Rune [] { checkChar, ' ' }) + item.Title;
} else if (item.CheckType.HasFlag (MenuItemCheckStyle.Checked) ||
item.CheckType.HasFlag (MenuItemCheckStyle.Radio)) {
textToDraw = uncheckedChar + " " + item.Title;
textToDraw = ustring.Make (new Rune [] { uncheckedChar, ' ' }) + item.Title;
} else {
textToDraw = item.Title;
}

View File

@@ -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,65 +10,44 @@ namespace Terminal.Gui {
public class RadioGroup : View {
int selected, cursor;
/// <summary>
/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> 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)
void Init(Rect rect, ustring [] radioLabels, int selected)
{
if (radioLabels == null) {
this.radioLabels = new List<ustring>();
} else {
this.radioLabels = radioLabels.ToList ();
}
this.selected = selected;
this.radioLabels = radioLabels;
SetWidthHeight (this.radioLabels);
CanFocus = true;
}
/// <summary>
/// The location of the cursor in the <see cref="RadioGroup"/>
/// </summary>
public int Cursor {
get => cursor;
set {
if (cursor < 0 || cursor >= radioLabels.Length)
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 [] { }) { }
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 (string [] radioLabels, int selected = 0) : base ()
public RadioGroup (ustring [] radioLabels, int selected = 0) : base ()
{
SetWidthHeight(radioLabels);
this.selected = selected;
this.radioLabels = radioLabels;
CanFocus = true;
Init (Rect.Empty, radioLabels, selected);
}
void SetWidthHeight(string[] radioLabels)
/// <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, ustring [] radioLabels, int selected = 0) : base (rect)
{
var r = MakeRect(0, 0, radioLabels);
Width = r.Width;
Height = radioLabels.Length;
}
static Rect MakeRect (int x, int y, string [] radioLabels)
{
int width = 0;
foreach (var s in radioLabels)
width = Math.Max (s.Length + 4, width);
return new Rect (x, y, width, radioLabels.Length);
Init (rect, radioLabels, selected);
}
/// <summary>
@@ -75,44 +58,89 @@ namespace Terminal.Gui {
/// <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) { }
public RadioGroup (int x, int y, ustring [] radioLabels, int selected = 0) :
this (MakeRect (x, y, radioLabels != null ? radioLabels.ToList() : null), radioLabels, selected) { }
string [] radioLabels;
/// <summary>
/// The location of the cursor in the <see cref="RadioGroup"/>
/// </summary>
public int Cursor {
get => cursor;
set {
if (cursor < 0 || cursor >= radioLabels.Count)
return;
cursor = value;
SetNeedsDisplay ();
}
}
void SetWidthHeight (List<ustring> radioLabels)
{
var r = MakeRect(0, 0, radioLabels);
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, 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 + 3, width);
return new Rect (x, y, width, radioLabels.Count);
}
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 ();
}

View File

@@ -156,9 +156,9 @@ namespace Terminal.Gui {
var by2 = (position + bh) * bh / Size;
Move (col, 0);
Driver.AddRune ('^');
Driver.AddRune (Driver.UpArrow);
Move (col, Bounds.Height - 1);
Driver.AddRune ('v');
Driver.AddRune (Driver.DownArrow);
for (int y = 0; y < bh; y++) {
Move (col, y + 1);
if (y < by1 - 1 || y > by2)
@@ -204,7 +204,7 @@ namespace Terminal.Gui {
var bx2 = (position + bw) * bw / Size;
Move (0, row);
Driver.AddRune ('<');
Driver.AddRune (Driver.LeftArrow);
for (int x = 0; x < bw; x++) {
@@ -224,7 +224,7 @@ namespace Terminal.Gui {
}
Driver.AddRune (special);
}
Driver.AddRune ('>');
Driver.AddRune (Driver.RightArrow);
}
}
}

View File

@@ -117,7 +117,7 @@ namespace UICatalog {
};
_settingsPane.Add (_computedCheckBox);
var radioItems = new [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" };
var radioItems = new ustring [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" };
_locationFrame = new FrameView ("Location (Pos)") {
X = Pos.Left (_computedCheckBox),
Y = Pos.Bottom (_computedCheckBox),
@@ -146,7 +146,7 @@ namespace UICatalog {
_locationFrame.Add (_xRadioGroup);
radioItems = new [] { "Percent(y)", "AnchorEnd(y)", "Center", "At(y)" };
radioItems = new ustring [] { "Percent(y)", "AnchorEnd(y)", "Center", "At(y)" };
label = new Label ("y:") { X = Pos.Right (_xRadioGroup) + 1, Y = 0 };
_locationFrame.Add (label);
_yText = new TextField ($"{_yVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 };
@@ -173,7 +173,7 @@ namespace UICatalog {
Width = 40,
};
radioItems = new [] { "Percent(width)", "Fill(width)", "Sized(width)" };
radioItems = new ustring [] { "Percent(width)", "Fill(width)", "Sized(width)" };
label = new Label ("width:") { X = 0, Y = 0 };
_sizeFrame.Add (label);
_wRadioGroup = new RadioGroup (radioItems) {
@@ -193,7 +193,7 @@ namespace UICatalog {
_sizeFrame.Add (_wText);
_sizeFrame.Add (_wRadioGroup);
radioItems = new [] { "Percent(height)", "Fill(height)", "Sized(height)" };
radioItems = new ustring [] { "Percent(height)", "Fill(height)", "Sized(height)" };
label = new Label ("height:") { X = Pos.Right (_wRadioGroup) + 1, Y = 0 };
_sizeFrame.Add (label);
_hText = new TextField ($"{_hVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 };

View File

@@ -111,7 +111,7 @@ namespace UICatalog {
Win.Add (computedFrame);
// Demonstrates how changing the View.Frame property can move Views
var moveBtn = new Button ("Move This Button via Pos") {
var moveBtn = new Button ("Move This \u263b Button _via Pos") {
X = 0,
Y = Pos.Center() - 1,
Width = 30,
@@ -124,7 +124,7 @@ namespace UICatalog {
computedFrame.Add (moveBtn);
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
var sizeBtn = new Button ("Size This Button via Pos") {
var sizeBtn = new Button ("Size This \u263a Button _via Pos") {
X = 0,
Y = Pos.Center () + 1,
Width = 30,
@@ -168,7 +168,7 @@ namespace UICatalog {
};
Win.Add (label);
var radioGroup = new RadioGroup (new [] { "Left", "Right", "Centered", "Justified" }) {
var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) {
X = 4,
Y = Pos.Bottom (label) + 1,
Selected = 2,

View File

@@ -1,5 +1,6 @@
using NStack;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Terminal.Gui;
@@ -26,36 +27,40 @@ namespace UICatalog {
};
Win.Add (charMap);
var label = new Label ("Jump To Unicode Block:") { X = Pos.Right (charMap) + 1, Y = Pos.Y (charMap) };
Win.Add (label);
Button CreateBlock (Window win, ustring title, int start, int end, View align)
(ustring radioLabel, int start, int end) CreateRadio (ustring title, int start, int end)
{
var button = new Button ($"{title} (U+{start:x5}-{end:x5})") {
X = Pos.X (align),
Y = Pos.Bottom (align),
Clicked = () => {
charMap.Start = start;
},
};
win.Add (button);
return button;
return ($"{title} (U+{start:x5}-{end:x5})", start, end);
}
var radioItems = new (ustring radioLabel, int start, int end) [] {
CreateRadio("Currency Symbols", 0x20A0, 0x20CF),
CreateRadio("Letterlike Symbols", 0x2100, 0x214F),
CreateRadio("Arrows", 0x2190, 0x21ff),
CreateRadio("Mathematical symbols", 0x2200, 0x22ff),
CreateRadio("Miscellaneous Technical", 0x2300, 0x23ff),
CreateRadio("Box Drawing & Geometric Shapes", 0x2500, 0x25ff),
CreateRadio("Miscellaneous Symbols", 0x2600, 0x26ff),
CreateRadio("Dingbats", 0x2700, 0x27ff),
CreateRadio("Braille", 0x2800, 0x28ff),
CreateRadio("Miscellaneous Symbols and Arrows", 0x2b00, 0x2bff),
CreateRadio("Alphabetic Presentation Forms", 0xFB00, 0xFb4f),
CreateRadio("Cuneiform Numbers and Punctuation", 0x12400, 0x1240f),
CreateRadio("Chess Symbols", 0x1FA00, 0x1FA0f),
CreateRadio("End", CharMap.MaxCodePointVal - 16, CharMap.MaxCodePointVal),
};
var label = new Label ("Unicode Blocks:") { X = Pos.Right (charMap) + 2, Y = Pos.Y (charMap) };
Win.Add (label);
var button = CreateBlock (Win, "Currency Symbols", 0x20A0, 0x20CF, label);
button = CreateBlock (Win, "Letterlike Symbols", 0x2100, 0x214F, button);
button = CreateBlock (Win, "Arrows", 0x2190, 0x21ff, button);
button = CreateBlock (Win, "Mathematical symbols", 0x2200, 0x22ff, button);
button = CreateBlock (Win, "Miscellaneous Technical", 0x2300, 0x23ff, button);
button = CreateBlock (Win, "Box Drawing & Geometric Shapes", 0x2500, 0x25ff, button);
button = CreateBlock (Win, "Miscellaneous Symbols", 0x2600, 0x26ff, button);
button = CreateBlock (Win, "Dingbats", 0x2700, 0x27ff, button);
button = CreateBlock (Win, "Braille", 0x2800, 0x28ff, button);
button = CreateBlock (Win, "Miscellaneous Symbols and Arrows", 0x2b00, 0x2bff, button);
button = CreateBlock (Win, "Alphabetic Presentation Forms", 0xFB00, 0xFb4f, button);
button = CreateBlock (Win, "Cuneiform Numbers and Punctuation[1", 0x12400, 0x1240f, button);
button = CreateBlock (Win, "Chess Symbols", 0x1FA00, 0x1FA0f, button);
button = CreateBlock (Win, "End", CharMap.MaxCodePointVal - 16, CharMap.MaxCodePointVal, button);
var jumpList = new RadioGroup (radioItems.Select (t => t.radioLabel).ToArray ());
jumpList.X = Pos.X (label);
jumpList.Y = Pos.Bottom (label);
jumpList.Width = Dim.Fill ();
jumpList.SelectedItemChanged = (selected) => {
charMap.Start = radioItems[selected].start;
};
Win.Add (jumpList);
}
}
@@ -70,7 +75,6 @@ namespace UICatalog {
set {
_start = value;
ContentOffset = new Point (0, _start / 16);
SetNeedsDisplay ();
}
}
@@ -80,7 +84,7 @@ namespace UICatalog {
// Row Header + space + (space + char + space)
public static int RowHeaderWidth => $"U+{MaxCodePointVal:x5}".Length;
public static int RowWidth => RowHeaderWidth + 1 + (" c ".Length * 16);
public static int RowWidth => RowHeaderWidth + (" c".Length * 16);
public CharMap ()
{
@@ -102,7 +106,7 @@ namespace UICatalog {
private void CharMap_DrawContent (Rect viewport)
{
for (int header = 0; header < 16; header++) {
Move (viewport.X + RowHeaderWidth + 1 + (header * 3), 0);
Move (viewport.X + RowHeaderWidth + (header * 2), 0);
Driver.AddStr ($" {header:x} ");
}
for (int row = 0, y = 0; row < viewport.Height / 2 - 1; row++, y += 2) {
@@ -112,8 +116,8 @@ namespace UICatalog {
Move (0, y + 1);
Driver.AddStr (rowLabel);
for (int col = 0; col < 16; col++) {
Move (viewport.X + RowHeaderWidth + 1 + (col * 3), 0 + y + 1);
Driver.AddStr ($" {(char)((-viewport.Y + row) * 16 + col)} ");
Move (viewport.X + RowHeaderWidth + (col * 2), 0 + y + 1);
Driver.AddStr ($" {(char)((-viewport.Y + row) * 16 + col)}");
}
}
}

View File

@@ -118,7 +118,7 @@ namespace UICatalog {
TextAlignment = Terminal.Gui.TextAlignment.Right,
};
frame.Add (label);
var styleRadioGroup = new RadioGroup (new [] { "_Query", "_Error" } ) {
var styleRadioGroup = new RadioGroup (new ustring [] { "_Query", "_Error" } ) {
X = Pos.Right (label) + 1,
Y = Pos.Top (label),
};

View File

@@ -69,7 +69,7 @@ namespace UICatalog {
label = new Label ("RadioGroup:") { X = Pos.X (label), Y = Pos.Bottom (listView) + 1 };
Win.Add (label);
var radioGroup = new RadioGroup (new [] { "item #1", " ~  s  gui.cs   master ↑10", "Со_хранить" }, selected: 0) {
var radioGroup = new RadioGroup (new ustring [] { "item #1", " ~  s  gui.cs   master ↑10", "Со_хранить" }, selected: 0) {
X = 15,
Y = Pos.Y (label),
Width = Dim.Percent (60),

View File

@@ -5,6 +5,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<StartupObject>UICatalog.UICatalogApp</StartupObject>
<AssemblyVersion>1.0.0.1</AssemblyVersion>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>