Browse Source

enabled better characters

Charlie Kindel 5 years ago
parent
commit
dc878b899c

+ 1 - 1
Example/demo.cs

@@ -168,7 +168,7 @@ static class Demo {
 			passText,
 			passText,
 			new FrameView (new Rect (3, 10, 25, 6), "Options"){
 			new FrameView (new Rect (3, 10, 25, 6), "Options"){
 				new CheckBox (1, 0, "Remember me"),
 				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 [] {
 			new ListView (new Rect (59, 6, 16, 4), new string [] {
 				"First row",
 				"First row",

+ 14 - 0
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -531,6 +531,20 @@ namespace Terminal.Gui {
 			RightTee = Curses.ACS_RTEE;
 			RightTee = Curses.ACS_RTEE;
 			TopTee = Curses.ACS_TTEE;
 			TopTee = Curses.ACS_TTEE;
 			BottomTee = Curses.ACS_BTEE;
 			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.TopLevel = new ColorScheme ();
 			Colors.Base = new ColorScheme ();
 			Colors.Base = new ColorScheme ();

+ 14 - 0
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -164,6 +164,20 @@ namespace Terminal.Gui {
 			RightTee = '\u2524';
 			RightTee = '\u2524';
 			TopTee = '\u22a4';
 			TopTee = '\u22a4';
 			BottomTee = '\u22a5';
 			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)
 		public override Attribute MakeAttribute (Color fore, Color back)

+ 14 - 0
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -497,6 +497,20 @@ namespace Terminal.Gui {
 			RightTee = '\u2524';
 			RightTee = '\u2524';
 			TopTee = '\u22a4';
 			TopTee = '\u22a4';
 			BottomTee = '\u22a5';
 			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)]
 		[StructLayout (LayoutKind.Sequential)]

+ 34 - 0
Terminal.Gui/Core/ConsoleDriver.cs

@@ -948,6 +948,40 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// </summary>
 		public Rune BottomTee;
 		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>
 		/// <summary>
 		/// Make the attribute for the foreground and background colors.
 		/// Make the attribute for the foreground and background colors.
 		/// </summary>
 		/// </summary>

+ 1 - 1
Terminal.Gui/Core/View.cs

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

+ 7 - 7
Terminal.Gui/Views/Menu.cs

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

+ 91 - 63
Terminal.Gui/Views/RadioGroup.cs

@@ -1,4 +1,8 @@
-using System;
+using NStack;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
 namespace Terminal.Gui {
 namespace Terminal.Gui {
 	/// <summary>
 	/// <summary>
 	/// <see cref="RadioGroup"/> shows a group of radio labels, only one of those can be selected at a given time
 	/// <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 {
 	public class RadioGroup : View {
 		int selected, cursor;
 		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>
 		/// <summary>
 		/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// Initializes a new instance of the <see cref="RadioGroup"/> class using <see cref="LayoutStyle.Computed"/> layout.
 		/// </summary>
 		/// </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="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="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>
 		/// <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>
 		/// <summary>
 		/// The location of the cursor in the <see cref="RadioGroup"/>
 		/// The location of the cursor in the <see cref="RadioGroup"/>
 		/// </summary>
 		/// </summary>
 		public int Cursor {
 		public int Cursor {
 			get => cursor;
 			get => cursor;
 			set {
 			set {
-				if (cursor < 0 || cursor >= radioLabels.Length)
+				if (cursor < 0 || cursor >= radioLabels.Count)
 					return;
 					return;
 				cursor = value;
 				cursor = value;
 				SetNeedsDisplay ();
 				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);
 			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;
 			int width = 0;
 
 
+			if (radioLabels == null) {
+				return new Rect (x, y, width, 0);
+			}
+
 			foreach (var s in radioLabels)
 			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>
 		/// <summary>
 		/// The radio labels to display
 		/// The radio labels to display
 		/// </summary>
 		/// </summary>
 		/// <value>The radio labels.</value>
 		/// <value>The radio labels.</value>
-		public string [] RadioLabels { 
-			get => radioLabels;
+		public ustring [] RadioLabels { 
+			get => radioLabels.ToArray();
 			set {
 			set {
-				Update(value);
-				radioLabels = value;
-				selected = 0;
+				var prevCount = radioLabels.Count;
+				radioLabels = value.ToList ();
+				if (prevCount != radioLabels.Count) {
+					SetWidthHeight (radioLabels);
+				}
+				Selected = 0;
 				cursor = 0;
 				cursor = 0;
 				SetNeedsDisplay ();
 				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/>
 		///<inheritdoc/>
 		public override void Redraw (Rect bounds)
 		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);
 				Move (0, i);
 				Driver.SetAttribute (ColorScheme.Normal);
 				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);
 				DrawHotString (radioLabels [i], HasFocus && i == cursor, ColorScheme);
 			}
 			}
 			base.Redraw (bounds);
 			base.Redraw (bounds);
@@ -121,11 +149,11 @@ namespace Terminal.Gui {
 		///<inheritdoc/>
 		///<inheritdoc/>
 		public override void PositionCursor ()
 		public override void PositionCursor ()
 		{
 		{
-			Move (1, cursor);
+			Move (0, cursor);
 		}
 		}
 
 
 		/// <summary>
 		/// <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>
 		/// </summary>
 		public Action<int> SelectedItemChanged;
 		public Action<int> SelectedItemChanged;
 
 
@@ -183,7 +211,7 @@ namespace Terminal.Gui {
 				}
 				}
 				break;
 				break;
 			case Key.CursorDown:
 			case Key.CursorDown:
-				if (cursor + 1 < radioLabels.Length) {
+				if (cursor + 1 < radioLabels.Count) {
 					cursor++;
 					cursor++;
 					SetNeedsDisplay ();
 					SetNeedsDisplay ();
 					return true;
 					return true;
@@ -204,7 +232,7 @@ namespace Terminal.Gui {
 
 
 			SuperView.SetFocus (this);
 			SuperView.SetFocus (this);
 
 
-			if (me.Y < radioLabels.Length) {
+			if (me.Y < radioLabels.Count) {
 				cursor = Selected = me.Y;
 				cursor = Selected = me.Y;
 				SetNeedsDisplay ();
 				SetNeedsDisplay ();
 			}
 			}

+ 4 - 4
Terminal.Gui/Views/ScrollView.cs

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

+ 4 - 4
UICatalog/Scenarios/AllViewsTester.cs

@@ -117,7 +117,7 @@ namespace UICatalog {
 			};
 			};
 			_settingsPane.Add (_computedCheckBox);
 			_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)") {
 			_locationFrame = new FrameView ("Location (Pos)") {
 				X = Pos.Left (_computedCheckBox),
 				X = Pos.Left (_computedCheckBox),
 				Y = Pos.Bottom (_computedCheckBox),
 				Y = Pos.Bottom (_computedCheckBox),
@@ -146,7 +146,7 @@ namespace UICatalog {
 
 
 			_locationFrame.Add (_xRadioGroup);
 			_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 };
 			label = new Label ("y:") { X = Pos.Right (_xRadioGroup) + 1, Y = 0 };
 			_locationFrame.Add (label);
 			_locationFrame.Add (label);
 			_yText = new TextField ($"{_yVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 };
 			_yText = new TextField ($"{_yVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 };
@@ -173,7 +173,7 @@ namespace UICatalog {
 				Width = 40,
 				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 };
 			label = new Label ("width:") { X = 0, Y = 0 };
 			_sizeFrame.Add (label);
 			_sizeFrame.Add (label);
 			_wRadioGroup = new RadioGroup (radioItems) {
 			_wRadioGroup = new RadioGroup (radioItems) {
@@ -193,7 +193,7 @@ namespace UICatalog {
 			_sizeFrame.Add (_wText);
 			_sizeFrame.Add (_wText);
 			_sizeFrame.Add (_wRadioGroup);
 			_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 };
 			label = new Label ("height:") { X = Pos.Right (_wRadioGroup) + 1, Y = 0 };
 			_sizeFrame.Add (label);
 			_sizeFrame.Add (label);
 			_hText = new TextField ($"{_hVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 };
 			_hText = new TextField ($"{_hVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 };

+ 3 - 3
UICatalog/Scenarios/Buttons.cs

@@ -111,7 +111,7 @@ namespace UICatalog {
 			Win.Add (computedFrame);
 			Win.Add (computedFrame);
 
 
 			// Demonstrates how changing the View.Frame property can move Views
 			// 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,
 				X = 0,
 				Y = Pos.Center() - 1,
 				Y = Pos.Center() - 1,
 				Width = 30,
 				Width = 30,
@@ -124,7 +124,7 @@ namespace UICatalog {
 			computedFrame.Add (moveBtn);
 			computedFrame.Add (moveBtn);
 
 
 			// Demonstrates how changing the View.Frame property can SIZE Views (#583)
 			// 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,
 				X = 0,
 				Y = Pos.Center () + 1,
 				Y = Pos.Center () + 1,
 				Width = 30,
 				Width = 30,
@@ -168,7 +168,7 @@ namespace UICatalog {
 			};
 			};
 			Win.Add (label);
 			Win.Add (label);
 
 
-			var radioGroup = new RadioGroup (new [] { "Left", "Right", "Centered", "Justified" }) {
+			var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) {
 				X = 4,
 				X = 4,
 				Y = Pos.Bottom (label) + 1,
 				Y = Pos.Bottom (label) + 1,
 				Selected = 2,
 				Selected = 2,

+ 35 - 31
UICatalog/Scenarios/CharacterMap.cs

@@ -1,5 +1,6 @@
 using NStack;
 using NStack;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 using System.Text;
 using Terminal.Gui;
 using Terminal.Gui;
 
 
@@ -26,36 +27,40 @@ namespace UICatalog {
 			};
 			};
 
 
 			Win.Add (charMap);
 			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 {
 			set {
 				_start = value;
 				_start = value;
 				ContentOffset = new Point (0, _start / 16);
 				ContentOffset = new Point (0, _start / 16);
-
 				SetNeedsDisplay ();
 				SetNeedsDisplay ();
 			}
 			}
 		}
 		}
@@ -80,7 +84,7 @@ namespace UICatalog {
 
 
 		// Row Header + space + (space + char + space)
 		// Row Header + space + (space + char + space)
 		public static int RowHeaderWidth => $"U+{MaxCodePointVal:x5}".Length;
 		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 ()
 		public CharMap ()
 		{
 		{
@@ -102,7 +106,7 @@ namespace UICatalog {
 		private void CharMap_DrawContent (Rect viewport)
 		private void CharMap_DrawContent (Rect viewport)
 		{
 		{
 			for (int header = 0; header < 16; header++) {
 			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} ");
 				Driver.AddStr ($" {header:x} ");
 			}
 			}
 			for (int row = 0, y = 0; row < viewport.Height / 2 - 1; row++, y += 2) {
 			for (int row = 0, y = 0; row < viewport.Height / 2 - 1; row++, y += 2) {
@@ -112,8 +116,8 @@ namespace UICatalog {
 					Move (0, y + 1);
 					Move (0, y + 1);
 					Driver.AddStr (rowLabel);
 					Driver.AddStr (rowLabel);
 					for (int col = 0; col < 16; col++) {
 					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)}");
 					}
 					}
 				}
 				}
 			}
 			}

+ 1 - 1
UICatalog/Scenarios/MessageBoxes.cs

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

+ 1 - 1
UICatalog/Scenarios/Unicode.cs

@@ -69,7 +69,7 @@ namespace UICatalog {
 
 
 			label = new Label ("RadioGroup:") { X = Pos.X (label), Y = Pos.Bottom (listView) + 1 };
 			label = new Label ("RadioGroup:") { X = Pos.X (label), Y = Pos.Bottom (listView) + 1 };
 			Win.Add (label);
 			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,
 				X = 15,
 				Y = Pos.Y (label),
 				Y = Pos.Y (label),
 				Width = Dim.Percent (60),
 				Width = Dim.Percent (60),

+ 1 - 0
UICatalog/UICatalog.csproj

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