Files
Terminal.Gui/UICatalog/Scenarios/LabelsAsButtons.cs
BDisp 713b2c4725 Fixes #92. Remove dependency on ustring. (#2620)
* Remove NStack and replace ustring to string.

* Add unit test and improving some code.

* Adjust code and fix all unit tests errors.

* Add XML Document and move the Rune folder into the Text folder.

* Improve unit tests with byte array on DecodeRune and DecodeLastRune.

* Fix unit test.

* 😂Code review

* Reduce unit tests code.

* Change StringExtensions.Make to StringExtensions.ToString and added some more unit tests.

* Fix merge errors.

* Remove GetTextWidth and calls replaced with StringExtensions.GetColumns.

* Hack to use UseSystemConsole passed in the command line arguments.

* Revert "Hack to use UseSystemConsole passed in the command line arguments."

This reverts commit b74d11c786.

* Remove Application.UseSystemConsole from the config file.

* Fix errors related by removing UseSystemConsole from the config file.

* Fixes #2633. DecodeEscSeq throw an exception if cki is null.

* Fix an exception if SelectedItem is -1.

* Set SelectedItem to 0 and remove unnecessary ToString.

* Using a unique ToString method for Rune and other for byte.

* Fix a bug where a wider rune is added with only a width of 1.

* Force the SelectedGlyph is the one that was typed after jumpList is executed.

* Added more InlineData to RuneTests.

* Reducing significantly the code by using Theory attribute in the TextFormatterTests.

* Override PositionCursor to handle the CharMap cursor position.

* Fix merge errors.

* Minor tweaks to API docs

---------

Co-authored-by: Tig Kindel <tig@users.noreply.github.com>
2023-05-20 19:35:32 +02:00

312 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Labels As Buttons", Description: "Illustrates that Button is really just a Label++")]
[ScenarioCategory ("Controls")]
[ScenarioCategory ("Proof of Concept")]
public class LabelsAsLabels : Scenario {
public override void Setup ()
{
// Add a label & text field so we can demo IsDefault
var editLabel = new Label ("TextField (to demo IsDefault):") {
X = 0,
Y = 0,
};
Win.Add (editLabel);
// Add a TextField using Absolute layout.
var edit = new TextField (31, 0, 15, "");
Win.Add (edit);
// This is the default Label (IsDefault = true); if user presses ENTER in the TextField
// the scenario will quit
var defaultLabel = new Label ("_Quit") {
X = Pos.Center (),
//TODO: Change to use Pos.AnchorEnd()
Y = Pos.Bottom (Win) - 3,
//IsDefault = true,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
defaultLabel.Clicked += (s,e) => Application.RequestStop ();
Win.Add (defaultLabel);
var swapLabel = new Label (50, 0, "S_wap Default (Absolute Layout)") {
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
swapLabel.Clicked += (s,e) => {
//defaultLabel.IsDefault = !defaultLabel.IsDefault;
//swapLabel.IsDefault = !swapLabel.IsDefault;
};
Win.Add (swapLabel);
static void DoMessage (Label Label, string txt)
{
Label.Clicked += (s,e) => {
var btnText = Label.Text.ToString ();
MessageBox.Query ("Message", $"Did you click {txt}?", "Yes", "No");
};
}
var colorLabelsLabel = new Label ("Color Labels:") {
X = 0,
Y = Pos.Bottom (editLabel) + 1,
};
Win.Add (colorLabelsLabel);
//With this method there is no need to call Application.TopReady += () => Application.TopRedraw (Top.Bounds);
var x = Pos.Right (colorLabelsLabel) + 2;
foreach (var colorScheme in Colors.ColorSchemes) {
var colorLabel = new Label ($"{colorScheme.Key}") {
ColorScheme = colorScheme.Value,
X = x,
Y = Pos.Y (colorLabelsLabel),
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
DoMessage (colorLabel, colorLabel.Text);
Win.Add (colorLabel);
x += colorLabel.Text.Length + 2;
}
Application.Top.Ready += (s,e) => Application.Top.Draw ();
Label Label;
Win.Add (Label = new Label ("A super long _Label that will probably expose a bug in clipping or wrapping of text. Will it?") {
X = 2,
Y = Pos.Bottom (colorLabelsLabel) + 1,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
});
DoMessage (Label, Label.Text);
// Note the 'N' in 'Newline' will be the hotkey
Win.Add (Label = new Label ("a Newline\nin the Label") {
X = 2,
Y = Pos.Bottom (Label) + 1,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
TextAlignment = TextAlignment.Centered,
VerticalTextAlignment = VerticalTextAlignment.Middle
});
Label.Clicked += (s,e) => MessageBox.Query ("Message", "Question?", "Yes", "No");
var textChanger = new Label ("Te_xt Changer") {
X = 2,
Y = Pos.Bottom (Label) + 1,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
Win.Add (textChanger);
textChanger.Clicked += (s,e) => textChanger.Text += "!";
Win.Add (Label = new Label ("Lets see if this will move as \"Text Changer\" grows") {
X = Pos.Right (textChanger) + 2,
Y = Pos.Y (textChanger),
HotKeySpecifier = (Rune)'_',
CanFocus = true,
});
var removeLabel = new Label ("Remove this Label") {
X = 2,
Y = Pos.Bottom (Label) + 1,
ColorScheme = Colors.Error,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
Win.Add (removeLabel);
// This in interesting test case because `moveBtn` and below are laid out relative to this one!
removeLabel.Clicked += (s,e) => {
// Now this throw a InvalidOperationException on the TopologicalSort method as is expected.
//Win.Remove (removeLabel);
removeLabel.Visible = false;
Win.SetNeedsDisplay ();
};
var computedFrame = new FrameView ("Computed Layout") {
X = 0,
Y = Pos.Bottom (removeLabel) + 1,
Width = Dim.Percent (50),
Height = 5
};
Win.Add (computedFrame);
// Demonstrates how changing the View.Frame property can move Views
var moveBtn = new Label ("Move This \u263b Label _via Pos") {
X = 0,
Y = Pos.Center () - 1,
Width = 30,
ColorScheme = Colors.Error,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
moveBtn.Clicked += (s,e) => {
moveBtn.X = moveBtn.Frame.X + 5;
// This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
//computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
};
computedFrame.Add (moveBtn);
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
var sizeBtn = new Label ("Size This \u263a Label _via Pos") {
//var sizeBtn = new Label ("Size This x Label _via Pos") {
X = 0,
Y = Pos.Center () + 1,
Width = 30,
ColorScheme = Colors.Error,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
AutoSize = false
};
sizeBtn.Clicked += (s,e) => {
sizeBtn.Width = sizeBtn.Frame.Width + 5;
//computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
};
computedFrame.Add (sizeBtn);
var absoluteFrame = new FrameView ("Absolute Layout") {
X = Pos.Right (computedFrame),
Y = Pos.Bottom (removeLabel) + 1,
Width = Dim.Fill (),
Height = 5
};
Win.Add (absoluteFrame);
// Demonstrates how changing the View.Frame property can move Views
var moveBtnA = new Label (0, 0, "Move This Label via Frame") {
ColorScheme = Colors.Error,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
moveBtnA.Clicked += (s,e) => {
moveBtnA.Frame = new Rect (moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height);
};
absoluteFrame.Add (moveBtnA);
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
var sizeBtnA = new Label (0, 2, " ~  s  gui.cs   master ↑10 = Со_хранить") {
ColorScheme = Colors.Error,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
AutoSize = false
};
sizeBtnA.Clicked += (s,e) => {
sizeBtnA.Frame = new Rect (sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height);
};
absoluteFrame.Add (sizeBtnA);
var label = new Label ("Text Alignment (changes the four Labels above): ") {
X = 2,
Y = Pos.Bottom (computedFrame) + 1,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
Win.Add (label);
var radioGroup = new RadioGroup (new string [] { "Left", "Right", "Centered", "Justified" }) {
X = 4,
Y = Pos.Bottom (label) + 1,
SelectedItem = 2,
};
Win.Add (radioGroup);
// Demo changing hotkey
string MoveHotkey (string txt)
{
// Remove the '_'
var runes = txt.ToRuneList ();
var i = runes.IndexOf ((Rune)'_');
string start = "";
if (i > -1) {
start = StringExtensions.ToString (runes.GetRange (0, i));
}
txt = start + StringExtensions.ToString (runes.GetRange (i + 1, runes.Count - (i + 1)));
runes = txt.ToRuneList ();
// Move over one or go to start
i++;
if (i >= runes.Count) {
i = 0;
}
// Slip in the '_'
start = StringExtensions.ToString (runes.GetRange (0, i));
return start + '_' + StringExtensions.ToString (runes.GetRange (i, runes.Count - i));
}
var mhkb = "Click to Change th_is Label's Hotkey";
var moveHotKeyBtn = new Label (mhkb) {
X = 2,
Y = Pos.Bottom (radioGroup) + 1,
Width = Dim.Width (computedFrame) - 2,
ColorScheme = Colors.TopLevel,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
moveHotKeyBtn.Clicked += (s,e) => {
moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
};
Win.Add (moveHotKeyBtn);
string muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
var moveUnicodeHotKeyBtn = new Label (muhkb) {
X = Pos.Left (absoluteFrame) + 1,
Y = Pos.Bottom (radioGroup) + 1,
Width = Dim.Width (absoluteFrame) - 2,
ColorScheme = Colors.TopLevel,
HotKeySpecifier = (Rune)'_',
CanFocus = true,
};
moveUnicodeHotKeyBtn.Clicked += (s,e) => {
moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
};
Win.Add (moveUnicodeHotKeyBtn);
radioGroup.SelectedItemChanged += (s,args) => {
switch (args.SelectedItem) {
case 0:
moveBtn.TextAlignment = TextAlignment.Left;
sizeBtn.TextAlignment = TextAlignment.Left;
moveBtnA.TextAlignment = TextAlignment.Left;
sizeBtnA.TextAlignment = TextAlignment.Left;
moveHotKeyBtn.TextAlignment = TextAlignment.Left;
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
break;
case 1:
moveBtn.TextAlignment = TextAlignment.Right;
sizeBtn.TextAlignment = TextAlignment.Right;
moveBtnA.TextAlignment = TextAlignment.Right;
sizeBtnA.TextAlignment = TextAlignment.Right;
moveHotKeyBtn.TextAlignment = TextAlignment.Right;
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
break;
case 2:
moveBtn.TextAlignment = TextAlignment.Centered;
sizeBtn.TextAlignment = TextAlignment.Centered;
moveBtnA.TextAlignment = TextAlignment.Centered;
sizeBtnA.TextAlignment = TextAlignment.Centered;
moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
break;
case 3:
moveBtn.TextAlignment = TextAlignment.Justified;
sizeBtn.TextAlignment = TextAlignment.Justified;
moveBtnA.TextAlignment = TextAlignment.Justified;
sizeBtnA.TextAlignment = TextAlignment.Justified;
moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
break;
}
};
Application.Top.Ready += (s,e) => radioGroup.Refresh ();
}
}
}