From 713b2c4725f5283ebb23da48eccadec842b27661 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 20 May 2023 18:35:32 +0100 Subject: [PATCH] Fixes #92. Remove dependency on ustring. (#2620) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 b74d11c7864fa6e20d40ef5cbead89a42f81ee5e. * 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 --- ReactiveExample/LoginView.cs | 14 +- ReactiveExample/LoginViewModel.cs | 14 +- ReactiveExample/README.md | 2 +- Terminal.Gui/Application.cs | 7 +- Terminal.Gui/Clipboard/Clipboard.cs | 8 +- .../Configuration/RuneJsonConverter.cs | 17 +- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 37 +- .../CursesDriver/CursesDriver.cs | 20 +- .../ConsoleDrivers/FakeDriver/FakeDriver.cs | 24 +- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 27 +- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 26 +- Terminal.Gui/Drawing/Glyphs.cs | 248 +- Terminal.Gui/Drawing/LineCanvas.cs | 2 +- Terminal.Gui/Drawing/Ruler.cs | 5 +- Terminal.Gui/Drawing/Thickness.cs | 23 +- Terminal.Gui/Input/ShortcutHelper.cs | 27 +- Terminal.Gui/Resources/config.json | 1 - Terminal.Gui/StringExtensions.cs | 32 - Terminal.Gui/Terminal.Gui.csproj | 1 - .../Text/Autocomplete/AppendAutocomplete.cs | 40 +- .../Text/Autocomplete/AutocompleteContext.cs | 2 +- .../Text/Autocomplete/IAutocomplete.cs | 2 +- .../Text/Autocomplete/ISuggestionGenerator.cs | 2 +- .../Text/Autocomplete/PopupAutocomplete.cs | 4 +- .../SingleWordSuggestionGenerator.cs | 6 +- Terminal.Gui/Text/RuneExtensions.cs | 311 ++ Terminal.Gui/Text/StringExtensions.cs | 154 + Terminal.Gui/Text/TextFormatter.cs | 288 +- Terminal.Gui/View/Frame.cs | 20 +- Terminal.Gui/View/TitleEventArgs.cs | 8 +- Terminal.Gui/View/View.cs | 20 +- Terminal.Gui/View/ViewDrawing.cs | 16 +- Terminal.Gui/View/ViewKeyboard.cs | 4 +- Terminal.Gui/View/ViewLayout.cs | 6 +- Terminal.Gui/View/ViewMouse.cs | 2 +- Terminal.Gui/View/ViewSubViews.cs | 2 +- Terminal.Gui/View/ViewText.cs | 16 +- .../Views/AutocompleteFilepathContext.cs | 21 +- Terminal.Gui/Views/Button.cs | 21 +- Terminal.Gui/Views/CheckBox.cs | 26 +- Terminal.Gui/Views/ColorPicker.cs | 10 +- Terminal.Gui/Views/ComboBox.cs | 26 +- Terminal.Gui/Views/DateField.cs | 53 +- Terminal.Gui/Views/Dialog.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 14 +- Terminal.Gui/Views/FrameView.cs | 8 +- Terminal.Gui/Views/GraphView/Annotations.cs | 2 +- Terminal.Gui/Views/GraphView/Axis.cs | 3 +- .../Views/GraphView/GraphCellToRender.cs | 1 + Terminal.Gui/Views/GraphView/GraphView.cs | 4 +- Terminal.Gui/Views/GraphView/Series.cs | 1 + Terminal.Gui/Views/HexView.cs | 11 +- Terminal.Gui/Views/HistoryTextItem.cs | 2 +- Terminal.Gui/Views/Label.cs | 10 +- Terminal.Gui/Views/LineView.cs | 3 +- Terminal.Gui/Views/ListView.cs | 26 +- Terminal.Gui/Views/Menu.cs | 84 +- Terminal.Gui/Views/MessageBox.cs | 44 +- Terminal.Gui/Views/OpenDialog.cs | 4 +- Terminal.Gui/Views/ProgressBar.cs | 12 +- Terminal.Gui/Views/RadioGroup.cs | 30 +- Terminal.Gui/Views/SaveDialog.cs | 6 +- Terminal.Gui/Views/ScrollBarView.cs | 1 + Terminal.Gui/Views/StatusBar.cs | 24 +- Terminal.Gui/Views/TabView.cs | 12 +- .../TableView/CheckBoxTableSourceWrapper.cs | 1 + .../Views/TableView/ListTableSource.cs | 9 +- Terminal.Gui/Views/TableView/TableView.cs | 20 +- Terminal.Gui/Views/TextChangedEventArgs.cs | 6 +- Terminal.Gui/Views/TextChangingEventArgs.cs | 6 +- Terminal.Gui/Views/TextField.cs | 96 +- Terminal.Gui/Views/TextValidateField.cs | 48 +- Terminal.Gui/Views/TextView.cs | 205 +- Terminal.Gui/Views/TileView.cs | 8 +- Terminal.Gui/Views/TimeField.cs | 22 +- Terminal.Gui/Views/TreeView/Branch.cs | 25 +- Terminal.Gui/Views/TreeView/TreeStyle.cs | 1 + Terminal.Gui/Views/TreeView/TreeView.cs | 4 +- Terminal.Gui/Views/Window.cs | 2 +- Terminal.Gui/Views/Wizard/Wizard.cs | 26 +- UICatalog/Scenario.cs | 2 +- UICatalog/Scenarios/AllViewsTester.cs | 34 +- UICatalog/Scenarios/Animation.cs | 2 +- UICatalog/Scenarios/Buttons.cs | 22 +- UICatalog/Scenarios/CharacterMap.cs | 92 +- UICatalog/Scenarios/ComputedLayout.cs | 4 +- UICatalog/Scenarios/CsvEditor.cs | 4 +- UICatalog/Scenarios/Dialogs.cs | 4 +- UICatalog/Scenarios/DynamicMenuBar.cs | 53 +- UICatalog/Scenarios/DynamicStatusBar.cs | 41 +- UICatalog/Scenarios/Editor.cs | 66 +- UICatalog/Scenarios/FileDialogExamples.cs | 150 +- UICatalog/Scenarios/Frames.cs | 11 +- UICatalog/Scenarios/GraphViewExample.cs | 13 +- UICatalog/Scenarios/Keys.cs | 2 +- UICatalog/Scenarios/LabelsAsButtons.cs | 52 +- UICatalog/Scenarios/LineDrawing.cs | 6 +- UICatalog/Scenarios/LineViewExample.cs | 6 +- UICatalog/Scenarios/ListViewWithSelection.cs | 10 +- UICatalog/Scenarios/ListsAndCombos.cs | 6 +- UICatalog/Scenarios/MessageBoxes.cs | 7 +- UICatalog/Scenarios/MultiColouredTable.cs | 47 +- UICatalog/Scenarios/Progress.cs | 2 +- UICatalog/Scenarios/ProgressBarStyles.cs | 2 +- UICatalog/Scenarios/Scrolling.cs | 13 +- UICatalog/Scenarios/Snake.cs | 1 + UICatalog/Scenarios/SpinnerStyles.cs | 2 +- UICatalog/Scenarios/SyntaxHighlighting.cs | 13 +- UICatalog/Scenarios/TableEditor.cs | 3 +- UICatalog/Scenarios/Text.cs | 3 +- UICatalog/Scenarios/TextAlignments.cs | 1 + .../Scenarios/TextAlignmentsAndDirection.cs | 5 +- UICatalog/Scenarios/TextFormatterDemo.cs | 7 +- UICatalog/Scenarios/TreeViewFileSystem.cs | 19 +- UICatalog/Scenarios/Unicode.cs | 7 +- UICatalog/Scenarios/WizardAsView.cs | 3 +- UICatalog/Scenarios/Wizards.cs | 9 +- UICatalog/UICatalog.cs | 3 +- .../Configuration/ConfigurationMangerTests.cs | 13 +- UnitTests/Configuration/SettingsScopeTests.cs | 6 - UnitTests/Dialogs/DialogTests.cs | 10 +- UnitTests/Dialogs/WizardTests.cs | 6 +- UnitTests/Drawing/LineCanvasTests.cs | 5 +- UnitTests/Drawing/RulerTests.cs | 2 +- UnitTests/Drawing/StraightLineTests.cs | 3 +- UnitTests/Drawing/ThicknessTests.cs | 10 +- UnitTests/TestHelpers.cs | 43 +- UnitTests/Text/RuneTests.cs | 714 +++ UnitTests/Text/StringTests.cs | 70 + UnitTests/Text/TextFormatterTests.cs | 4492 ++++------------- UnitTests/Text/UnicodeTests.cs | 89 +- UnitTests/UICatalog/ScenarioTests.cs | 18 +- UnitTests/View/DrawTests.cs | 24 +- UnitTests/View/FrameTests.cs | 2 +- UnitTests/View/KeyboardTests.cs | 4 +- UnitTests/View/Layout/AbsoluteLayoutTests.cs | 2 +- UnitTests/View/Layout/AutoSizeTests.cs | 28 +- UnitTests/View/Layout/DimTests.cs | 2 +- UnitTests/View/Layout/LayoutTests.cs | 5 +- UnitTests/View/NavigationTests.cs | 2 +- UnitTests/View/TitleTests.cs | 6 +- UnitTests/View/ViewTests.cs | 10 +- UnitTests/Views/AllViewsTests.cs | 4 +- UnitTests/Views/ButtonTests.cs | 16 +- UnitTests/Views/GraphViewTests.cs | 32 +- UnitTests/Views/LabelTests.cs | 6 +- UnitTests/Views/ListViewTests.cs | 2 +- UnitTests/Views/MenuTests.cs | 20 +- UnitTests/Views/ProgressBarTests.cs | 642 +-- UnitTests/Views/RadioGroupTests.cs | 16 +- UnitTests/Views/ScrollViewTests.cs | 4 +- UnitTests/Views/TableViewTests.cs | 4 +- UnitTests/Views/TextFieldTests.cs | 226 +- UnitTests/Views/TextViewTests.cs | 52 +- UnitTests/Views/WindowTests.cs | 4 +- 155 files changed, 4173 insertions(+), 5526 deletions(-) delete mode 100644 Terminal.Gui/StringExtensions.cs create mode 100644 Terminal.Gui/Text/RuneExtensions.cs create mode 100644 Terminal.Gui/Text/StringExtensions.cs create mode 100644 UnitTests/Text/RuneTests.cs create mode 100644 UnitTests/Text/StringTests.cs diff --git a/ReactiveExample/LoginView.cs b/ReactiveExample/LoginView.cs index 1bd36fcff..a74fb9f94 100644 --- a/ReactiveExample/LoginView.cs +++ b/ReactiveExample/LoginView.cs @@ -1,6 +1,6 @@ using System.Reactive.Disposables; using System.Reactive.Linq; -using NStack; +using System.Text; using ReactiveUI; using Terminal.Gui; using ReactiveMarbles.ObservableEvents; @@ -64,7 +64,7 @@ namespace ReactiveExample { }; ViewModel .WhenAnyValue (x => x.UsernameLength) - .Select (length => ustring.Make ($"Username ({length} characters)")) + .Select (length => $"Username ({length} characters)") .BindTo (usernameLengthLabel, x => x.Text) .DisposeWith (_disposable); Add (usernameLengthLabel); @@ -100,7 +100,7 @@ namespace ReactiveExample { }; ViewModel .WhenAnyValue (x => x.PasswordLength) - .Select (length => ustring.Make ($"Password ({length} characters)")) + .Select (length => $"Password ({length} characters)") .BindTo (passwordLengthLabel, x => x.Text) .DisposeWith (_disposable); Add (passwordLengthLabel); @@ -108,8 +108,8 @@ namespace ReactiveExample { } Label ValidationLabel (View previous) { - var error = ustring.Make("Please, enter user name and password."); - var success = ustring.Make("The input is valid!"); + var error = "Please, enter user name and password."; + var success = "The input is valid!"; var validationLabel = new Label(error) { X = Pos.Left(previous), Y = Pos.Top(previous) + 1, @@ -130,8 +130,8 @@ namespace ReactiveExample { } Label LoginProgressLabel (View previous) { - var progress = ustring.Make ("Logging in..."); - var idle = ustring.Make ("Press 'Login' to log in."); + var progress = "Logging in..."; + var idle = "Press 'Login' to log in."; var loginProgressLabel = new Label(idle) { X = Pos.Left(previous), Y = Pos.Top(previous) + 1, diff --git a/ReactiveExample/LoginViewModel.cs b/ReactiveExample/LoginViewModel.cs index e9f1d4745..619e4c802 100644 --- a/ReactiveExample/LoginViewModel.cs +++ b/ReactiveExample/LoginViewModel.cs @@ -3,7 +3,7 @@ using System.Reactive; using System.Reactive.Linq; using System.Runtime.Serialization; using System.Threading.Tasks; -using NStack; +using System.Text; using ReactiveUI; using ReactiveUI.Fody.Helpers; @@ -30,8 +30,8 @@ namespace ReactiveExample { x => x.Username, x => x.Password, (username, password) => - !ustring.IsNullOrEmpty (username) && - !ustring.IsNullOrEmpty (password)); + !string.IsNullOrEmpty (username) && + !string.IsNullOrEmpty (password)); _isValid = canLogin.ToProperty (this, x => x.IsValid); Login = ReactiveCommand.CreateFromTask ( @@ -49,16 +49,16 @@ namespace ReactiveExample { Clear = ReactiveCommand.Create (() => { }); Clear.Subscribe (unit => { - Username = ustring.Empty; - Password = ustring.Empty; + Username = string.Empty; + Password = string.Empty; }); } [Reactive, DataMember] - public ustring Username { get; set; } = ustring.Empty; + public string Username { get; set; } = string.Empty; [Reactive, DataMember] - public ustring Password { get; set; } = ustring.Empty; + public string Password { get; set; } = string.Empty; [IgnoreDataMember] public int UsernameLength => _usernameLength.Value; diff --git a/ReactiveExample/README.md b/ReactiveExample/README.md index fb9b8dcf0..61f86cfa5 100644 --- a/ReactiveExample/README.md +++ b/ReactiveExample/README.md @@ -38,7 +38,7 @@ usernameInput .BindTo (ViewModel, x => x.Username); ``` -If you combine `OneWay` and `OneWayToSource` data bindings, you get `TwoWay` data binding. Also be sure to use the `ustring` type instead of the `string` type. Invoking commands should be as simple as this: +If you combine `OneWay` and `OneWayToSource` data bindings, you get `TwoWay` data binding. Also be sure to use the `string` type instead of the `string` type. Invoking commands should be as simple as this: ```cs // 'clearButton' is 'Button' clearButton diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index bc4252054..929578fda 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -51,7 +51,6 @@ namespace Terminal.Gui { /// /// If , forces the use of the System.Console-based (see ) driver. The default is . /// - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] public static bool UseSystemConsole { get; set; } = false; // For Unit testing - ignores UseSystemConsole @@ -442,10 +441,10 @@ namespace Terminal.Gui { } else if (Top != null && Toplevel != Top && _toplevels.Contains (Top)) { Top.OnLeave (Toplevel); } - if (string.IsNullOrEmpty (Toplevel.Id.ToString ())) { + if (string.IsNullOrEmpty (Toplevel.Id)) { var count = 1; var id = (_toplevels.Count + count).ToString (); - while (_toplevels.Count > 0 && _toplevels.FirstOrDefault (x => x.Id.ToString () == id) != null) { + while (_toplevels.Count > 0 && _toplevels.FirstOrDefault (x => x.Id == id) != null) { count++; id = (_toplevels.Count + count).ToString (); } @@ -453,7 +452,7 @@ namespace Terminal.Gui { _toplevels.Push (Toplevel); } else { - var dup = _toplevels.FirstOrDefault (x => x.Id.ToString () == Toplevel.Id); + var dup = _toplevels.FirstOrDefault (x => x.Id == Toplevel.Id); if (dup == null) { _toplevels.Push (Toplevel); } diff --git a/Terminal.Gui/Clipboard/Clipboard.cs b/Terminal.Gui/Clipboard/Clipboard.cs index 4aed183da..2d47022c5 100644 --- a/Terminal.Gui/Clipboard/Clipboard.cs +++ b/Terminal.Gui/Clipboard/Clipboard.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; namespace Terminal.Gui { @@ -25,16 +25,16 @@ namespace Terminal.Gui { /// /// public static class Clipboard { - static ustring contents; + static string contents; /// /// Gets (copies from) or sets (pastes to) the contents of the OS clipboard. /// - public static ustring Contents { + public static string Contents { get { try { if (IsSupported) { - return contents = ustring.Make (Application.Driver.Clipboard.GetClipboardData ()); + return contents = Application.Driver.Clipboard.GetClipboardData (); } else { return contents; } diff --git a/Terminal.Gui/Configuration/RuneJsonConverter.cs b/Terminal.Gui/Configuration/RuneJsonConverter.cs index 725b1aa20..2685f68eb 100644 --- a/Terminal.Gui/Configuration/RuneJsonConverter.cs +++ b/Terminal.Gui/Configuration/RuneJsonConverter.cs @@ -2,11 +2,10 @@ using System.Text; using System.Text.Json; using System.Text.Json.Serialization; -//using Rune = System.Rune; namespace Terminal.Gui { /// - /// Json converter for . Supports + /// Json converter for . Supports /// A string as one of: /// - unicode char (e.g. "☑") /// - U+hex format (e.g. "U+2611") @@ -14,29 +13,29 @@ namespace Terminal.Gui { /// A number /// - The unicode code in decimal /// - internal class RuneJsonConverter : JsonConverter { - public override System.Rune Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal class RuneJsonConverter : JsonConverter { + public override Rune Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { var value = reader.GetString (); - if (value.ToUpper ().StartsWith ("U+") || value.StartsWith ("\\u")) { + if (value.StartsWith ("U+", StringComparison.OrdinalIgnoreCase) || value.StartsWith ("\\u")) { try { uint result = uint.Parse (value [2..^0], System.Globalization.NumberStyles.HexNumber); - return new System.Rune (result); + return new Rune (result); } catch (FormatException e) { throw new JsonException ($"Invalid Rune format: {value}.", e); } } else { - return new System.Rune (value [0]); + return new Rune (value [0]); } throw new JsonException ($"Invalid Rune format: {value}."); } else if (reader.TokenType == JsonTokenType.Number) { - return new System.Rune (reader.GetUInt32 ()); + return new Rune (reader.GetUInt32 ()); } throw new JsonException ($"Unexpected StartObject token when parsing Rune: {reader.TokenType}."); } - public override void Write (Utf8JsonWriter writer, System.Rune value, JsonSerializerOptions options) + public override void Write (Utf8JsonWriter writer, Rune value, JsonSerializerOptions options) { // HACK: Writes a JSON comment in addition to the glyph to ease debugging. // Technically, JSON comments are not valid, but we use relaxed decoding diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 5445d24bd..a2757d8de 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -1,7 +1,7 @@ // // ConsoleDriver.cs: Base class for Terminal.Gui ConsoleDriver implementations. // -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.ComponentModel; @@ -347,13 +347,13 @@ namespace Terminal.Gui { /// /// Creates a new instance. /// - public ColorScheme() { } + public ColorScheme () { } /// /// Creates a new instance, initialized with the values from . /// /// The scheme to initlize the new instance with. - public ColorScheme (ColorScheme scheme) : base() + public ColorScheme (ColorScheme scheme) : base () { if (scheme != null) { _normal = scheme.Normal; @@ -617,8 +617,8 @@ namespace Terminal.Gui { /// /// Provides the defined s. /// - [SerializableConfigurationProperty (Scope = typeof(ThemeScope), OmitClassName = true)] - [JsonConverter(typeof(DictionaryJsonConverter))] + [SerializableConfigurationProperty (Scope = typeof (ThemeScope), OmitClassName = true)] + [JsonConverter (typeof (DictionaryJsonConverter))] public static Dictionary ColorSchemes { get; private set; } } @@ -679,7 +679,7 @@ namespace Terminal.Gui { /// Works under Xterm-like terminal otherwise this is equivalent to BoxFix = 0x02020164, } - + /// /// ConsoleDriver is an abstract class that defines the requirements for a console driver. /// There are currently three implementations: (for Unix and Mac), , and that uses the .NET Console API. @@ -756,24 +756,7 @@ namespace Terminal.Gui { /// /// Rune to add. public abstract void AddRune (Rune rune); - - /// - /// Ensures a Rune is not a control character and can be displayed by translating characters below 0x20 - /// to equivalent, printable, Unicode chars. - /// - /// Rune to translate - /// - public static Rune MakePrintable (Rune c) - { - if (c <= 0x1F || (c >= 0X7F && c <= 0x9F)) { - // ASCII (C0) control characters. - // C1 control characters (https://www.aivosto.com/articles/control-characters.html#c1) - return new Rune (c + 0x2400); - } - - return c; - } - + /// /// Ensures that the column and line are in a valid range from the size of the driver. /// @@ -788,7 +771,7 @@ namespace Terminal.Gui { /// Adds the to the display at the cursor position. /// /// String. - public abstract void AddStr (ustring str); + public abstract void AddStr (string str); /// /// Prepare the driver and set the key and mouse events handlers. @@ -928,12 +911,12 @@ namespace Terminal.Gui { /// /// /// - public virtual void FillRect (Rect rect, System.Rune rune = default) + public virtual void FillRect (Rect rect, Rune rune = default) { for (var r = rect.Y; r < rect.Y + rect.Height; r++) { for (var c = rect.X; c < rect.X + rect.Width; c++) { Application.Driver.Move (c, r); - Application.Driver.AddRune (rune == default ? ' ' : rune); + Application.Driver.AddRune ((Rune)(rune == default ? ' ' : rune.Value)); } } } diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 7a7b09402..263bd7600 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -7,7 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; -using NStack; +using System.Text; using Unix.Terminal; namespace Terminal.Gui { @@ -50,8 +50,8 @@ namespace Terminal.Gui { static bool sync = false; public override void AddRune (Rune rune) { - rune = MakePrintable (rune); - var runeWidth = Rune.ColumnWidth (rune); + rune = rune.MakePrintable (); + var runeWidth = rune.GetColumns (); var validClip = IsValidContent (ccol, crow, Clip); if (validClip) { @@ -61,7 +61,7 @@ namespace Terminal.Gui { } if (runeWidth == 0 && ccol > 0) { var r = contents [crow, ccol - 1, 0]; - var s = new string (new char [] { (char)r, (char)rune }); + var s = new string (new char [] { (char)r, (char)rune.Value }); string sn; if (!s.IsNormalized ()) { sn = s.Normalize (); @@ -76,7 +76,7 @@ namespace Terminal.Gui { } else { if (runeWidth < 2 && ccol > 0 - && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) { + && ((Rune)(char)contents [crow, ccol - 1, 0]).GetColumns () > 1) { var curAtttib = CurrentAttribute; Curses.attrset (contents [crow, ccol - 1, 1]); @@ -86,7 +86,7 @@ namespace Terminal.Gui { Curses.attrset (curAtttib); } else if (runeWidth < 2 && ccol <= Clip.Right - 1 - && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) { + && ((Rune)(char)contents [crow, ccol, 0]).GetColumns () > 1) { var curAtttib = CurrentAttribute; Curses.attrset (contents [crow, ccol + 1, 1]); @@ -100,8 +100,8 @@ namespace Terminal.Gui { Curses.addch ((int)(uint)' '); contents [crow, ccol, 0] = (int)(uint)' '; } else { - Curses.addch ((int)(uint)rune); - contents [crow, ccol, 0] = (int)(uint)rune; + Curses.addch ((int)(uint)rune.Value); + contents [crow, ccol, 0] = (int)(uint)rune.Value; } contents [crow, ccol, 1] = CurrentAttribute; contents [crow, ccol, 2] = 1; @@ -127,10 +127,10 @@ namespace Terminal.Gui { } } - public override void AddStr (ustring str) + public override void AddStr (string str) { // TODO; optimize this to determine if the str fits in the clip region, and if so, use Curses.addstr directly - foreach (var rune in str) + foreach (var rune in str.EnumerateRunes ()) AddRune (rune); } diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index b71bc3f1d..2f7df9534 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -7,7 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Threading; -using NStack; +using System.Text; // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; @@ -118,8 +118,8 @@ namespace Terminal.Gui { public override void AddRune (Rune rune) { - rune = MakePrintable (rune); - var runeWidth = Rune.ColumnWidth (rune); + rune = rune.MakePrintable (); + var runeWidth = rune.GetColumns (); var validClip = IsValidContent (ccol, crow, Clip); if (validClip) { @@ -130,7 +130,7 @@ namespace Terminal.Gui { } if (runeWidth == 0 && ccol > 0) { var r = contents [crow, ccol - 1, 0]; - var s = new string (new char [] { (char)r, (char)rune }); + var s = new string (new char [] { (char)r, (char)rune.Value }); string sn; if (!s.IsNormalized ()) { sn = s.Normalize (); @@ -144,12 +144,12 @@ namespace Terminal.Gui { } else { if (runeWidth < 2 && ccol > 0 - && Rune.ColumnWidth ((Rune)contents [crow, ccol - 1, 0]) > 1) { + && ((Rune)contents [crow, ccol - 1, 0]).GetColumns () > 1) { contents [crow, ccol - 1, 0] = (int)(uint)' '; } else if (runeWidth < 2 && ccol <= Clip.Right - 1 - && Rune.ColumnWidth ((Rune)contents [crow, ccol, 0]) > 1) { + && ((Rune)contents [crow, ccol, 0]).GetColumns () > 1) { contents [crow, ccol + 1, 0] = (int)(uint)' '; contents [crow, ccol + 1, 2] = 1; @@ -158,7 +158,7 @@ namespace Terminal.Gui { if (runeWidth > 1 && ccol == Clip.Right - 1) { contents [crow, ccol, 0] = (int)(uint)' '; } else { - contents [crow, ccol, 0] = (int)(uint)rune; + contents [crow, ccol, 0] = (int)(uint)rune.Value; } contents [crow, ccol, 1] = CurrentAttribute; contents [crow, ccol, 2] = 1; @@ -191,9 +191,9 @@ namespace Terminal.Gui { } } - public override void AddStr (ustring str) + public override void AddStr (string str) { - foreach (var rune in str) + foreach (var rune in str.EnumerateRunes ()) AddRune (rune); } @@ -281,11 +281,11 @@ namespace Terminal.Gui { if (color != redrawColor) SetColor (color); - Rune rune = contents [row, col, 0]; - if (Rune.DecodeSurrogatePair (rune, out char [] spair)) { + Rune rune = (Rune)contents [row, col, 0]; + if (rune.DecodeSurrogatePair (out char [] spair)) { FakeConsole.Write (spair); } else { - FakeConsole.Write ((char)rune); + FakeConsole.Write ((char)rune.Value); } contents [row, col, 2] = 0; } diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 1617cd188..4a3c48e82 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -11,7 +11,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using NStack; +using System.Text; namespace Terminal.Gui { internal class NetWinVTConsole { @@ -195,12 +195,13 @@ namespace Terminal.Gui { isEscSeq = false; break; } - } else if (consoleKeyInfo.KeyChar == (char)Key.Esc && isEscSeq) { + } else if (consoleKeyInfo.KeyChar == (char)Key.Esc && isEscSeq && cki != null) { DecodeEscSeq (ref newConsoleKeyInfo, ref key, cki, ref mod); cki = null; break; } else { GetConsoleInputType (consoleKeyInfo); + isEscSeq = false; break; } } @@ -668,14 +669,14 @@ namespace Terminal.Gui { if (contents.Length != Rows * Cols * 3) { return; } - rune = MakePrintable (rune); - var runeWidth = Rune.ColumnWidth (rune); + rune = rune.MakePrintable (); + var runeWidth = rune.GetColumns (); var validClip = IsValidContent (ccol, crow, Clip); if (validClip) { if (runeWidth == 0 && ccol > 0) { var r = contents [crow, ccol - 1, 0]; - var s = new string (new char [] { (char)r, (char)rune }); + var s = new string (new char [] { (char)r, (char)rune.Value }); string sn; if (!s.IsNormalized ()) { sn = s.Normalize (); @@ -689,12 +690,12 @@ namespace Terminal.Gui { } else { if (runeWidth < 2 && ccol > 0 - && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) { + && ((Rune)(char)contents [crow, ccol - 1, 0]).GetColumns () > 1) { contents [crow, ccol - 1, 0] = (int)(uint)' '; } else if (runeWidth < 2 && ccol <= Clip.Right - 1 - && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) { + && ((Rune)(char)contents [crow, ccol, 0]).GetColumns () > 1) { contents [crow, ccol + 1, 0] = (int)(uint)' '; contents [crow, ccol + 1, 2] = 1; @@ -703,7 +704,7 @@ namespace Terminal.Gui { if (runeWidth > 1 && ccol == Clip.Right - 1) { contents [crow, ccol, 0] = (int)(uint)' '; } else { - contents [crow, ccol, 0] = (int)(uint)rune; + contents [crow, ccol, 0] = (int)(uint)rune.Value; } contents [crow, ccol, 1] = CurrentAttribute; contents [crow, ccol, 2] = 1; @@ -729,9 +730,9 @@ namespace Terminal.Gui { } } - public override void AddStr (ustring str) + public override void AddStr (string str) { - foreach (var rune in str) + foreach (var rune in str.EnumerateRunes ()) AddRune (rune); } @@ -950,12 +951,12 @@ namespace Terminal.Gui { output.Append (WriteAttributes (attr)); } outputWidth++; - var rune = contents [row, col, 0]; + var rune = (Rune)contents [row, col, 0]; char [] spair; - if (Rune.DecodeSurrogatePair ((uint)rune, out spair)) { + if (rune.DecodeSurrogatePair (out spair)) { output.Append (spair); } else { - output.Append ((char)rune); + output.Append ((char)rune.Value); } contents [row, col, 2] = 0; } diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 71b837abf..85ba30cde 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -1,7 +1,7 @@ // // WindowsDriver.cs: Windows specific driver // -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.ComponentModel; @@ -742,7 +742,7 @@ namespace Terminal.Gui { mLoop.ProcessInput = (e) => ProcessInput (e); - mLoop.WinChanged = (s,e) => { + mLoop.WinChanged = (s, e) => { ChangeWin (e.Size); }; } @@ -1520,15 +1520,15 @@ namespace Terminal.Gui { public override void AddRune (Rune rune) { - rune = MakePrintable (rune); - var runeWidth = Rune.ColumnWidth (rune); + rune = rune.MakePrintable (); + var runeWidth = rune.GetColumns (); var position = GetOutputBufferPosition (); var validClip = IsValidContent (ccol, crow, Clip); if (validClip) { if (runeWidth == 0 && ccol > 0) { var r = contents [crow, ccol - 1, 0]; - var s = new string (new char [] { (char)r, (char)rune }); + var s = new string (new char [] { (char)r, (char)rune.Value }); string sn; if (!s.IsNormalized ()) { sn = s.Normalize (); @@ -1545,14 +1545,14 @@ namespace Terminal.Gui { WindowsConsole.SmallRect.Update (ref damageRegion, (short)(ccol - 1), (short)crow); } else { if (runeWidth < 2 && ccol > 0 - && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) { + && ((Rune)(char)contents [crow, ccol - 1, 0]).GetColumns () > 1) { var prevPosition = crow * Cols + (ccol - 1); OutputBuffer [prevPosition].Char.UnicodeChar = ' '; contents [crow, ccol - 1, 0] = (int)(uint)' '; } else if (runeWidth < 2 && ccol <= Clip.Right - 1 - && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) { + && ((Rune)(char)contents [crow, ccol, 0]).GetColumns () > 1) { var prevPosition = GetOutputBufferPosition () + 1; OutputBuffer [prevPosition].Char.UnicodeChar = (char)' '; @@ -1563,8 +1563,8 @@ namespace Terminal.Gui { OutputBuffer [position].Char.UnicodeChar = (char)' '; contents [crow, ccol, 0] = (int)(uint)' '; } else { - OutputBuffer [position].Char.UnicodeChar = (char)rune; - contents [crow, ccol, 0] = (int)(uint)rune; + OutputBuffer [position].Char.UnicodeChar = (char)rune.Value; + contents [crow, ccol, 0] = (int)(uint)rune.Value; } OutputBuffer [position].Attributes = (ushort)CurrentAttribute; contents [crow, ccol, 1] = CurrentAttribute; @@ -1594,9 +1594,9 @@ namespace Terminal.Gui { } } - public override void AddStr (ustring str) + public override void AddStr (string str) { - foreach (var rune in str) + foreach (var rune in str.EnumerateRunes ()) AddRune (rune); } @@ -1868,7 +1868,7 @@ namespace Terminal.Gui { /// Invoked when the window is changed. /// public EventHandler WinChanged; - + public WindowsMainLoop (ConsoleDriver consoleDriver = null) { this.consoleDriver = consoleDriver ?? throw new ArgumentNullException ("Console driver instance must be provided."); @@ -1990,7 +1990,7 @@ namespace Terminal.Gui { } if (winChanged) { winChanged = false; - WinChanged?.Invoke (this, new SizeChangedEventArgs(windowSize)); + WinChanged?.Invoke (this, new SizeChangedEventArgs (windowSize)); } } } diff --git a/Terminal.Gui/Drawing/Glyphs.cs b/Terminal.Gui/Drawing/Glyphs.cs index 9037241ee..4f8941e32 100644 --- a/Terminal.Gui/Drawing/Glyphs.cs +++ b/Terminal.Gui/Drawing/Glyphs.cs @@ -1,6 +1,6 @@ using static Terminal.Gui.ConfigurationManager; using System.Text.Json.Serialization; -using Rune = System.Rune; +using System.Text; namespace Terminal.Gui { /// @@ -24,369 +24,369 @@ namespace Terminal.Gui { /// /// Checked indicator (e.g. for and ). /// - public Rune Checked { get; set; } = '☑'; + public Rune Checked { get; set; } = (Rune)'☑'; /// /// Not Checked indicator (e.g. for and ). /// - public Rune UnChecked { get; set; } = '☐'; + public Rune UnChecked { get; set; } = (Rune)'☐'; /// /// Null Checked indicator (e.g. for and ). /// - public Rune NullChecked { get; set; } = '☒'; + public Rune NullChecked { get; set; } = (Rune)'☒'; /// /// Selected indicator (e.g. for and ). /// - public Rune Selected { get; set; } = '◉'; + public Rune Selected { get; set; } = (Rune)'◉'; /// /// Not Selected indicator (e.g. for and ). /// - public Rune UnSelected { get; set; } = '○'; + public Rune UnSelected { get; set; } = (Rune)'○'; /// /// Horizontal arrow. /// - public Rune RightArrow { get; set; } = '►'; + public Rune RightArrow { get; set; } = (Rune)'►'; /// /// Left arrow. /// - public Rune LeftArrow { get; set; } = '◄'; + public Rune LeftArrow { get; set; } = (Rune)'◄'; /// /// Down arrow. /// - public Rune DownArrow { get; set; } = '▼'; + public Rune DownArrow { get; set; } = (Rune)'▼'; /// /// Vertical arrow. /// - public Rune UpArrow { get; set; } = '▲'; + public Rune UpArrow { get; set; } = (Rune)'▲'; /// /// Left default indicator (e.g. for . /// - public Rune LeftDefaultIndicator { get; set; } = '►'; + public Rune LeftDefaultIndicator { get; set; } = (Rune)'►'; /// /// Horizontal default indicator (e.g. for . /// - public Rune RightDefaultIndicator { get; set; } = '◄'; + public Rune RightDefaultIndicator { get; set; } = (Rune)'◄'; /// /// Left Bracket (e.g. for . Default is (U+005B) - [. /// - public Rune LeftBracket { get; set; } = '⟦'; + public Rune LeftBracket { get; set; } = (Rune)'⟦'; /// /// Horizontal Bracket (e.g. for . Default is (U+005D) - ]. /// - public Rune RightBracket { get; set; } = '⟧'; + public Rune RightBracket { get; set; } = (Rune)'⟧'; /// /// Half block meter segment (e.g. for ). /// - public Rune BlocksMeterSegment { get; set; } = '▌'; + public Rune BlocksMeterSegment { get; set; } = (Rune)'▌'; /// /// Continuous block meter segment (e.g. for ). /// - public Rune ContinuousMeterSegment { get; set; } = '█'; + public Rune ContinuousMeterSegment { get; set; } = (Rune)'█'; /// /// Stipple pattern (e.g. for ). Default is Light Shade (U+2591) - ░. /// - public Rune Stipple { get; set; } = '░'; + public Rune Stipple { get; set; } = (Rune)'░'; /// /// Diamond (e.g. for . Default is Lozenge (U+25CA) - ◊. /// - public Rune Diamond { get; set; } = '◊'; + public Rune Diamond { get; set; } = (Rune)'◊'; /// /// Close. Default is Heavy Ballot X (U+2718) - ✘. /// - public Rune Close { get; set; } = '✘'; + public Rune Close { get; set; } = (Rune)'✘'; /// /// Minimize. Default is Lower Horizontal Shadowed White Circle (U+274F) - ❏. /// - public Rune Minimize { get; set; } = '❏'; + public Rune Minimize { get; set; } = (Rune)'❏'; /// /// Maximize. Default is Upper Horizontal Shadowed White Circle (U+273D) - ✽. /// - public Rune Maximize { get; set; } = '✽'; + public Rune Maximize { get; set; } = (Rune)'✽'; /// /// Dot. Default is (U+2219) - ∙. /// - public Rune Dot { get; set; } = '∙'; + public Rune Dot { get; set; } = (Rune)'∙'; /// /// Expand (e.g. for . /// - public Rune Expand { get; set; } = '+'; + public Rune Expand { get; set; } = (Rune)'+'; /// /// Expand (e.g. for . /// - public Rune Collapse { get; set; } = '-'; + public Rune Collapse { get; set; } = (Rune)'-'; /// /// Apple. Because snek. /// - public Rune Apple { get; set; } = '❦' ; // BUGBUG: "🍎"[0] should work, but doesn't + public Rune Apple { get; set; } = (Rune)'❦' ; // BUGBUG: "🍎"[0] should work, but doesn't #endregion /// /// Folder icon. Defaults to ꤉ (Kayah Li Digit Nine) /// - public Rune Folder { get; set; } = '꤉'; + public Rune Folder { get; set; } = (Rune)'꤉'; /// /// File icon. Defaults to ☰ (Trigram For Heaven) /// - public Rune File { get; set; } = '☰'; + public Rune File { get; set; } = (Rune)'☰'; #region ----------------- Lines ----------------- /// /// Box Drawings Horizontal Line - Light (U+2500) - ─ /// - public Rune HLine { get; set; } = '─'; + public Rune HLine { get; set; } = (Rune)'─'; /// /// Box Drawings Vertical Line - Light (U+2502) - │ /// - public Rune VLine { get; set; } = '│'; + public Rune VLine { get; set; } = (Rune)'│'; /// /// Box Drawings Double Horizontal (U+2550) - ═ /// - public Rune HLineDbl { get; set; } = '═'; + public Rune HLineDbl { get; set; } = (Rune)'═'; /// /// Box Drawings Double Vertical (U+2551) - ║ /// - public Rune VLineDbl { get; set; } = '║'; + public Rune VLineDbl { get; set; } = (Rune)'║'; /// /// Box Drawings Heavy Double Dash Horizontal (U+254D) - ╍ /// - public Rune HLineHvDa2 { get; set; } = '╍'; + public Rune HLineHvDa2 { get; set; } = (Rune)'╍'; /// /// Box Drawings Heavy Triple Dash Vertical (U+2507) - ┇ /// - public Rune VLineHvDa3 { get; set; } = '┇'; + public Rune VLineHvDa3 { get; set; } = (Rune)'┇'; /// /// Box Drawings Heavy Triple Dash Horizontal (U+2505) - ┅ /// - public Rune HLineHvDa3 { get; set; } = '┅'; + public Rune HLineHvDa3 { get; set; } = (Rune)'┅'; /// /// Box Drawings Heavy Quadruple Dash Horizontal (U+2509) - ┉ /// - public Rune HLineHvDa4 { get; set; } = '┉'; + public Rune HLineHvDa4 { get; set; } = (Rune)'┉'; /// /// Box Drawings Heavy Double Dash Vertical (U+254F) - ╏ /// - public Rune VLineHvDa2 { get; set; } = '╏'; + public Rune VLineHvDa2 { get; set; } = (Rune)'╏'; /// /// Box Drawings Heavy Quadruple Dash Vertical (U+250B) - ┋ /// - public Rune VLineHvDa4 { get; set; } = '┋'; + public Rune VLineHvDa4 { get; set; } = (Rune)'┋'; /// /// Box Drawings Light Double Dash Horizontal (U+254C) - ╌ /// - public Rune HLineDa2 { get; set; } = '╌'; + public Rune HLineDa2 { get; set; } = (Rune)'╌'; /// /// Box Drawings Light Triple Dash Vertical (U+2506) - ┆ /// - public Rune VLineDa3 { get; set; } = '┆'; + public Rune VLineDa3 { get; set; } = (Rune)'┆'; /// /// Box Drawings Light Triple Dash Horizontal (U+2504) - ┄ /// - public Rune HLineDa3 { get; set; } = '┄'; + public Rune HLineDa3 { get; set; } = (Rune)'┄'; /// /// Box Drawings Light Quadruple Dash Horizontal (U+2508) - ┈ /// - public Rune HLineDa4 { get; set; } = '┈'; + public Rune HLineDa4 { get; set; } = (Rune)'┈'; /// /// Box Drawings Light Double Dash Vertical (U+254E) - ╎ /// - public Rune VLineDa2 { get; set; } = '╎'; + public Rune VLineDa2 { get; set; } = (Rune)'╎'; /// /// Box Drawings Light Quadruple Dash Vertical (U+250A) - ┊ /// - public Rune VLineDa4 { get; set; } = '┊'; + public Rune VLineDa4 { get; set; } = (Rune)'┊'; /// /// Box Drawings Heavy Horizontal (U+2501) - ━ /// - public Rune HLineHv { get; set; } = '━'; + public Rune HLineHv { get; set; } = (Rune)'━'; /// /// Box Drawings Heavy Vertical (U+2503) - ┃ /// - public Rune VLineHv { get; set; } = '┃'; + public Rune VLineHv { get; set; } = (Rune)'┃'; /// /// Box Drawings Light Left (U+2574) - ╴ /// - public Rune HalfLeftLine { get; set; } = '╴'; + public Rune HalfLeftLine { get; set; } = (Rune)'╴'; /// /// Box Drawings Light Vertical (U+2575) - ╵ /// - public Rune HalfTopLine { get; set; } = '╵'; + public Rune HalfTopLine { get; set; } = (Rune)'╵'; /// /// Box Drawings Light Horizontal (U+2576) - ╶ /// - public Rune HalfRightLine { get; set; } = '╶'; + public Rune HalfRightLine { get; set; } = (Rune)'╶'; /// /// Box Drawings Light Down (U+2577) - ╷ /// - public Rune HalfBottomLine { get; set; } = '╷'; + public Rune HalfBottomLine { get; set; } = (Rune)'╷'; /// /// Box Drawings Heavy Left (U+2578) - ╸ /// - public Rune HalfLeftLineHv { get; set; } = '╸'; + public Rune HalfLeftLineHv { get; set; } = (Rune)'╸'; /// /// Box Drawings Heavy Vertical (U+2579) - ╹ /// - public Rune HalfTopLineHv { get; set; } = '╹'; + public Rune HalfTopLineHv { get; set; } = (Rune)'╹'; /// /// Box Drawings Heavy Horizontal (U+257A) - ╺ /// - public Rune HalfRightLineHv { get; set; } = '╺'; + public Rune HalfRightLineHv { get; set; } = (Rune)'╺'; /// /// Box Drawings Light Vertical and Horizontal (U+257B) - ╻ /// - public Rune HalfBottomLineLt { get; set; } = '╻'; + public Rune HalfBottomLineLt { get; set; } = (Rune)'╻'; /// /// Box Drawings Light Horizontal and Heavy Horizontal (U+257C) - ╼ /// - public Rune RightSideLineLtHv { get; set; } = '╼'; + public Rune RightSideLineLtHv { get; set; } = (Rune)'╼'; /// /// Box Drawings Light Vertical and Heavy Horizontal (U+257D) - ╽ /// - public Rune BottomSideLineLtHv { get; set; } = '╽'; + public Rune BottomSideLineLtHv { get; set; } = (Rune)'╽'; /// /// Box Drawings Heavy Left and Light Horizontal (U+257E) - ╾ /// - public Rune LeftSideLineHvLt { get; set; } = '╾'; + public Rune LeftSideLineHvLt { get; set; } = (Rune)'╾'; /// /// Box Drawings Heavy Vertical and Light Horizontal (U+257F) - ╿ /// - public Rune TopSideLineHvLt { get; set; } = '╿'; + public Rune TopSideLineHvLt { get; set; } = (Rune)'╿'; #endregion #region ----------------- Upper Left Corners ----------------- /// /// Box Drawings Upper Left Corner - Light Vertical and Light Horizontal (U+250C) - ┌ /// - public Rune ULCorner { get; set; } = '┌'; + public Rune ULCorner { get; set; } = (Rune)'┌'; /// /// Box Drawings Upper Left Corner - Double (U+2554) - ╔ /// - public Rune ULCornerDbl { get; set; } = '╔'; + public Rune ULCornerDbl { get; set; } = (Rune)'╔'; /// /// Box Drawings Upper Left Corner - Light Arc Down and Horizontal (U+256D) - ╭ /// - public Rune ULCornerR { get; set; } = '╭'; + public Rune ULCornerR { get; set; } = (Rune)'╭'; /// /// Box Drawings Heavy Down and Horizontal (U+250F) - ┏ /// - public Rune ULCornerHv { get; set; } = '┏'; + public Rune ULCornerHv { get; set; } = (Rune)'┏'; /// /// Box Drawings Down Heavy and Horizontal Light (U+251E) - ┎ /// - public Rune ULCornerHvLt { get; set; } = '┎'; + public Rune ULCornerHvLt { get; set; } = (Rune)'┎'; /// /// Box Drawings Down Light and Horizontal Heavy (U+250D) - ┎ /// - public Rune ULCornerLtHv { get; set; } = '┍'; + public Rune ULCornerLtHv { get; set; } = (Rune)'┍'; /// /// Box Drawings Double Down and Single Horizontal (U+2553) - ╓ /// - public Rune ULCornerDblSingle { get; set; } = '╓'; + public Rune ULCornerDblSingle { get; set; } = (Rune)'╓'; /// /// Box Drawings Single Down and Double Horizontal (U+2552) - ╒ /// - public Rune ULCornerSingleDbl { get; set; } = '╒'; + public Rune ULCornerSingleDbl { get; set; } = (Rune)'╒'; #endregion #region ----------------- Lower Left Corners ----------------- /// /// Box Drawings Lower Left Corner - Light Vertical and Light Horizontal (U+2514) - └ /// - public Rune LLCorner { get; set; } = '└'; + public Rune LLCorner { get; set; } = (Rune)'└'; /// /// Box Drawings Heavy Vertical and Horizontal (U+2517) - ┗ /// - public Rune LLCornerHv { get; set; } = '┗'; + public Rune LLCornerHv { get; set; } = (Rune)'┗'; /// /// Box Drawings Heavy Vertical and Horizontal Light (U+2516) - ┖ /// - public Rune LLCornerHvLt { get; set; } = '┖'; + public Rune LLCornerHvLt { get; set; } = (Rune)'┖'; /// /// Box Drawings Vertical Light and Horizontal Heavy (U+2511) - ┕ /// - public Rune LLCornerLtHv { get; set; } = '┕'; + public Rune LLCornerLtHv { get; set; } = (Rune)'┕'; /// /// Box Drawings Double Vertical and Double Left (U+255A) - ╚ /// - public Rune LLCornerDbl { get; set; } = '╚'; + public Rune LLCornerDbl { get; set; } = (Rune)'╚'; /// /// Box Drawings Single Vertical and Double Left (U+2558) - ╘ /// - public Rune LLCornerSingleDbl { get; set; } = '╘'; + public Rune LLCornerSingleDbl { get; set; } = (Rune)'╘'; /// /// Box Drawings Double Down and Single Left (U+2559) - ╙ /// - public Rune LLCornerDblSingle { get; set; } = '╙'; + public Rune LLCornerDblSingle { get; set; } = (Rune)'╙'; /// /// Box Drawings Upper Left Corner - Light Arc Down and Left (U+2570) - ╰ /// - public Rune LLCornerR { get; set; } = '╰'; + public Rune LLCornerR { get; set; } = (Rune)'╰'; #endregion @@ -394,226 +394,226 @@ namespace Terminal.Gui { /// /// Box Drawings Upper Horizontal Corner - Light Vertical and Light Horizontal (U+2510) - ┐ /// - public Rune URCorner { get; set; } = '┐'; + public Rune URCorner { get; set; } = (Rune)'┐'; /// /// Box Drawings Upper Horizontal Corner - Double Vertical and Double Horizontal (U+2557) - ╗ /// - public Rune URCornerDbl { get; set; } = '╗'; + public Rune URCornerDbl { get; set; } = (Rune)'╗'; /// /// Box Drawings Upper Horizontal Corner - Light Arc Vertical and Horizontal (U+256E) - ╮ /// - public Rune URCornerR { get; set; } = '╮'; + public Rune URCornerR { get; set; } = (Rune)'╮'; /// /// Box Drawings Heavy Down and Left (U+2513) - ┓ /// - public Rune URCornerHv { get; set; } = '┓'; + public Rune URCornerHv { get; set; } = (Rune)'┓'; /// /// Box Drawings Heavy Vertical and Left Down Light (U+2511) - ┑ /// - public Rune URCornerHvLt { get; set; } = '┑'; + public Rune URCornerHvLt { get; set; } = (Rune)'┑'; /// /// Box Drawings Down Light and Horizontal Heavy (U+2514) - ┒ /// - public Rune URCornerLtHv { get; set; } = '┒'; + public Rune URCornerLtHv { get; set; } = (Rune)'┒'; /// /// Box Drawings Double Vertical and Single Left (U+2556) - ╖ /// - public Rune URCornerDblSingle { get; set; } = '╖'; + public Rune URCornerDblSingle { get; set; } = (Rune)'╖'; /// /// Box Drawings Single Vertical and Double Left (U+2555) - ╕ /// - public Rune URCornerSingleDbl { get; set; } = '╕'; + public Rune URCornerSingleDbl { get; set; } = (Rune)'╕'; #endregion #region ----------------- Lower Right Corners ----------------- /// /// Box Drawings Lower Right Corner - Light (U+2518) - ┘ /// - public Rune LRCorner { get; set; } = '┘'; + public Rune LRCorner { get; set; } = (Rune)'┘'; /// /// Box Drawings Lower Right Corner - Double (U+255D) - ╝ /// - public Rune LRCornerDbl { get; set; } = '╝'; + public Rune LRCornerDbl { get; set; } = (Rune)'╝'; /// /// Box Drawings Lower Right Corner - Rounded (U+256F) - ╯ /// - public Rune LRCornerR { get; set; } = '╯'; + public Rune LRCornerR { get; set; } = (Rune)'╯'; /// /// Box Drawings Lower Right Corner - Heavy (U+251B) - ┛ /// - public Rune LRCornerHv { get; set; } = '┛'; + public Rune LRCornerHv { get; set; } = (Rune)'┛'; /// /// Box Drawings Lower Right Corner - Double Vertical and Single Horizontal (U+255C) - ╜ /// - public Rune LRCornerDblSingle { get; set; } = '╜'; + public Rune LRCornerDblSingle { get; set; } = (Rune)'╜'; /// /// Box Drawings Lower Right Corner - Single Vertical and Double Horizontal (U+255B) - ╛ /// - public Rune LRCornerSingleDbl { get; set; } = '╛'; + public Rune LRCornerSingleDbl { get; set; } = (Rune)'╛'; /// /// Box Drawings Lower Right Corner - Light Vertical and Heavy Horizontal (U+2519) - ┙ /// - public Rune LRCornerLtHv { get; set; } = '┙'; + public Rune LRCornerLtHv { get; set; } = (Rune)'┙'; /// /// Box Drawings Lower Right Corner - Heavy Vertical and Light Horizontal (U+251A) - ┚ /// - public Rune LRCornerHvLt { get; set; } = '┚'; + public Rune LRCornerHvLt { get; set; } = (Rune)'┚'; #endregion #region ----------------- Tees ----------------- /// /// Box Drawings Left Tee - Single Vertical and Single Horizontal (U+251C) - ├ /// - public Rune LeftTee { get; set; } = '├'; + public Rune LeftTee { get; set; } = (Rune)'├'; /// /// Box Drawings Left Tee - Single Vertical and Double Horizontal (U+255E) - ╞ /// - public Rune LeftTeeDblH { get; set; } = '╞'; + public Rune LeftTeeDblH { get; set; } = (Rune)'╞'; /// /// Box Drawings Left Tee - Double Vertical and Single Horizontal (U+255F) - ╟ /// - public Rune LeftTeeDblV { get; set; } = '╟'; + public Rune LeftTeeDblV { get; set; } = (Rune)'╟'; /// /// Box Drawings Left Tee - Double Vertical and Double Horizontal (U+2560) - ╠ /// - public Rune LeftTeeDbl { get; set; } = '╠'; + public Rune LeftTeeDbl { get; set; } = (Rune)'╠'; /// /// Box Drawings Left Tee - Heavy Horizontal and Light Vertical (U+2523) - ┝ /// - public Rune LeftTeeHvH { get; set; } = '┝'; + public Rune LeftTeeHvH { get; set; } = (Rune)'┝'; /// /// Box Drawings Left Tee - Light Horizontal and Heavy Vertical (U+252B) - ┠ /// - public Rune LeftTeeHvV { get; set; } = '┠'; + public Rune LeftTeeHvV { get; set; } = (Rune)'┠'; /// /// Box Drawings Left Tee - Heavy Vertical and Heavy Horizontal (U+2527) - ┣ /// - public Rune LeftTeeHvDblH { get; set; } = '┣'; + public Rune LeftTeeHvDblH { get; set; } = (Rune)'┣'; /// /// Box Drawings Righ Tee - Single Vertical and Single Horizontal (U+2524) - ┤ /// - public Rune RightTee { get; set; } = '┤'; + public Rune RightTee { get; set; } = (Rune)'┤'; /// /// Box Drawings Right Tee - Single Vertical and Double Horizontal (U+2561) - ╡ /// - public Rune RightTeeDblH { get; set; } = '╡'; + public Rune RightTeeDblH { get; set; } = (Rune)'╡'; /// /// Box Drawings Right Tee - Double Vertical and Single Horizontal (U+2562) - ╢ /// - public Rune RightTeeDblV { get; set; } = '╢'; + public Rune RightTeeDblV { get; set; } = (Rune)'╢'; /// /// Box Drawings Right Tee - Double Vertical and Double Horizontal (U+2563) - ╣ /// - public Rune RightTeeDbl { get; set; } = '╣'; + public Rune RightTeeDbl { get; set; } = (Rune)'╣'; /// /// Box Drawings Right Tee - Heavy Horizontal and Light Vertical (U+2528) - ┥ /// - public Rune RightTeeHvH { get; set; } = '┥'; + public Rune RightTeeHvH { get; set; } = (Rune)'┥'; /// /// Box Drawings Right Tee - Light Horizontal and Heavy Vertical (U+2530) - ┨ /// - public Rune RightTeeHvV { get; set; } = '┨'; + public Rune RightTeeHvV { get; set; } = (Rune)'┨'; /// /// Box Drawings Right Tee - Heavy Vertical and Heavy Horizontal (U+252C) - ┫ /// - public Rune RightTeeHvDblH { get; set; } = '┫'; + public Rune RightTeeHvDblH { get; set; } = (Rune)'┫'; /// /// Box Drawings Top Tee - Single Vertical and Single Horizontal (U+252C) - ┬ /// - public Rune TopTee { get; set; } = '┬'; + public Rune TopTee { get; set; } = (Rune)'┬'; /// /// Box Drawings Top Tee - Single Vertical and Double Horizontal (U+2564) - ╤ /// - public Rune TopTeeDblH { get; set; } = '╤'; + public Rune TopTeeDblH { get; set; } = (Rune)'╤'; /// /// Box Drawings Top Tee - Double Vertical and Single Horizontal (U+2565) - ╥ /// - public Rune TopTeeDblV { get; set; } = '╥'; + public Rune TopTeeDblV { get; set; } = (Rune)'╥'; /// /// Box Drawings Top Tee - Double Vertical and Double Horizontal (U+2566) - ╦ /// - public Rune TopTeeDbl { get; set; } = '╦'; + public Rune TopTeeDbl { get; set; } = (Rune)'╦'; /// /// Box Drawings Top Tee - Heavy Horizontal and Light Vertical (U+252F) - ┯ /// - public Rune TopTeeHvH { get; set; } = '┯'; + public Rune TopTeeHvH { get; set; } = (Rune)'┯'; /// /// Box Drawings Top Tee - Light Horizontal and Heavy Vertical (U+2537) - ┰ /// - public Rune TopTeeHvV { get; set; } = '┰'; + public Rune TopTeeHvV { get; set; } = (Rune)'┰'; /// /// Box Drawings Top Tee - Heavy Vertical and Heavy Horizontal (U+2533) - ┳ /// - public Rune TopTeeHvDblH { get; set; } = '┳'; + public Rune TopTeeHvDblH { get; set; } = (Rune)'┳'; /// /// Box Drawings Bottom Tee - Single Vertical and Single Horizontal (U+2534) - ┴ /// - public Rune BottomTee { get; set; } = '┴'; + public Rune BottomTee { get; set; } = (Rune)'┴'; /// /// Box Drawings Bottom Tee - Single Vertical and Double Horizontal (U+2567) - ╧ /// - public Rune BottomTeeDblH { get; set; } = '╧'; + public Rune BottomTeeDblH { get; set; } = (Rune)'╧'; /// /// Box Drawings Bottom Tee - Double Vertical and Single Horizontal (U+2568) - ╨ /// - public Rune BottomTeeDblV { get; set; } = '╨'; + public Rune BottomTeeDblV { get; set; } = (Rune)'╨'; /// /// Box Drawings Bottom Tee - Double Vertical and Double Horizontal (U+2569) - ╩ /// - public Rune BottomTeeDbl { get; set; } = '╩'; + public Rune BottomTeeDbl { get; set; } = (Rune)'╩'; /// /// Box Drawings Bottom Tee - Heavy Horizontal and Light Vertical (U+2535) - ┷ /// - public Rune BottomTeeHvH { get; set; } = '┷'; + public Rune BottomTeeHvH { get; set; } = (Rune)'┷'; /// /// Box Drawings Bottom Tee - Light Horizontal and Heavy Vertical (U+253D) - ┸ /// - public Rune BottomTeeHvV { get; set; } = '┸'; + public Rune BottomTeeHvV { get; set; } = (Rune)'┸'; /// /// Box Drawings Bottom Tee - Heavy Vertical and Heavy Horizontal (U+2539) - ┻ /// - public Rune BottomTeeHvDblH { get; set; } = '┻'; + public Rune BottomTeeHvDblH { get; set; } = (Rune)'┻'; #endregion @@ -621,37 +621,37 @@ namespace Terminal.Gui { /// /// Box Drawings Cross - Single Vertical and Single Horizontal (U+253C) - ┼ /// - public Rune Cross { get; set; } = '┼'; + public Rune Cross { get; set; } = (Rune)'┼'; /// /// Box Drawings Cross - Single Vertical and Double Horizontal (U+256A) - ╪ /// - public Rune CrossDblH { get; set; } = '╪'; + public Rune CrossDblH { get; set; } = (Rune)'╪'; /// /// Box Drawings Cross - Double Vertical and Single Horizontal (U+256B) - ╫ /// - public Rune CrossDblV { get; set; } = '╫'; + public Rune CrossDblV { get; set; } = (Rune)'╫'; /// /// Box Drawings Cross - Double Vertical and Double Horizontal (U+256C) - ╬ /// - public Rune CrossDbl { get; set; } = '╬'; + public Rune CrossDbl { get; set; } = (Rune)'╬'; /// /// Box Drawings Cross - Heavy Horizontal and Light Vertical (U+253F) - ┿ /// - public Rune CrossHvH { get; set; } = '┿'; + public Rune CrossHvH { get; set; } = (Rune)'┿'; /// /// Box Drawings Cross - Light Horizontal and Heavy Vertical (U+2541) - ╂ /// - public Rune CrossHvV { get; set; } = '╂'; + public Rune CrossHvV { get; set; } = (Rune)'╂'; /// /// Box Drawings Cross - Heavy Vertical and Heavy Horizontal (U+254B) - ╋ /// - public Rune CrossHv { get; set; } = '╋'; + public Rune CrossHv { get; set; } = (Rune)'╋'; #endregion } } diff --git a/Terminal.Gui/Drawing/LineCanvas.cs b/Terminal.Gui/Drawing/LineCanvas.cs index 8ea8b0a49..d0bb56e72 100644 --- a/Terminal.Gui/Drawing/LineCanvas.cs +++ b/Terminal.Gui/Drawing/LineCanvas.cs @@ -3,7 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; -using Rune = System.Rune; + namespace Terminal.Gui { diff --git a/Terminal.Gui/Drawing/Ruler.cs b/Terminal.Gui/Drawing/Ruler.cs index cb59040c1..4272b83e7 100644 --- a/Terminal.Gui/Drawing/Ruler.cs +++ b/Terminal.Gui/Drawing/Ruler.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Text; @@ -58,7 +57,7 @@ namespace Terminal.Gui { var vrule = _vTemplate.Repeat ((int)Math.Ceiling ((double)(Length + 2) / (double)_vTemplate.Length)) [start..(Length + start)]; for (var r = location.Y; r < location.Y + Length; r++) { Application.Driver.Move (location.X, r); - Application.Driver.AddRune (vrule [r - location.Y]); + Application.Driver.AddRune ((Rune)vrule [r - location.Y]); } } } diff --git a/Terminal.Gui/Drawing/Thickness.cs b/Terminal.Gui/Drawing/Thickness.cs index 176db55c8..a15bf8125 100644 --- a/Terminal.Gui/Drawing/Thickness.cs +++ b/Terminal.Gui/Drawing/Thickness.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Text; using System.Text.Json.Serialization; @@ -143,19 +142,19 @@ namespace Terminal.Gui { return Rect.Empty; } - System.Rune clearChar = ' '; - System.Rune leftChar = clearChar; - System.Rune rightChar = clearChar; - System.Rune topChar = clearChar; - System.Rune bottomChar = clearChar; + Rune clearChar = (Rune)' '; + Rune leftChar = clearChar; + Rune rightChar = clearChar; + Rune topChar = clearChar; + Rune bottomChar = clearChar; if ((ConsoleDriver.Diagnostics & ConsoleDriver.DiagnosticFlags.FramePadding) == ConsoleDriver.DiagnosticFlags.FramePadding) { - leftChar = 'L'; - rightChar = 'R'; - topChar = 'T'; - bottomChar = 'B'; + leftChar = (Rune)'L'; + rightChar = (Rune)'R'; + topChar = (Rune)'T'; + bottomChar = (Rune)'B'; if (!string.IsNullOrEmpty (label)) { - leftChar = rightChar = bottomChar = topChar = label [0]; + leftChar = rightChar = bottomChar = topChar = (Rune)label [0]; } } diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs index 437a6e4a4..e1b1a3bdb 100644 --- a/Terminal.Gui/Input/ShortcutHelper.cs +++ b/Terminal.Gui/Input/ShortcutHelper.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -27,7 +26,7 @@ namespace Terminal.Gui { /// /// The keystroke combination used in the as string. /// - public virtual ustring ShortcutTag => GetShortcutTag (shortcut); + public virtual string ShortcutTag => GetShortcutTag (shortcut); /// /// The action to run if the is defined. @@ -61,7 +60,7 @@ namespace Terminal.Gui { /// The shortcut key. /// The delimiter string. /// - public static ustring GetShortcutTag (Key shortcut, ustring delimiter = null) + public static string GetShortcutTag (Key shortcut, string delimiter = null) { if (shortcut == Key.Null) { return ""; @@ -71,7 +70,7 @@ namespace Terminal.Gui { if (delimiter == null) { delimiter = MenuBar.ShortcutDelimiter; } - ustring tag = ustring.Empty; + string tag = string.Empty; var sCut = GetKeyToString (k, out Key knm).ToString (); if (knm == Key.Unknown) { k &= ~Key.Unknown; @@ -81,25 +80,25 @@ namespace Terminal.Gui { tag = "Ctrl"; } if ((k & Key.ShiftMask) != 0) { - if (!tag.IsEmpty) { + if (!string.IsNullOrEmpty(tag)) { tag += delimiter; } tag += "Shift"; } if ((k & Key.AltMask) != 0) { - if (!tag.IsEmpty) { + if (!string.IsNullOrEmpty(tag)) { tag += delimiter; } tag += "Alt"; } - ustring [] keys = ustring.Make (sCut).Split (","); + string [] keys = sCut.Split (","); for (int i = 0; i < keys.Length; i++) { - var key = keys [i].TrimSpace (); + var key = keys [i].Trim (); if (key == Key.AltMask.ToString () || key == Key.ShiftMask.ToString () || key == Key.CtrlMask.ToString ()) { continue; } - if (!tag.IsEmpty) { + if (!string.IsNullOrEmpty(tag)) { tag += delimiter; } if (!key.Contains ("F") && key.Length > 2 && keys.Length == 1) { @@ -120,7 +119,7 @@ namespace Terminal.Gui { /// /// The key to extract. /// Correspond to the non modifier key. - public static ustring GetKeyToString (Key key, out Key knm) + public static string GetKeyToString (Key key, out Key knm) { if (key == Key.Null) { knm = Key.Null; @@ -150,10 +149,10 @@ namespace Terminal.Gui { /// /// The key as string. /// The delimiter string. - public static Key GetShortcutFromTag (ustring tag, ustring delimiter = null) + public static Key GetShortcutFromTag (string tag, string delimiter = null) { var sCut = tag; - if (sCut.IsEmpty) { + if (string.IsNullOrEmpty(sCut)) { return default; } @@ -163,7 +162,7 @@ namespace Terminal.Gui { delimiter = MenuBar.ShortcutDelimiter; } - ustring [] keys = sCut.Split (delimiter); + string [] keys = sCut.Split (delimiter); for (int i = 0; i < keys.Length; i++) { var k = keys [i]; if (k == "Ctrl") { diff --git a/Terminal.Gui/Resources/config.json b/Terminal.Gui/Resources/config.json index 10d489107..49e669d53 100644 --- a/Terminal.Gui/Resources/config.json +++ b/Terminal.Gui/Resources/config.json @@ -35,7 +35,6 @@ "Ctrl" ] }, - "Application.UseSystemConsole": false, "Application.IsMouseDisabled": false, "Theme": "Default", "Themes": [ diff --git a/Terminal.Gui/StringExtensions.cs b/Terminal.Gui/StringExtensions.cs deleted file mode 100644 index 4242dec5c..000000000 --- a/Terminal.Gui/StringExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text; - -namespace Terminal.Gui { - /// - /// Extension helper of to work with specific text manipulation./> - /// - public static class StringExtensions { - /// - /// Repeats the times. - /// - /// The text to repeat. - /// Number of times to repeat the text. - /// - /// The text repeated if is greater than zero, - /// otherwise . - /// - public static string Repeat (this string instr, int n) - { - if (n <= 0) { - return null; - } - - if (string.IsNullOrEmpty (instr) || n == 1) { - return instr; - } - - return new StringBuilder (instr.Length * n) - .Insert (0, instr, n) - .ToString (); - } - } -} diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index d70fbb6b3..9f9e582b6 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -26,7 +26,6 @@ - diff --git a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs index 4ca620fa7..5bff31c6c 100644 --- a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Text; namespace Terminal.Gui { @@ -30,12 +31,12 @@ namespace Terminal.Gui { this.textField = textField; SelectionKey = Key.Tab; - ColorScheme = new ColorScheme{ - Normal = new Attribute(Color.DarkGray,0), - Focus = new Attribute(Color.DarkGray,0), - HotNormal = new Attribute(Color.DarkGray,0), - HotFocus = new Attribute(Color.DarkGray,0), - Disabled = new Attribute(Color.DarkGray,0), + ColorScheme = new ColorScheme { + Normal = new Attribute (Color.DarkGray, 0), + Focus = new Attribute (Color.DarkGray, 0), + HotNormal = new Attribute (Color.DarkGray, 0), + HotFocus = new Attribute (Color.DarkGray, 0), + Disabled = new Attribute (Color.DarkGray, 0), }; } @@ -64,16 +65,13 @@ namespace Terminal.Gui { } else if (key == Key.CursorDown) { return this.CycleSuggestion (-1); - } - else if(key == CloseKey && Suggestions.Any()) - { - ClearSuggestions(); + } else if (key == CloseKey && Suggestions.Any ()) { + ClearSuggestions (); _suspendSuggestions = true; return true; } - if(char.IsLetterOrDigit((char)kb.KeyValue)) - { + if (char.IsLetterOrDigit ((char)kb.KeyValue)) { _suspendSuggestions = false; } @@ -84,8 +82,7 @@ namespace Terminal.Gui { /// public override void GenerateSuggestions (AutocompleteContext context) { - if(_suspendSuggestions) - { + if (_suspendSuggestions) { return; } base.GenerateSuggestions (context); @@ -107,14 +104,13 @@ namespace Terminal.Gui { var suggestion = this.Suggestions.ElementAt (this.SelectedIdx); var fragment = suggestion.Replacement.Substring (suggestion.Remove); - int spaceAvailable = textField.Bounds.Width - textField.Text.ConsoleWidth; - int spaceRequired = fragment.Sum(c=>Rune.ColumnWidth(c)); + int spaceAvailable = textField.Bounds.Width - textField.Text.GetColumns (); + int spaceRequired = fragment.EnumerateRunes ().Sum (c => c.GetColumns ()); - if(spaceAvailable < spaceRequired) - { - fragment = new string( - fragment.TakeWhile(c=> (spaceAvailable -= Rune.ColumnWidth(c)) >= 0) - .ToArray() + if (spaceAvailable < spaceRequired) { + fragment = new string ( + fragment.TakeWhile (c => (spaceAvailable -= ((Rune)c).GetColumns ()) >= 0) + .ToArray () ); } @@ -137,7 +133,7 @@ namespace Terminal.Gui { newText += insert.Replacement; textField.Text = newText; - this.textField.MoveEnd(); + this.textField.MoveEnd (); this.ClearSuggestions (); return true; diff --git a/Terminal.Gui/Text/Autocomplete/AutocompleteContext.cs b/Terminal.Gui/Text/Autocomplete/AutocompleteContext.cs index 17c90d2f3..1a9947972 100644 --- a/Terminal.Gui/Text/Autocomplete/AutocompleteContext.cs +++ b/Terminal.Gui/Text/Autocomplete/AutocompleteContext.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Rune = System.Rune; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs index a12c93161..0aec12ae2 100644 --- a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using Rune = System.Rune; + namespace Terminal.Gui { diff --git a/Terminal.Gui/Text/Autocomplete/ISuggestionGenerator.cs b/Terminal.Gui/Text/Autocomplete/ISuggestionGenerator.cs index 7ad64569f..19698c33c 100644 --- a/Terminal.Gui/Text/Autocomplete/ISuggestionGenerator.cs +++ b/Terminal.Gui/Text/Autocomplete/ISuggestionGenerator.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Rune = System.Rune; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index f24cf6e55..fb2f49cdd 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; -using Rune = System.Rune; + namespace Terminal.Gui { @@ -275,7 +275,7 @@ namespace Terminal.Gui { /// trueif the key can be handled falseotherwise. public override bool ProcessKey (KeyEvent kb) { - if (SuggestionGenerator.IsWordChar ((char)kb.Key)) { + if (SuggestionGenerator.IsWordChar ((Rune)(char)kb.Key)) { Visible = true; ManipulatePopup (); closed = false; diff --git a/Terminal.Gui/Text/Autocomplete/SingleWordSuggestionGenerator.cs b/Terminal.Gui/Text/Autocomplete/SingleWordSuggestionGenerator.cs index 3af30b8c1..d41775a89 100644 --- a/Terminal.Gui/Text/Autocomplete/SingleWordSuggestionGenerator.cs +++ b/Terminal.Gui/Text/Autocomplete/SingleWordSuggestionGenerator.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Rune = System.Rune; + namespace Terminal.Gui { @@ -50,7 +50,7 @@ namespace Terminal.Gui { /// public virtual bool IsWordChar (Rune rune) { - return Char.IsLetterOrDigit ((char)rune); + return Char.IsLetterOrDigit ((char)rune.Value); } /// @@ -92,7 +92,7 @@ namespace Terminal.Gui { // we are at the end of a word. Work out what has been typed so far while (endIdx-- > 0) { if (IsWordChar (line [endIdx])) { - sb.Insert (0, (char)line [endIdx]); + sb.Insert (0, (char)line [endIdx].Value); } else { break; } diff --git a/Terminal.Gui/Text/RuneExtensions.cs b/Terminal.Gui/Text/RuneExtensions.cs new file mode 100644 index 000000000..d27e6ff82 --- /dev/null +++ b/Terminal.Gui/Text/RuneExtensions.cs @@ -0,0 +1,311 @@ +using System.Globalization; +using System.Text; + +namespace Terminal.Gui; + +/// +/// Extends to support TUI text manipulation. +/// +public static class RuneExtensions { + /// + /// Maximum Unicode code point. + /// + public static int MaxUnicodeCodePoint = 0x10FFFF; + + /// + /// Gets the number of columns the rune occupies in the terminal. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The rune to measure. + /// + /// The number of columns required to fit the rune, 0 if the argument is the null character, or + /// -1 if the value is not printable, + /// otherwise the number of columns that the rune occupies. + /// + public static int GetColumns (this Rune rune) + { + // TODO: I believe there is a way to do this without using our own tables, using Rune. + var codePoint = rune.Value; + switch (codePoint) { + case < 0x20: + case >= 0x7f and < 0xa0: + return -1; + case < 0x7f: + return 1; + } + /* binary search in table of non-spacing characters */ + if (BiSearch (codePoint, _combining, _combining.GetLength (0) - 1) != 0) { + return 0; + } + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + return 1 + (BiSearch (codePoint, _combiningWideChars, _combiningWideChars.GetLength (0) - 1) != 0 ? 1 : 0); + } + + /// + /// Returns if the rune is a combining character. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// + /// + public static bool IsCombiningMark (this System.Text.Rune rune) + { + UnicodeCategory category = Rune.GetUnicodeCategory (rune); + return Rune.GetUnicodeCategory (rune) == UnicodeCategory.NonSpacingMark + || category == UnicodeCategory.SpacingCombiningMark + || category == UnicodeCategory.EnclosingMark; + } + + /// + /// Ensures the rune is not a control character and can be displayed by translating characters below 0x20 + /// to equivalent, printable, Unicode chars. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// + /// + public static Rune MakePrintable (this System.Text.Rune rune) => Rune.IsControl (rune) ? new Rune (rune.Value + 0x2400) : rune; + + /// + /// Get number of bytes required to encode the rune, based on the provided encoding. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The rune to probe. + /// The encoding used; the default is UTF8. + /// The number of bytes required. + public static int GetEncodingLength (this Rune rune, Encoding encoding = null) + { + encoding ??= Encoding.UTF8; + var bytes = encoding.GetBytes (rune.ToString ().ToCharArray ()); + var offset = 0; + if (bytes [^1] == 0) { + offset++; + } + return bytes.Length - offset; + } + + /// + /// Writes into the destination buffer starting at offset the UTF8 encoded version of the rune. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The rune to encode. + /// The destination buffer. + /// Starting offset to look into. + /// Number of bytes valid in the buffer, or -1 to make it the length of the buffer. + /// he number of bytes written into the destination buffer. + public static int Encode (this Rune rune, byte [] dest, int start = 0, int count = -1) + { + var bytes = Encoding.UTF8.GetBytes (rune.ToString ()); + var length = 0; + for (var i = 0; i < (count == -1 ? bytes.Length : count); i++) { + if (bytes [i] == 0) { + break; + } + dest [start + i] = bytes [i]; + length++; + } + return length; + } + + /// + /// Attempts to decode the rune as a surrogate pair to UTF-16. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The rune to decode. + /// The chars if the rune is a surrogate pair. Null otherwise. + /// if the rune is a valid surrogate pair; otherwise. + public static bool DecodeSurrogatePair (this Rune rune, out char [] chars) + { + if (rune.IsSurrogatePair ()) { + chars = rune.ToString ().ToCharArray (); + return true; + } + chars = null; + return false; + } + + /// + /// Attempts to encode (as UTF-16) a surrogate pair. + /// + /// The high surrogate code point. + /// The low surrogate code point. + /// The encoded rune. + /// if the encoding succeeded; otherwise. + public static bool EncodeSurrogatePair (char highSurrogate, char lowSurrogate, out Rune result) + { + result = default; + if (char.IsSurrogatePair (highSurrogate, lowSurrogate)) { + result = (Rune)char.ConvertToUtf32 (highSurrogate, lowSurrogate); + return true; + } + return false; + } + + /// + /// Reports whether a rune is a surrogate code point. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The rune to probe. + /// if the rune is a surrogate code point; otherwise. + public static bool IsSurrogatePair (this Rune rune) + { + return char.IsSurrogatePair (rune.ToString (), 0); + } + + /// + /// Reports if the provided array of bytes can be encoded as UTF-8. + /// + /// The byte array to probe. + /// true if is valid; otherwise, false. + public static bool CanBeEncodedAsRune (byte [] buffer) + { + var str = Encoding.Unicode.GetString (buffer); + foreach (var rune in str.EnumerateRunes ()) { + if (rune == Rune.ReplacementChar) { + return false; + } + } + return true; + } + + // ---------------- implementation details ------------------ + // TODO: Can this be handled by the new .NET 8 Rune type? + static readonly int [,] _combining = new int [,] { + { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, + { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, + { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, + { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, + { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, + { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, + { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, + { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, + { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, + { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, + { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, + { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, + { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, + { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, + { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, + { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, + { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x2E9A, 0x2E9A }, + { 0x2EF4, 0x2EFF }, { 0x2FD6, 0x2FEF }, { 0x2FFC, 0x2FFF }, + { 0x31E4, 0x31EF }, { 0x321F, 0x321F }, { 0xA48D, 0xA48F }, + { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, { 0xA825, 0xA826 }, + { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, { 0xFE1A, 0xFE1F }, + { 0xFE20, 0xFE23 }, { 0xFE53, 0xFE53 }, { 0xFE67, 0xFE67 }, + { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, + { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, + { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, + { 0xE0100, 0xE01EF } + }; + + static readonly int [,] _combiningWideChars = new int [,] { + /* Hangul Jamo init. consonants - 0x1100, 0x11ff */ + /* Miscellaneous Technical - 0x2300, 0x23ff */ + /* Hangul Syllables - 0x11a8, 0x11c2 */ + /* CJK Compatibility Ideographs - f900, fad9 */ + /* Vertical forms - fe10, fe19 */ + /* CJK Compatibility Forms - fe30, fe4f */ + /* Fullwidth Forms - ff01, ffee */ + /* Alphabetic Presentation Forms - 0xFB00, 0xFb4f */ + /* Chess Symbols - 0x1FA00, 0x1FA0f */ + + { 0x1100, 0x115f }, { 0x231a, 0x231b }, { 0x2329, 0x232a }, + { 0x23e9, 0x23ec }, { 0x23f0, 0x23f0 }, { 0x23f3, 0x23f3 }, + { 0x25fd, 0x25fe }, { 0x2614, 0x2615 }, { 0x2648, 0x2653 }, + { 0x267f, 0x267f }, { 0x2693, 0x2693 }, { 0x26a1, 0x26a1 }, + { 0x26aa, 0x26ab }, { 0x26bd, 0x26be }, { 0x26c4, 0x26c5 }, + { 0x26ce, 0x26ce }, { 0x26d4, 0x26d4 }, { 0x26ea, 0x26ea }, + { 0x26f2, 0x26f3 }, { 0x26f5, 0x26f5 }, { 0x26fa, 0x26fa }, + { 0x26fd, 0x26fd }, { 0x2705, 0x2705 }, { 0x270a, 0x270b }, + { 0x2728, 0x2728 }, { 0x274c, 0x274c }, { 0x274e, 0x274e }, + { 0x2753, 0x2755 }, { 0x2757, 0x2757 }, { 0x2795, 0x2797 }, + { 0x27b0, 0x27b0 }, { 0x27bf, 0x27bf }, { 0x2b1b, 0x2b1c }, + { 0x2b50, 0x2b50 }, { 0x2b55, 0x2b55 }, { 0x2e80, 0x303e }, + { 0x3041, 0x3096 }, { 0x3099, 0x30ff }, { 0x3105, 0x312f }, + { 0x3131, 0x318e }, { 0x3190, 0x3247 }, { 0x3250, 0x4dbf }, + { 0x4e00, 0xa4c6 }, { 0xa960, 0xa97c }, { 0xac00, 0xd7a3 }, + { 0xf900, 0xfaff }, { 0xfe10, 0xfe1f }, { 0xfe30, 0xfe6b }, + { 0xff01, 0xff60 }, { 0xffe0, 0xffe6 }, + { 0x16fe0, 0x16fe4 }, { 0x16ff0, 0x16ff1 }, { 0x17000, 0x187f7 }, + { 0x18800, 0x18cd5 }, { 0x18d00, 0x18d08 }, { 0x1aff0, 0x1affc }, + { 0x1b000, 0x1b122 }, { 0x1b150, 0x1b152 }, { 0x1b164, 0x1b167 }, { 0x1b170, 0x1b2fb }, { 0x1d538, 0x1d550 }, + { 0x1f004, 0x1f004 }, { 0x1f0cf, 0x1f0cf }, /*{ 0x1f100, 0x1f10a },*/ + //{ 0x1f110, 0x1f12d }, { 0x1f130, 0x1f169 }, { 0x1f170, 0x1f1ac }, + { 0x1f18f, 0x1f199 }, + { 0x1f1e6, 0x1f1ff }, { 0x1f200, 0x1f202 }, { 0x1f210, 0x1f23b }, + { 0x1f240, 0x1f248 }, { 0x1f250, 0x1f251 }, { 0x1f260, 0x1f265 }, + { 0x1f300, 0x1f320 }, { 0x1f32d, 0x1f33e }, { 0x1f340, 0x1f37e }, + { 0x1f380, 0x1f393 }, { 0x1f3a0, 0x1f3ca }, { 0x1f3cf, 0x1f3d3 }, + { 0x1f3e0, 0x1f3f0 }, { 0x1f3f4, 0x1f3f4 }, { 0x1f3f8, 0x1f43e }, + { 0x1f440, 0x1f44e }, { 0x1f450, 0x1f4fc }, { 0x1f4ff, 0x1f53d }, + { 0x1f54b, 0x1f54e }, { 0x1f550, 0x1f567 }, { 0x1f57a, 0x1f57a }, + { 0x1f595, 0x1f596 }, { 0x1f5a4, 0x1f5a4 }, { 0x1f5fb, 0x1f606 }, + { 0x1f607, 0x1f64f }, { 0x1f680, 0x1f6c5 }, { 0x1f6cc, 0x1f6cc }, + { 0x1f6d0, 0x1f6d2 }, { 0x1f6d5, 0x1f6d7 }, { 0x1f6dd, 0x1f6df }, { 0x1f6eb, 0x1f6ec }, + { 0x1f6f4, 0x1f6fc }, { 0x1f7e0, 0x1f7eb }, { 0x1f7f0, 0x1f7f0 }, { 0x1f90c, 0x1f93a }, + { 0x1f93c, 0x1f945 }, { 0x1f947, 0x1f97f }, { 0x1f980, 0x1f9cc }, + { 0x1f9cd, 0x1f9ff }, { 0x1fa70, 0x1fa74 }, { 0x1fa78, 0x1fa7c }, { 0x1fa80, 0x1fa86 }, + { 0x1fa90, 0x1faac }, { 0x1fab0, 0x1faba }, { 0x1fac0, 0x1fac5 }, + { 0x1fad0, 0x1fad9 }, { 0x1fae0, 0x1fae7 }, { 0x1faf0, 0x1faf6 }, { 0x20000, 0x2fffd }, { 0x30000, 0x3fffd }, + //{ 0xe0100, 0xe01ef }, { 0xf0000, 0xffffd }, { 0x100000, 0x10fffd } + }; + + static int BiSearch (int rune, int [,] table, int max) + { + var min = 0; + + if (rune < table [0, 0] || rune > table [max, 1]) { + return 0; + } + while (max >= min) { + var mid = (min + max) / 2; + if (rune > table [mid, 1]) { + min = mid + 1; + } else if (rune < table [mid, 0]) { + max = mid - 1; + } else { + return 1; + } + } + + return 0; + } +} \ No newline at end of file diff --git a/Terminal.Gui/Text/StringExtensions.cs b/Terminal.Gui/Text/StringExtensions.cs new file mode 100644 index 000000000..a1387718b --- /dev/null +++ b/Terminal.Gui/Text/StringExtensions.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Terminal.Gui; +/// +/// Extensions to to support TUI text manipulation. +/// +public static class StringExtensions { + /// + /// Repeats the string times. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The text to repeat. + /// Number of times to repeat the text. + /// + /// The text repeated if is greater than zero, + /// otherwise . + /// + public static string Repeat (this string str, int n) + { + if (n <= 0) { + return null; + } + + if (string.IsNullOrEmpty (str) || n == 1) { + return str; + } + + return new StringBuilder (str.Length * n) + .Insert (0, str, n) + .ToString (); + } + + /// + /// Gets the number of columns the string occupies in the terminal. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The string to measure. + /// + public static int GetColumns (this string str) + { + return str == null ? 0 : str.EnumerateRunes ().Sum (r => Math.Max (r.GetColumns (), 0)); + } + + /// + /// Gets the number of runes in the string. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The string to count. + /// + public static int GetRuneCount (this string str) => str.EnumerateRunes ().Count (); + + /// + /// Converts the string into a array. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The string to convert. + /// + public static Rune [] ToRunes (this string str) => str.EnumerateRunes ().ToArray (); + + /// + /// Converts the string into a . + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The string to convert. + /// + public static List ToRuneList (this string str) => str.EnumerateRunes ().ToList (); + + /// + /// Unpacks the first UTF-8 encoding in the string and returns the rune and its width in bytes. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The string to decode. + /// Starting offset. + /// Number of bytes in the buffer, or -1 to make it the length of the buffer. + /// + public static (Rune Rune, int Size) DecodeRune (this string str, int start = 0, int count = -1) + { + var rune = str.EnumerateRunes ().ToArray () [start]; + var bytes = Encoding.UTF8.GetBytes (rune.ToString ()); + if (count == -1) { + count = bytes.Length; + } + var operationStatus = Rune.DecodeFromUtf8 (bytes, out rune, out int bytesConsumed); + if (operationStatus == System.Buffers.OperationStatus.Done && bytesConsumed >= count) { + return (rune, bytesConsumed); + } + return (Rune.ReplacementChar, 1); + } + + /// + /// Unpacks the last UTF-8 encoding in the string. + /// + /// + /// This is a Terminal.Gui extension method to to support TUI text manipulation. + /// + /// The string to decode. + /// Index in string to stop at; if -1, use the buffer length. + /// + public static (Rune rune, int size) DecodeLastRune (this string str, int end = -1) + { + var rune = str.EnumerateRunes ().ToArray () [end == -1 ? ^1 : end]; + var bytes = Encoding.UTF8.GetBytes (rune.ToString ()); + var operationStatus = Rune.DecodeFromUtf8 (bytes, out rune, out int bytesConsumed); + if (operationStatus == System.Buffers.OperationStatus.Done) { + return (rune, bytesConsumed); + } + return (Rune.ReplacementChar, 1); + } + + /// + /// Converts a generic collection into a string. + /// + /// The enumerable rune to convert. + /// + public static string ToString (IEnumerable runes) + { + var str = string.Empty; + + foreach (var rune in runes) { + str += rune.ToString (); + } + + return str; + } + + /// + /// Converts a byte generic collection into a string in the provided encoding (default is UTF8) + /// + /// The enumerable byte to convert. + /// The encoding to be used. + /// + public static string ToString (IEnumerable bytes, Encoding encoding = null) + { + if (encoding == null) { + encoding = Encoding.UTF8; + } + return encoding.GetString (bytes.ToArray ()); + } +} diff --git a/Terminal.Gui/Text/TextFormatter.cs b/Terminal.Gui/Text/TextFormatter.cs index 97b02b587..bc50b4418 100644 --- a/Terminal.Gui/Text/TextFormatter.cs +++ b/Terminal.Gui/Text/TextFormatter.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; -using NStack; -using Rune = System.Rune; namespace Terminal.Gui { /// @@ -12,19 +10,20 @@ namespace Terminal.Gui { /// public enum TextAlignment { /// - /// Aligns the text to the left of the frame. + /// The text will be left-aligned. /// Left, /// - /// Aligns the text to the right side of the frame. + /// The text will be right-aligned. /// Right, /// - /// Centers the text in the frame. + /// The text will be centered horizontally. /// Centered, /// - /// Shows the text as justified text in the frame. + /// The text will be justified (spaces will be added to existing spaces such that + /// the text fills the container horizontally). /// Justified } @@ -34,19 +33,20 @@ namespace Terminal.Gui { /// public enum VerticalTextAlignment { /// - /// Aligns the text to the top of the frame. + /// The text will be top-aligned. /// Top, /// - /// Aligns the text to the bottom of the frame. + /// The text will be bottom-aligned. /// Bottom, /// - /// Centers the text verticaly in the frame. + /// The text will centered vertically. /// Middle, /// - /// Shows the text as justified text in the frame. + /// The text will be justified (spaces will be added to existing spaces such that + /// the text fills the container vertically). /// Justified } @@ -112,17 +112,17 @@ namespace Terminal.Gui { } /// - /// Provides text formatting capabilities for console apps. Supports, hotkeys, horizontal alignment, multiple lines, and word-based line wrap. + /// Provides text formatting. Supports s, horizontal alignment, vertical alignment, multiple lines, and word-based line wrap. /// public class TextFormatter { #region Static Members - static ustring StripCRLF (ustring str, bool keepNewLine = false) + static string StripCRLF (string str, bool keepNewLine = false) { var runes = str.ToRuneList (); for (int i = 0; i < runes.Count; i++) { - switch (runes [i]) { + switch ((char)runes [i].Value) { case '\n': if (!keepNewLine) { runes.RemoveAt (i); @@ -130,7 +130,7 @@ namespace Terminal.Gui { break; case '\r': - if ((i + 1) < runes.Count && runes [i + 1] == '\n') { + if ((i + 1) < runes.Count && runes [i + 1].Value == '\n') { runes.RemoveAt (i); if (!keepNewLine) { runes.RemoveAt (i); @@ -144,19 +144,19 @@ namespace Terminal.Gui { break; } } - return ustring.Make (runes); + return StringExtensions.ToString (runes); } - static ustring ReplaceCRLFWithSpace (ustring str) + static string ReplaceCRLFWithSpace (string str) { var runes = str.ToRuneList (); for (int i = 0; i < runes.Count; i++) { - switch (runes [i]) { + switch (runes [i].Value) { case '\n': runes [i] = (Rune)' '; break; case '\r': - if ((i + 1) < runes.Count && runes [i + 1] == '\n') { + if ((i + 1) < runes.Count && runes [i + 1].Value == '\n') { runes [i] = (Rune)' '; runes.RemoveAt (i + 1); i++; @@ -166,7 +166,7 @@ namespace Terminal.Gui { break; } } - return ustring.Make (runes); + return StringExtensions.ToString (runes); } /// @@ -175,29 +175,29 @@ namespace Terminal.Gui { /// /// The text. /// A list of text without the newline characters. - public static List SplitNewLine (ustring text) + public static List SplitNewLine (string text) { var runes = text.ToRuneList (); - var lines = new List (); + var lines = new List (); var start = 0; var end = 0; for (int i = 0; i < runes.Count; i++) { end = i; - switch (runes [i]) { + switch (runes [i].Value) { case '\n': - lines.Add (ustring.Make (runes.GetRange (start, end - start))); + lines.Add (StringExtensions.ToString (runes.GetRange (start, end - start))); i++; start = i; break; case '\r': - if ((i + 1) < runes.Count && runes [i + 1] == '\n') { - lines.Add (ustring.Make (runes.GetRange (start, end - start))); + if ((i + 1) < runes.Count && runes [i + 1].Value == '\n') { + lines.Add (StringExtensions.ToString (runes.GetRange (start, end - start))); i += 2; start = i; } else { - lines.Add (ustring.Make (runes.GetRange (start, end - start))); + lines.Add (StringExtensions.ToString (runes.GetRange (start, end - start))); i++; start = i; } @@ -205,11 +205,11 @@ namespace Terminal.Gui { } } if (runes.Count > 0 && lines.Count == 0) { - lines.Add (ustring.Make (runes)); + lines.Add (StringExtensions.ToString (runes)); } else if (runes.Count > 0 && start < runes.Count) { - lines.Add (ustring.Make (runes.GetRange (start, runes.Count - start))); + lines.Add (StringExtensions.ToString (runes.GetRange (start, runes.Count - start))); } else { - lines.Add (ustring.Make ("")); + lines.Add (""); } return lines; } @@ -228,16 +228,16 @@ namespace Terminal.Gui { return text; // if value is not wide enough - if (text.Sum (c => Rune.ColumnWidth (c)) < width) { + if (text.EnumerateRunes ().Sum (c => c.GetColumns ()) < width) { // pad it out with spaces to the given alignment - int toPad = width - (text.Sum (c => Rune.ColumnWidth (c))); + int toPad = width - (text.EnumerateRunes ().Sum (c => c.GetColumns ())); return text + new string (' ', toPad); } // value is too wide - return new string (text.TakeWhile (c => (width -= Rune.ColumnWidth (c)) >= 0).ToArray ()); + return new string (text.TakeWhile (c => (width -= ((Rune)c).GetColumns ()) >= 0).ToArray ()); } /// @@ -261,7 +261,7 @@ namespace Terminal.Gui { /// If is at most one space will be preserved at the end of the last line. /// /// - public static List WordWrapText (ustring text, int width, bool preserveTrailingSpaces = false, int tabWidth = 0, + public static List WordWrapText (string text, int width, bool preserveTrailingSpaces = false, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { if (width < 0) { @@ -269,9 +269,9 @@ namespace Terminal.Gui { } int start = 0, end; - var lines = new List (); + var lines = new List (); - if (ustring.IsNullOrEmpty (text)) { + if (string.IsNullOrEmpty (text)) { return lines; } @@ -280,13 +280,13 @@ namespace Terminal.Gui { while ((end = start) < runes.Count) { end = GetNextWhiteSpace (start, width, out bool incomplete); if (end == 0 && incomplete) { - start = text.RuneCount; + start = text.GetRuneCount (); break; } - lines.Add (ustring.Make (runes.GetRange (start, end - start))); + lines.Add (StringExtensions.ToString (runes.GetRange (start, end - start))); start = end; if (incomplete) { - start = text.RuneCount; + start = text.GetRuneCount (); break; } } @@ -333,7 +333,7 @@ namespace Terminal.Gui { // //if (line [0] == ' ' && (lines.Count > 0 && lines [lines.Count - 1] [0] == ' ')) { // //} else { // //} - // lines.Add (ustring.Make (line)); + // lines.Add (string.Make (line)); // // move forward to next non-space // while (width > 1 && start < runes.Count && runes [start] == ' ') { @@ -343,28 +343,34 @@ namespace Terminal.Gui { //} while ((end = start + Math.Max (GetLengthThatFits (runes.GetRange (start, runes.Count - start), width), 1)) < runes.Count) { - while (runes [end] != ' ' && end > start) + while (runes [end].Value != ' ' && end > start) end--; if (end == start) end = start + GetLengthThatFits (runes.GetRange (end, runes.Count - end), width); - lines.Add (ustring.Make (runes.GetRange (start, end - start))); - start = end; - if (runes [end] == ' ') { - start++; + var str = StringExtensions.ToString (runes.GetRange (start, end - start)); + if (end > start && str.GetColumns () <= width) { + lines.Add (str); + start = end; + if (runes [end].Value == ' ') { + start++; + } + } else { + end++; + start = end; } } - + } else { while ((end = start + width) < runes.Count) { - while (runes [end] != ' ' && end > start) { + while (runes [end].Value != ' ' && end > start) { end--; } if (end == start) { end = start + width; } - lines.Add (ustring.Make (runes.GetRange (start, end - start))); + lines.Add (StringExtensions.ToString (runes.GetRange (start, end - start))); start = end; - if (runes [end] == ' ') { + if (runes [end].Value == ' ') { start++; } } @@ -381,7 +387,7 @@ namespace Terminal.Gui { while (length < cWidth && to < runes.Count) { var rune = runes [to]; if (IsHorizontalDirection (textDirection)) { - length += Rune.ColumnWidth (rune); + length += rune.GetColumns (); } else { length++; } @@ -391,7 +397,7 @@ namespace Terminal.Gui { } return to; } - if (rune == ' ') { + if (rune.Value == ' ') { if (length == cWidth) { return to + 1; } else if (length > cWidth) { @@ -399,7 +405,7 @@ namespace Terminal.Gui { } else { return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length); } - } else if (rune == '\t') { + } else if (rune.Value == '\t') { length += tabWidth + 1; if (length == tabWidth && tabWidth > cWidth) { return to + 1; @@ -411,17 +417,20 @@ namespace Terminal.Gui { } to++; } - if (cLength > 0 && to < runes.Count && runes [to] != ' ' && runes [to] != '\t') { + if (cLength > 0 && to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t') { return from; - } else if (cLength > 0 && to < runes.Count && (runes [to] == ' ' || runes [to] == '\t')) { + } else if (cLength > 0 && to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t')) { return lastFrom; } else { return to; } } - if (start < text.RuneCount) { - lines.Add (ustring.Make (runes.GetRange (start, runes.Count - start))); + if (start < text.GetRuneCount ()) { + var str = StringExtensions.ToString (runes.GetRange (start, runes.Count - start)); + if (IsVerticalDirection (textDirection) || preserveTrailingSpaces || (!preserveTrailingSpaces && str.GetColumns () <= width)) { + lines.Add (str); + } } return lines; @@ -435,7 +444,7 @@ namespace Terminal.Gui { /// Alignment. /// The text direction. /// Justified and clipped text. - public static ustring ClipAndJustify (ustring text, int width, TextAlignment talign, TextDirection textDirection = TextDirection.LeftRight_TopBottom) + public static string ClipAndJustify (string text, int width, TextAlignment talign, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { return ClipAndJustify (text, width, talign == TextAlignment.Justified, textDirection); } @@ -448,12 +457,12 @@ namespace Terminal.Gui { /// Justify. /// The text direction. /// Justified and clipped text. - public static ustring ClipAndJustify (ustring text, int width, bool justify, TextDirection textDirection = TextDirection.LeftRight_TopBottom) + public static string ClipAndJustify (string text, int width, bool justify, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { if (width < 0) { throw new ArgumentOutOfRangeException ("Width cannot be negative."); } - if (ustring.IsNullOrEmpty (text)) { + if (string.IsNullOrEmpty (text)) { return text; } @@ -461,15 +470,15 @@ namespace Terminal.Gui { int slen = runes.Count; if (slen > width) { if (IsHorizontalDirection (textDirection)) { - return ustring.Make (runes.GetRange (0, GetLengthThatFits (text, width))); + return StringExtensions.ToString (runes.GetRange (0, GetLengthThatFits (text, width))); } else { - return ustring.Make (runes.GetRange (0, width)); + return StringExtensions.ToString (runes.GetRange (0, width)); } } else { if (justify) { return Justify (text, width, ' ', textDirection); - } else if (IsHorizontalDirection (textDirection) && GetTextWidth (text) > width) { - return ustring.Make (runes.GetRange (0, GetLengthThatFits (text, width))); + } else if (IsHorizontalDirection (textDirection) && text.GetColumns () > width) { + return StringExtensions.ToString (runes.GetRange (0, GetLengthThatFits (text, width))); } return text; } @@ -484,21 +493,21 @@ namespace Terminal.Gui { /// Character to replace whitespace and pad with. For debugging purposes. /// The text direction. /// The justified text. - public static ustring Justify (ustring text, int width, char spaceChar = ' ', TextDirection textDirection = TextDirection.LeftRight_TopBottom) + public static string Justify (string text, int width, char spaceChar = ' ', TextDirection textDirection = TextDirection.LeftRight_TopBottom) { if (width < 0) { throw new ArgumentOutOfRangeException ("Width cannot be negative."); } - if (ustring.IsNullOrEmpty (text)) { + if (string.IsNullOrEmpty (text)) { return text; } - var words = text.Split (ustring.Make (' ')); + var words = text.Split (' '); int textCount; if (IsHorizontalDirection (textDirection)) { - textCount = words.Sum (arg => GetTextWidth (arg)); + textCount = words.Sum (arg => arg.GetColumns ()); } else { - textCount = words.Sum (arg => arg.RuneCount); + textCount = words.Sum (arg => arg.GetRuneCount ()); } var spaces = words.Length > 1 ? (width - textCount) / (words.Length - 1) : 0; var extras = words.Length > 1 ? (width - textCount) % (words.Length - 1) : 0; @@ -520,7 +529,7 @@ namespace Terminal.Gui { s.Append (spaceChar); } } - return ustring.Make (s.ToString ()); + return s.ToString (); } static char [] whitespace = new char [] { ' ', '\t' }; @@ -549,7 +558,7 @@ namespace Terminal.Gui { /// If is int.MaxValue, the text will be formatted to the maximum width possible. /// /// - public static List Format (ustring text, int width, TextAlignment talign, bool wordWrap, bool preserveTrailingSpaces = false, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom) + public static List Format (string text, int width, TextAlignment talign, bool wordWrap, bool preserveTrailingSpaces = false, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { return Format (text, width, talign == TextAlignment.Justified, wordWrap, preserveTrailingSpaces, tabWidth, textDirection); } @@ -578,16 +587,16 @@ namespace Terminal.Gui { /// If is int.MaxValue, the text will be formatted to the maximum width possible. /// /// - public static List Format (ustring text, int width, bool justify, bool wordWrap, + public static List Format (string text, int width, bool justify, bool wordWrap, bool preserveTrailingSpaces = false, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { if (width < 0) { throw new ArgumentOutOfRangeException ("width cannot be negative"); } - List lineResult = new List (); + List lineResult = new List (); - if (ustring.IsNullOrEmpty (text) || width == 0) { - lineResult.Add (ustring.Empty); + if (string.IsNullOrEmpty (text) || width == 0) { + lineResult.Add (string.Empty); return lineResult; } @@ -602,18 +611,18 @@ namespace Terminal.Gui { int lp = 0; for (int i = 0; i < runeCount; i++) { Rune c = runes [i]; - if (c == '\n') { - var wrappedLines = WordWrapText (ustring.Make (runes.GetRange (lp, i - lp)), width, preserveTrailingSpaces, tabWidth, textDirection); + if (c.Value == '\n') { + var wrappedLines = WordWrapText (StringExtensions.ToString (runes.GetRange (lp, i - lp)), width, preserveTrailingSpaces, tabWidth, textDirection); foreach (var line in wrappedLines) { lineResult.Add (ClipAndJustify (line, width, justify, textDirection)); } if (wrappedLines.Count == 0) { - lineResult.Add (ustring.Empty); + lineResult.Add (string.Empty); } lp = i + 1; } } - foreach (var line in WordWrapText (ustring.Make (runes.GetRange (lp, runeCount - lp)), width, preserveTrailingSpaces, tabWidth, textDirection)) { + foreach (var line in WordWrapText (StringExtensions.ToString (runes.GetRange (lp, runeCount - lp)), width, preserveTrailingSpaces, tabWidth, textDirection)) { lineResult.Add (ClipAndJustify (line, width, justify, textDirection)); } @@ -626,7 +635,7 @@ namespace Terminal.Gui { /// Number of lines. /// Text, may contain newlines. /// The minimum width for the text. - public static int MaxLines (ustring text, int width) + public static int MaxLines (string text, int width) { var result = TextFormatter.Format (text, width, false, true); return result.Count; @@ -639,13 +648,13 @@ namespace Terminal.Gui { /// Width of the longest line after formatting the text constrained by . /// Text, may contain newlines. /// The number of columns to constrain the text to for formatting. - public static int MaxWidth (ustring text, int maxColumns) + public static int MaxWidth (string text, int maxColumns) { var result = TextFormatter.Format (text: text, width: maxColumns, justify: false, wordWrap: true); var max = 0; result.ForEach (s => { var m = 0; - s.ToRuneList ().ForEach (r => m += Math.Max (Rune.ColumnWidth (r), 1)); + s.ToRuneList ().ForEach (r => m += Math.Max (r.GetColumns (), 1)); if (m > max) { max = m; } @@ -654,25 +663,15 @@ namespace Terminal.Gui { } /// - /// Returns the width of the widest line in the text, accounting for wide-glyphs (uses ). + /// Returns the width of the widest line in the text, accounting for wide-glyphs (uses ). /// if it contains newlines. /// /// Text, may contain newlines. /// The length of the longest line. - public static int MaxWidthLine (ustring text) + public static int MaxWidthLine (string text) { var result = TextFormatter.SplitNewLine (text); - return result.Max (x => x.ConsoleWidth); - } - - /// - /// Gets the number of columns the passed text will use, ignoring newlines and accounting for wide-glyphs (uses ). - /// - /// - /// The text width. - public static int GetTextWidth (ustring text) - { - return text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)); + return result.Max (x => x.GetColumns ()); } /// @@ -683,13 +682,13 @@ namespace Terminal.Gui { /// The start index. /// The length. /// The maximum characters width. - public static int GetSumMaxCharWidth (List lines, int startIndex = -1, int length = -1) + public static int GetSumMaxCharWidth (List lines, int startIndex = -1, int length = -1) { var max = 0; for (int i = (startIndex == -1 ? 0 : startIndex); i < (length == -1 ? lines.Count : startIndex + length); i++) { var runes = lines [i]; if (runes.Length > 0) - max += runes.Max (r => Math.Max (Rune.ColumnWidth (r), 1)); + max += runes.EnumerateRunes ().Max (r => Math.Max (r.GetColumns (), 1)); } return max; } @@ -702,23 +701,23 @@ namespace Terminal.Gui { /// The start index. /// The length. /// The maximum characters width. - public static int GetSumMaxCharWidth (ustring text, int startIndex = -1, int length = -1) + public static int GetSumMaxCharWidth (string text, int startIndex = -1, int length = -1) { var max = 0; var runes = text.ToRunes (); for (int i = (startIndex == -1 ? 0 : startIndex); i < (length == -1 ? runes.Length : startIndex + length); i++) { - max += Math.Max (Rune.ColumnWidth (runes [i]), 1); + max += Math.Max (runes [i].GetColumns (), 1); } return max; } /// - /// Gets the number of the Runes in a that will fit in . + /// Gets the number of the Runes in a that will fit in . /// /// The text. /// The width. /// The index of the text that fit the width. - public static int GetLengthThatFits (ustring text, int columns) => GetLengthThatFits (text?.ToRuneList (), columns); + public static int GetLengthThatFits (string text, int columns) => GetLengthThatFits (text?.ToRuneList (), columns); /// /// Gets the number of the Runes in a list of Runes that will fit in . @@ -735,7 +734,7 @@ namespace Terminal.Gui { var runesLength = 0; var runeIdx = 0; for (; runeIdx < runes.Count; runeIdx++) { - var runeWidth = Math.Max (Rune.ColumnWidth (runes [runeIdx]), 1); + var runeWidth = Math.Max (runes [runeIdx].GetColumns (), 1); if (runesLength + runeWidth > columns) { break; } @@ -750,14 +749,14 @@ namespace Terminal.Gui { /// The lines. /// The width. /// The index of the list that fit the width. - public static int GetMaxColsForWidth (List lines, int width) + public static int GetMaxColsForWidth (List lines, int width) { var runesLength = 0; var lineIdx = 0; for (; lineIdx < lines.Count; lineIdx++) { var runes = lines [lineIdx].ToRuneList (); var maxRruneWidth = runes.Count > 0 - ? runes.Max (r => Math.Max (Rune.ColumnWidth (r), 1)) : 1; + ? runes.Max (r => Math.Max (r.GetColumns (), 1)) : 1; if (runesLength + maxRruneWidth > width) { break; } @@ -774,9 +773,9 @@ namespace Terminal.Gui { /// The text to measure /// The text direction. /// - public static Rect CalcRect (int x, int y, ustring text, TextDirection direction = TextDirection.LeftRight_TopBottom) + public static Rect CalcRect (int x, int y, string text, TextDirection direction = TextDirection.LeftRight_TopBottom) { - if (ustring.IsNullOrEmpty (text)) { + if (string.IsNullOrEmpty (text)) { return new Rect (new Point (x, y), Size.Empty); } @@ -787,16 +786,16 @@ namespace Terminal.Gui { int ml = 1; int cols = 0; - foreach (var rune in text) { - if (rune == '\n') { + foreach (var rune in text.EnumerateRunes ()) { + if (rune.Value == '\n') { ml++; if (cols > mw) { mw = cols; } cols = 0; - } else if (rune != '\r') { + } else if (rune.Value != '\r') { cols++; - var rw = Rune.ColumnWidth (rune); + var rw = ((Rune)rune).GetColumns (); if (rw > 0) { rw--; } @@ -813,17 +812,17 @@ namespace Terminal.Gui { int vh = 0; int rows = 0; - foreach (var rune in text) { - if (rune == '\n') { + foreach (var rune in text.EnumerateRunes ()) { + if (rune.Value == '\n') { vw++; if (rows > vh) { vh = rows; } rows = 0; cw = 1; - } else if (rune != '\r') { + } else if (rune.Value != '\r') { rows++; - var rw = Rune.ColumnWidth (rune); + var rw = ((Rune)rune).GetColumns (); if (cw < rw) { cw = rw; vw++; @@ -850,9 +849,9 @@ namespace Terminal.Gui { /// Outputs the Rune index into text. /// Outputs the hotKey. /// true if a hotkey was found; false otherwise. - public static bool FindHotKey (ustring text, Rune hotKeySpecifier, bool firstUpperCase, out int hotPos, out Key hotKey) + public static bool FindHotKey (string text, Rune hotKeySpecifier, bool firstUpperCase, out int hotPos, out Key hotKey) { - if (ustring.IsNullOrEmpty (text) || hotKeySpecifier == (Rune)0xFFFF) { + if (string.IsNullOrEmpty (text) || hotKeySpecifier == (Rune)0xFFFF) { hotPos = -1; hotKey = Key.Unknown; return false; @@ -865,8 +864,8 @@ namespace Terminal.Gui { // TODO: Ignore hot_key of two are provided // TODO: Do not support non-alphanumeric chars that can't be typed int i = 0; - foreach (Rune c in text) { - if ((char)c != 0xFFFD) { + foreach (Rune c in text.EnumerateRunes ()) { + if ((char)c.Value != 0xFFFD) { if (c == hotKeySpecifier) { hot_pos = i; } else if (hot_pos > -1) { @@ -880,8 +879,8 @@ namespace Terminal.Gui { // Legacy support - use first upper case char if the specifier was not found if (hot_pos == -1 && firstUpperCase) { i = 0; - foreach (Rune c in text) { - if ((char)c != 0xFFFD) { + foreach (Rune c in text.EnumerateRunes ()) { + if ((char)c.Value != 0xFFFD) { if (Rune.IsUpper (c)) { hot_key = c; hot_pos = i; @@ -895,8 +894,8 @@ namespace Terminal.Gui { if (hot_key != (Rune)0 && hot_pos != -1) { hotPos = hot_pos; - if (hot_key.IsValid && char.IsLetterOrDigit ((char)hot_key)) { - hotKey = (Key)char.ToUpperInvariant ((char)hot_key); + if (Rune.IsValid (hot_key.Value) && char.IsLetterOrDigit ((char)hot_key.Value)) { + hotKey = (Key)char.ToUpperInvariant ((char)hot_key.Value); return true; } } @@ -916,14 +915,14 @@ namespace Terminal.Gui { /// /// The returned string will not render correctly without first un-doing the tag. To undo the tag, search for /// - public ustring ReplaceHotKeyWithTag (ustring text, int hotPos) + public string ReplaceHotKeyWithTag (string text, int hotPos) { // Set the high bit var runes = text.ToRuneList (); - if (Rune.IsLetterOrNumber (runes [hotPos])) { - runes [hotPos] = new Rune ((uint)runes [hotPos]); + if (Rune.IsLetterOrDigit (runes [hotPos])) { + runes [hotPos] = new Rune ((uint)runes [hotPos].Value); } - return ustring.Make (runes); + return StringExtensions.ToString (runes); } /// @@ -933,33 +932,32 @@ namespace Terminal.Gui { /// The hot-key specifier (e.g. '_') to look for. /// Returns the position of the hot-key in the text. -1 if not found. /// The input text with the hotkey specifier ('_') removed. - public static ustring RemoveHotKeySpecifier (ustring text, int hotPos, Rune hotKeySpecifier) + public static string RemoveHotKeySpecifier (string text, int hotPos, Rune hotKeySpecifier) { - if (ustring.IsNullOrEmpty (text)) { + if (string.IsNullOrEmpty (text)) { return text; } // Scan - ustring start = ustring.Empty; + string start = string.Empty; int i = 0; foreach (Rune c in text) { if (c == hotKeySpecifier && i == hotPos) { i++; continue; } - start += ustring.Make (c); + start += c; i++; } return start; } #endregion // Static Members - List _lines = new List (); - ustring _text; + List _lines = new List (); + string _text; TextAlignment _textAlignment; VerticalTextAlignment _textVerticalAlignment; TextDirection _textDirection; - Attribute _textColor = -1; Key _hotKey; int _hotKeyPos = -1; Size _size; @@ -970,14 +968,14 @@ namespace Terminal.Gui { public event EventHandler HotKeyChanged; /// - /// The text to be displayed. This text is never modified. + /// The text to be displayed. This string is never modified. /// - public virtual ustring Text { + public virtual string Text { get => _text; set { _text = value; - if (_text != null && _text.RuneCount > 0 && (Size.Width == 0 || Size.Height == 0 || Size.Width != _text.ConsoleWidth)) { + if (_text != null && _text.GetRuneCount () > 0 && (Size.Width == 0 || Size.Height == 0 || Size.Width != _text.GetColumns ())) { // Provide a default size (width = length of longest line, height = 1) // TODO: It might makes more sense for the default to be width = length of first line? Size = new Size (TextFormatter.MaxWidth (Text, int.MaxValue), 1); @@ -1160,7 +1158,7 @@ namespace Terminal.Gui { public Size GetFormattedSize () { var lines = Lines; - var width = Lines.Max (line => TextFormatter.GetTextWidth (line)); + var width = Lines.Max (line => line.GetColumns ()); var height = Lines.Count; return new Size (width, height); } @@ -1171,15 +1169,15 @@ namespace Terminal.Gui { /// /// /// Upon a 'get' of this property, if the text needs to be formatted (if is true) - /// will be called internally. + /// will be called internally. /// /// - public List Lines { + public List Lines { get { // With this check, we protect against subclasses with overrides of Text - if (ustring.IsNullOrEmpty (Text) || Size.IsEmpty) { - _lines = new List { - ustring.Empty + if (string.IsNullOrEmpty (Text) || Size.IsEmpty) { + _lines = new List { + string.Empty }; NeedsFormat = false; return _lines; @@ -1253,7 +1251,7 @@ namespace Terminal.Gui { public void Draw (Rect bounds, Attribute normalColor, Attribute hotColor, Rect containerBounds = default, bool fillRemaining = true) { // With this check, we protect against subclasses with overrides of Text (like Button) - if (ustring.IsNullOrEmpty (_text)) { + if (string.IsNullOrEmpty (_text)) { return; } @@ -1322,7 +1320,7 @@ namespace Terminal.Gui { x = bounds.Right - runesWidth; CursorPosition = bounds.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0); } else { - var runesWidth = GetTextWidth (ustring.Make (runes)); + var runesWidth = StringExtensions.ToString (runes).GetColumns (); x = bounds.Right - runesWidth; CursorPosition = bounds.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0); } @@ -1340,7 +1338,7 @@ namespace Terminal.Gui { x = bounds.Left + line + ((bounds.Width - runesWidth) / 2); CursorPosition = (bounds.Width - runesWidth) / 2 + (_hotKeyPos > -1 ? _hotKeyPos : 0); } else { - var runesWidth = GetTextWidth (ustring.Make (runes)); + var runesWidth = StringExtensions.ToString (runes).GetColumns (); x = bounds.Left + (bounds.Width - runesWidth) / 2; CursorPosition = (bounds.Width - runesWidth) / 2 + (_hotKeyPos > -1 ? _hotKeyPos : 0); } @@ -1413,13 +1411,13 @@ namespace Terminal.Gui { } else { Application.Driver?.AddRune (rune); } - var runeWidth = Math.Max (Rune.ColumnWidth (rune), 1); + var runeWidth = Math.Max (rune.GetColumns (), 1); if (isVertical) { current++; } else { current += runeWidth; } - var nextRuneWidth = idx + 1 > -1 && idx + 1 < runes.Length ? Rune.ColumnWidth (runes [idx + 1]) : 0; + var nextRuneWidth = idx + 1 > -1 && idx + 1 < runes.Length ? runes [idx + 1].GetColumns () : 0; if (!isVertical && idx + 1 < runes.Length && current + nextRuneWidth > start + size) { break; } diff --git a/Terminal.Gui/View/Frame.cs b/Terminal.Gui/View/Frame.cs index beed23d88..83ecb6892 100644 --- a/Terminal.Gui/View/Frame.cs +++ b/Terminal.Gui/View/Frame.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.ComponentModel; @@ -163,11 +163,11 @@ namespace Terminal.Gui { var topTitleLineY = borderBounds.Y; var titleY = borderBounds.Y; var titleBarsLength = 0; // the little vertical thingies - var maxTitleWidth = Math.Min (Parent.Title.ConsoleWidth, Math.Min (screenBounds.Width - 4, borderBounds.Width - 4)); + var maxTitleWidth = Math.Min (Parent.Title.GetColumns (), Math.Min (screenBounds.Width - 4, borderBounds.Width - 4)); var sideLineLength = borderBounds.Height; var canDrawBorder = borderBounds.Width > 0 && borderBounds.Height > 0; - if (!ustring.IsNullOrEmpty (Parent?.Title)) { + if (!string.IsNullOrEmpty (Parent?.Title)) { if (Thickness.Top == 2) { topTitleLineY = borderBounds.Y - 1; titleY = topTitleLineY + 1; @@ -196,7 +196,7 @@ namespace Terminal.Gui { } - if (Id == "Border" && canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && !ustring.IsNullOrEmpty (Parent?.Title)) { + if (Id == "Border" && canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && !string.IsNullOrEmpty (Parent?.Title)) { var prevAttr = Driver.GetAttribute (); if (ColorScheme != null) { Driver.SetAttribute (HasFocus ? GetHotNormalColor () : GetNormalColor ()); @@ -225,7 +225,7 @@ namespace Terminal.Gui { if (drawTop) { // ╔╡Title╞═════╗ // ╔╡╞═════╗ - if (borderBounds.Width < 4 || ustring.IsNullOrEmpty (Parent?.Title)) { + if (borderBounds.Width < 4 || string.IsNullOrEmpty (Parent?.Title)) { // ╔╡╞╗ should be ╔══╗ lc.AddLine (new Point (borderBounds.Location.X, titleY), borderBounds.Width, Orientation.Horizontal, BorderStyle, Driver.GetAttribute ()); } else { @@ -275,14 +275,14 @@ namespace Terminal.Gui { } // Redraw title - if (drawTop && Id == "Border" && maxTitleWidth > 0 && !ustring.IsNullOrEmpty (Parent?.Title)) { + if (drawTop && Id == "Border" && maxTitleWidth > 0 && !string.IsNullOrEmpty (Parent?.Title)) { prevAttr = Driver.GetAttribute (); if (ColorScheme != null) { Driver.SetAttribute (HasFocus ? GetHotNormalColor () : GetNormalColor ()); } else { Driver.SetAttribute (Parent.HasFocus ? Parent.GetHotNormalColor () : Parent.GetNormalColor ()); } - DrawTitle (new Rect (borderBounds.X, titleY, Parent.Title.ConsoleWidth, 1), Parent?.Title); + DrawTitle (new Rect (borderBounds.X, titleY, Parent.Title.GetColumns (), 1), Parent?.Title); Driver.SetAttribute (prevAttr); } @@ -361,13 +361,13 @@ namespace Terminal.Gui { /// /// Screen relative region where the title will be drawn. /// The title. - public void DrawTitle (Rect region, ustring title) + public void DrawTitle (Rect region, string title) { var width = region.Width; - if (!ustring.IsNullOrEmpty (title)) { + if (!string.IsNullOrEmpty (title)) { Driver.Move (region.X + 2, region.Y); //Driver.AddRune (' '); - var str = title.Sum (r => Math.Max (Rune.ColumnWidth (r), 1)) >= width + var str = title.EnumerateRunes ().Sum (r => Math.Max (r.GetColumns (), 1)) >= width ? TextFormatter.Format (title, width, false, false) [0] : title; Driver.AddStr (str); } diff --git a/Terminal.Gui/View/TitleEventArgs.cs b/Terminal.Gui/View/TitleEventArgs.cs index aa51b18a9..54d7642ee 100644 --- a/Terminal.Gui/View/TitleEventArgs.cs +++ b/Terminal.Gui/View/TitleEventArgs.cs @@ -1,5 +1,5 @@ using System; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -9,12 +9,12 @@ namespace Terminal.Gui { /// /// The new Window Title. /// - public ustring NewTitle { get; set; } + public string NewTitle { get; set; } /// /// The old Window Title. /// - public ustring OldTitle { get; set; } + public string OldTitle { get; set; } /// /// Flag which allows canceling the Title change. @@ -26,7 +26,7 @@ namespace Terminal.Gui { /// /// The that is/has been replaced. /// The new to be replaced. - public TitleEventArgs (ustring oldTitle, ustring newTitle) + public TitleEventArgs (string oldTitle, string newTitle) { OldTitle = oldTitle; NewTitle = newTitle; diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs index c9fea00d5..766e70456 100644 --- a/Terminal.Gui/View/View.cs +++ b/Terminal.Gui/View/View.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { #region API Docs @@ -163,7 +163,7 @@ namespace Terminal.Gui { /// column to locate the View. /// row to locate the View. /// text to initialize the property with. - public View (int x, int y, ustring text) : this (TextFormatter.CalcRect (x, y, text), text) { } + public View (int x, int y, string text) : this (TextFormatter.CalcRect (x, y, text), text) { } /// /// Initializes a new instance of using layout. @@ -180,7 +180,7 @@ namespace Terminal.Gui { /// /// Location. /// text to initialize the property with. - public View (Rect rect, ustring text) + public View (Rect rect, string text) { SetInitialProperties (text, rect, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom); } @@ -200,7 +200,7 @@ namespace Terminal.Gui { /// /// text to initialize the property with. /// The text direction. - public View (ustring text, TextDirection direction = TextDirection.LeftRight_TopBottom) + public View (string text, TextDirection direction = TextDirection.LeftRight_TopBottom) { SetInitialProperties (text, Rect.Empty, LayoutStyle.Computed, direction); } @@ -213,7 +213,7 @@ namespace Terminal.Gui { /// /// /// - void SetInitialProperties (ustring text, Rect rect, LayoutStyle layoutStyle = LayoutStyle.Computed, + void SetInitialProperties (string text, Rect rect, LayoutStyle layoutStyle = LayoutStyle.Computed, TextDirection direction = TextDirection.LeftRight_TopBottom) { TextFormatter = new TextFormatter (); @@ -226,7 +226,7 @@ namespace Terminal.Gui { TabStop = false; LayoutStyle = layoutStyle; - Text = text == null ? ustring.Empty : text; + Text = text == null ? string.Empty : text; LayoutStyle = layoutStyle; Frame = rect.IsEmpty ? TextFormatter.CalcRect (0, 0, text, direction) : rect; OnResizeNeeded (); @@ -334,13 +334,13 @@ namespace Terminal.Gui { /// The id should be unique across all Views that share a SuperView. public string Id { get; set; } = ""; - ustring _title = ustring.Empty; + string _title = string.Empty; /// /// The title to be displayed for this . The title will be displayed if . /// is greater than 0. /// /// The title. - public ustring Title { + public string Title { get => _title; set { if (!OnTitleChanging (_title, value)) { @@ -363,7 +363,7 @@ namespace Terminal.Gui { /// The that is/has been replaced. /// The new to be replaced. /// `true` if an event handler canceled the Title change. - public virtual bool OnTitleChanging (ustring oldTitle, ustring newTitle) + public virtual bool OnTitleChanging (string oldTitle, string newTitle) { var args = new TitleEventArgs (oldTitle, newTitle); TitleChanging?.Invoke (this, args); @@ -381,7 +381,7 @@ namespace Terminal.Gui { /// /// The that is/has been replaced. /// The new to be replaced. - public virtual void OnTitleChanged (ustring oldTitle, ustring newTitle) + public virtual void OnTitleChanged (string oldTitle, string newTitle) { var args = new TitleEventArgs (oldTitle, newTitle); TitleChanged?.Invoke (this, args); diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs index 6ab70fe12..741361609 100644 --- a/Terminal.Gui/View/ViewDrawing.cs +++ b/Terminal.Gui/View/ViewDrawing.cs @@ -1,6 +1,6 @@ using System; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { public partial class View { @@ -155,7 +155,7 @@ namespace Terminal.Gui { for (var line = 0; line < h; line++) { Move (0, line); for (var col = 0; col < w; col++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } } @@ -174,7 +174,7 @@ namespace Terminal.Gui { for (var line = regionScreen.Y; line < regionScreen.Y + h; line++) { Driver.Move (regionScreen.X, line); for (var col = 0; col < w; col++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } } @@ -232,16 +232,16 @@ namespace Terminal.Gui { /// The hotkey is any character following the hotkey specifier, which is the underscore ('_') character by default. /// The hotkey specifier can be changed via /// - public void DrawHotString (ustring text, Attribute hotColor, Attribute normalColor) + public void DrawHotString (string text, Attribute hotColor, Attribute normalColor) { var hotkeySpec = HotKeySpecifier == (Rune)0xffff ? (Rune)'_' : HotKeySpecifier; Application.Driver.SetAttribute (normalColor); foreach (var rune in text) { - if (rune == hotkeySpec) { + if (rune == hotkeySpec.Value) { Application.Driver.SetAttribute (hotColor); continue; } - Application.Driver.AddRune (rune); + Application.Driver.AddRune ((Rune)rune); Application.Driver.SetAttribute (normalColor); } } @@ -252,7 +252,7 @@ namespace Terminal.Gui { /// String to display, the underscore before a letter flags the next letter as the hotkey. /// If set to this uses the focused colors from the color scheme, otherwise the regular ones. /// The color scheme to use. - public void DrawHotString (ustring text, bool focused, ColorScheme scheme) + public void DrawHotString (string text, bool focused, ColorScheme scheme) { if (focused) DrawHotString (text, scheme.HotFocus, scheme.Focus); @@ -445,7 +445,7 @@ namespace Terminal.Gui { Clear (ViewToScreen (Bounds)); } - if (!ustring.IsNullOrEmpty (TextFormatter.Text)) { + if (!string.IsNullOrEmpty (TextFormatter.Text)) { if (TextFormatter != null) { TextFormatter.NeedsFormat = true; } diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs index f1a6256ae..66a2ce491 100644 --- a/Terminal.Gui/View/ViewKeyboard.cs +++ b/Terminal.Gui/View/ViewKeyboard.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { public partial class View { @@ -69,7 +69,7 @@ namespace Terminal.Gui { /// /// The keystroke combination used in the as string. /// - public ustring ShortcutTag => ShortcutHelper.GetShortcutTag (_shortcutHelper.Shortcut); + public string ShortcutTag => ShortcutHelper.GetShortcutTag (_shortcutHelper.Shortcut); /// /// The action to run if the is defined. diff --git a/Terminal.Gui/View/ViewLayout.cs b/Terminal.Gui/View/ViewLayout.cs index f268ea02c..a8fed3a26 100644 --- a/Terminal.Gui/View/ViewLayout.cs +++ b/Terminal.Gui/View/ViewLayout.cs @@ -4,7 +4,7 @@ using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Reflection; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -385,10 +385,10 @@ namespace Terminal.Gui { } size = Bounds.Size; - if (!AutoSize && !ustring.IsNullOrEmpty (TextFormatter.Text)) { + if (!AutoSize && !string.IsNullOrEmpty (TextFormatter.Text)) { switch (TextFormatter.IsVerticalDirection (TextDirection)) { case true: - var colWidth = TextFormatter.GetSumMaxCharWidth (new List { TextFormatter.Text }, 0, 1); + var colWidth = TextFormatter.GetSumMaxCharWidth (new List { TextFormatter.Text }, 0, 1); // TODO: v2 - This uses frame.Width; it should only use Bounds if (_frame.Width < colWidth && (Width == null || diff --git a/Terminal.Gui/View/ViewMouse.cs b/Terminal.Gui/View/ViewMouse.cs index f5e1e8c37..2bed5f1dd 100644 --- a/Terminal.Gui/View/ViewMouse.cs +++ b/Terminal.Gui/View/ViewMouse.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { public partial class View { diff --git a/Terminal.Gui/View/ViewSubViews.cs b/Terminal.Gui/View/ViewSubViews.cs index fd9a0f5f2..01226fd80 100644 --- a/Terminal.Gui/View/ViewSubViews.cs +++ b/Terminal.Gui/View/ViewSubViews.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { public partial class View { diff --git a/Terminal.Gui/View/ViewText.cs b/Terminal.Gui/View/ViewText.cs index a8dcd1b7f..b77c8f821 100644 --- a/Terminal.Gui/View/ViewText.cs +++ b/Terminal.Gui/View/ViewText.cs @@ -1,10 +1,10 @@ -using NStack; +using System.Text; using System; namespace Terminal.Gui { public partial class View { - ustring _text; + string _text; /// /// The text displayed by the . @@ -26,7 +26,7 @@ namespace Terminal.Gui { /// (Rune)0xffff. /// /// - public virtual ustring Text { + public virtual string Text { get => _text; set { _text = value; @@ -154,12 +154,12 @@ namespace Terminal.Gui { { if (isWidth) { return TextFormatter.IsHorizontalDirection (TextDirection) && - TextFormatter.Text?.Contains (HotKeySpecifier) == true - ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0; + TextFormatter.Text?.Contains ((char)HotKeySpecifier.Value) == true + ? Math.Max (HotKeySpecifier.GetColumns (), 0) : 0; } else { return TextFormatter.IsVerticalDirection (TextDirection) && - TextFormatter.Text?.Contains (HotKeySpecifier) == true - ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0; + TextFormatter.Text?.Contains ((char)HotKeySpecifier.Value) == true + ? Math.Max (HotKeySpecifier.GetColumns(), 0) : 0; } } @@ -179,7 +179,7 @@ namespace Terminal.Gui { /// public Size GetSizeNeededForTextAndHotKey () { - if (ustring.IsNullOrEmpty (TextFormatter.Text)) { + if (string.IsNullOrEmpty (TextFormatter.Text)) { if (!IsInitialized) return Size.Empty; diff --git a/Terminal.Gui/Views/AutocompleteFilepathContext.cs b/Terminal.Gui/Views/AutocompleteFilepathContext.cs index 0a7bb090c..30b0b4df0 100644 --- a/Terminal.Gui/Views/AutocompleteFilepathContext.cs +++ b/Terminal.Gui/Views/AutocompleteFilepathContext.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.IO; @@ -10,8 +10,8 @@ namespace Terminal.Gui { internal class AutocompleteFilepathContext : AutocompleteContext { public FileDialogState State { get; set; } - public AutocompleteFilepathContext (ustring currentLine, int cursorPosition, FileDialogState state) - : base (currentLine.ToRuneList (), cursorPosition) + public AutocompleteFilepathContext (string currentLine, int cursorPosition, FileDialogState state) + : base (currentLine.EnumerateRunes ().ToList (), cursorPosition) { this.State = state; } @@ -30,18 +30,17 @@ namespace Terminal.Gui { return Enumerable.Empty (); } - var path = ustring.Make (context.CurrentLine).ToString (); + var path = StringExtensions.ToString (context.CurrentLine); var last = path.LastIndexOfAny (FileDialog.Separators); - - if(string.IsNullOrWhiteSpace(path) || !Path.IsPathRooted(path)) { + + if (string.IsNullOrWhiteSpace (path) || !Path.IsPathRooted (path)) { return Enumerable.Empty (); } var term = path.Substring (last + 1); - + // If path is /tmp/ then don't just list everything in it - if(string.IsNullOrWhiteSpace(term)) - { + if (string.IsNullOrWhiteSpace (term)) { return Enumerable.Empty (); } @@ -52,7 +51,7 @@ namespace Terminal.Gui { bool isWindows = RuntimeInformation.IsOSPlatform (OSPlatform.Windows); - var suggestions = state.Children.Where(d=> !d.IsParent).Select ( + var suggestions = state.Children.Where (d => !d.IsParent).Select ( e => e.FileSystemInfo is IDirectoryInfo d ? d.Name + System.IO.Path.DirectorySeparatorChar : e.FileSystemInfo.Name) @@ -76,7 +75,7 @@ namespace Terminal.Gui { public bool IsWordChar (Rune rune) { - if (rune == '\n') { + if (rune.Value == '\n') { return false; } diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index 68d92275d..7af58684f 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -6,7 +6,7 @@ // using System; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -58,7 +58,7 @@ namespace Terminal.Gui { /// If true, a special decoration is used, and the user pressing the enter key /// in a will implicitly activate this button. /// - public Button (ustring text, bool is_default = false) : base (text) + public Button (string text, bool is_default = false) : base (text) { SetInitialProperties (text, is_default); } @@ -73,7 +73,7 @@ namespace Terminal.Gui { /// X position where the button will be shown. /// Y position where the button will be shown. /// The button's text - public Button (int x, int y, ustring text) : this (x, y, text, false) { } + public Button (int x, int y, string text) : this (x, y, text, false) { } /// /// Initializes a new instance of using layout, based on the given text. @@ -89,8 +89,8 @@ namespace Terminal.Gui { /// If true, a special decoration is used, and the user pressing the enter key /// in a will implicitly activate this button. /// - public Button (int x, int y, ustring text, bool is_default) - : base (new Rect (x, y, text.RuneCount + 4 + (is_default ? 2 : 0), 1), text) + public Button (int x, int y, string text, bool is_default) + : base (new Rect (x, y, text.GetRuneCount () + 4 + (is_default ? 2 : 0), 1), text) { SetInitialProperties (text, is_default); } @@ -100,7 +100,7 @@ namespace Terminal.Gui { /// /// /// - void SetInitialProperties (ustring text, bool is_default) + void SetInitialProperties (string text, bool is_default) { TextAlignment = TextAlignment.Centered; VerticalTextAlignment = VerticalTextAlignment.Middle; @@ -180,15 +180,14 @@ namespace Terminal.Gui { TextFormatter.Text = Text; } else if (IsDefault) - TextFormatter.Text = ustring.Make (_leftBracket) + ustring.Make (_leftDefault) + " " + Text + " " + ustring.Make (_rightDefault) + ustring.Make (_rightBracket); + TextFormatter.Text = $"{_leftBracket}{_leftDefault} {Text} {_rightDefault}{_rightBracket}"; else { if (NoPadding) { - TextFormatter.Text = ustring.Make (_leftBracket) + Text + ustring.Make (_rightBracket); + TextFormatter.Text = $"{_leftBracket}{Text}{_rightBracket}"; } else { - TextFormatter.Text = ustring.Make (_leftBracket) + " " + Text + " " + ustring.Make (_rightBracket); + TextFormatter.Text = $"{_leftBracket} {Text} {_rightBracket}"; } } - } /// @@ -291,7 +290,7 @@ namespace Terminal.Gui { public override void PositionCursor () { if (HotKey == Key.Unknown && Text != "") { - for (int i = 0; i < TextFormatter.Text.RuneCount; i++) { + for (int i = 0; i < TextFormatter.Text.GetRuneCount (); i++) { if (TextFormatter.Text [i] == Text [0]) { Move (i, 0); return; diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs index 5195c0221..0968b1d33 100644 --- a/Terminal.Gui/Views/CheckBox.cs +++ b/Terminal.Gui/Views/CheckBox.cs @@ -5,7 +5,7 @@ // Miguel de Icaza (miguel@gnome.org) // using System; -using NStack; +using System.Text; namespace Terminal.Gui { @@ -47,7 +47,7 @@ namespace Terminal.Gui { /// /// S. /// If set to true is checked. - public CheckBox (ustring s, bool is_checked = false) : base () + public CheckBox (string s, bool is_checked = false) : base () { SetInitialProperties (s, is_checked); } @@ -59,7 +59,7 @@ namespace Terminal.Gui { /// 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) + public CheckBox (int x, int y, string s) : this (x, y, s, false) { } @@ -70,7 +70,7 @@ namespace Terminal.Gui { /// 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)) + public CheckBox (int x, int y, string s, bool is_checked) : base (new Rect (x, y, s.Length, 1)) { SetInitialProperties (s, is_checked); } @@ -81,17 +81,17 @@ namespace Terminal.Gui { /// /// /// - void SetInitialProperties (ustring s, bool is_checked) + void SetInitialProperties (string s, bool is_checked) { charNullChecked = CM.Glyphs.NullChecked; charChecked = CM.Glyphs.Checked; charUnChecked = CM.Glyphs.UnChecked; Checked = is_checked; - HotKeySpecifier = '_'; + HotKeySpecifier = (Rune)'_'; CanFocus = true; AutoSize = true; Text = s; - + OnResizeNeeded (); // Things this view knows how to do @@ -109,10 +109,10 @@ namespace Terminal.Gui { case TextAlignment.Left: case TextAlignment.Centered: case TextAlignment.Justified: - TextFormatter.Text = ustring.Make (GetCheckedState ()) + " " + GetFormatterText (); + TextFormatter.Text = $"{GetCheckedState ()} {GetFormatterText ()}"; break; case TextAlignment.Right: - TextFormatter.Text = GetFormatterText () + " " + ustring.Make (GetCheckedState ()); + TextFormatter.Text = $"{GetFormatterText ()} {GetCheckedState ()}"; break; } } @@ -126,12 +126,12 @@ namespace Terminal.Gui { } } - ustring GetFormatterText () + string GetFormatterText () { - if (AutoSize || ustring.IsNullOrEmpty (Text) || Frame.Width <= 2) { + if (AutoSize || string.IsNullOrEmpty (Text) || Frame.Width <= 2) { return Text; } - return Text.RuneSubstring (0, Math.Min (Frame.Width - 2, Text.RuneCount)); + return Text [..Math.Min (Frame.Width - 2, Text.GetRuneCount ())]; } /// @@ -209,7 +209,7 @@ namespace Terminal.Gui { } else { Checked = !Checked; } - + OnToggled (new ToggleEventArgs (previousChecked, Checked)); SetNeedsDisplay (); return true; diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index 4aaeddf86..c9d0cb9b4 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -1,7 +1,5 @@ using System; -using System.Reflection; -using NStack; -using static Terminal.Gui.SpinnerStyle; +using System.Text; namespace Terminal.Gui { @@ -75,8 +73,8 @@ namespace Terminal.Gui { // Cursor runes. private static readonly Rune [] _cursorRunes = new Rune [] { - 0x250C, 0x2500, 0x2500, 0x2510, - 0x2514, 0x2500, 0x2500, 0x2518 + (Rune)0x250C, (Rune) 0x2500, (Rune) 0x2500, (Rune) 0x2510, + (Rune) 0x2514, (Rune) 0x2500, (Rune) 0x2500, (Rune) 0x2518 }; /// @@ -189,7 +187,7 @@ namespace Terminal.Gui { for (var zoomedY = 0; zoomedY < BoxHeight; zoomedY++) { for (var zoomedX = 0; zoomedX < BoxWidth; zoomedX++) { Move (x * BoxWidth + zoomedX, y * BoxHeight + zoomedY); - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); index++; } } diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index e63ebdbaf..c4a3395e7 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -8,7 +8,7 @@ using System; using System.Collections; using System.Collections.Generic; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -122,7 +122,7 @@ namespace Terminal.Gui { Move (0, row); if (Source == null || item >= Source.Count) { for (int c = 0; c < f.Width; c++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } else { var rowEventArgs = new ListViewRowEventArgs (item); OnRowRender (rowEventArgs); @@ -132,7 +132,7 @@ namespace Terminal.Gui { } if (AllowsMarking) { Driver.AddRune (Source.IsMarked (item) ? (AllowsMultipleSelection ? CM.Glyphs.Checked : CM.Glyphs.Selected) : (AllowsMultipleSelection ? CM.Glyphs.UnChecked : CM.Glyphs.UnSelected)); - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } Source.Render (this, Driver, isSelected, item, col, row, f.Width - col, start); } @@ -232,7 +232,7 @@ namespace Terminal.Gui { public event EventHandler OpenSelectedItem; readonly IList searchset = new List (); - ustring text = ""; + string text = ""; readonly TextField search; readonly ComboListView listview; bool autoHide = true; @@ -249,7 +249,7 @@ namespace Terminal.Gui { /// Public constructor /// /// - public ComboBox (ustring text) : base () + public ComboBox (string text) : base () { search = new TextField (""); listview = new ComboListView (this, HideDropdownListOnClick) { LayoutStyle = LayoutStyle.Computed, CanFocus = true, TabStop = false }; @@ -484,7 +484,7 @@ namespace Terminal.Gui { search.SetFocus (); } - search.CursorPosition = search.Text.RuneCount; + search.CursorPosition = search.Text.GetRuneCount (); return base.OnEnter (view); } @@ -627,7 +627,7 @@ namespace Terminal.Gui { if (listview.HasFocus && listview.SelectedItem == 0 && searchset?.Count > 0) // jump back to search { - search.CursorPosition = search.Text.RuneCount; + search.CursorPosition = search.Text.GetRuneCount (); search.SetFocus (); return true; } @@ -640,7 +640,9 @@ namespace Terminal.Gui { if (searchset?.Count > 0) { listview.TabStop = true; listview.SetFocus (); - SetValue (searchset [listview.SelectedItem]); + if (listview.SelectedItem > -1) { + SetValue (searchset [listview.SelectedItem]); + } } else { listview.TabStop = false; SuperView?.FocusNext (); @@ -716,7 +718,7 @@ namespace Terminal.Gui { /// /// The currently selected list item /// - public new ustring Text { + public new string Text { get { return text; } @@ -750,7 +752,7 @@ namespace Terminal.Gui { } SetValue (listview.SelectedItem > -1 ? searchset [listview.SelectedItem] : text); - search.CursorPosition = search.Text.ConsoleWidth; + search.CursorPosition = search.Text.GetColumns (); Search_Changed (this, new TextChangedEventArgs (search.Text)); OnOpenSelectedItem (); Reset (keepSearchText: true); @@ -758,7 +760,7 @@ namespace Terminal.Gui { isShow = false; } - private int GetSelectedItemFromSource (ustring value) + private int GetSelectedItemFromSource (string value) { if (source == null) { return -1; @@ -814,7 +816,7 @@ namespace Terminal.Gui { return; } - if (ustring.IsNullOrEmpty (search.Text) && ustring.IsNullOrEmpty (e.OldValue)) { + if (string.IsNullOrEmpty (search.Text) && string.IsNullOrEmpty (e.OldValue)) { ResetSearchSet (); } else if (search.Text != e.OldValue) { isShow = true; diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index f537fb25a..2a4b95161 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -8,7 +8,7 @@ using System; using System.Globalization; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -123,13 +123,13 @@ namespace Terminal.Gui { string GetLongFormat (string lf) { - ustring [] frm = ustring.Make (lf).Split (ustring.Make (sepChar)); + string [] frm = lf.Split (sepChar); for (int i = 0; i < frm.Length; i++) { - if (frm [i].Contains ("M") && frm [i].RuneCount < 2) + if (frm [i].Contains ("M") && frm [i].GetRuneCount () < 2) lf = lf.Replace ("M", "MM"); - if (frm [i].Contains ("d") && frm [i].RuneCount < 2) + if (frm [i].Contains ("d") && frm [i].GetRuneCount () < 2) lf = lf.Replace ("d", "dd"); - if (frm [i].Contains ("y") && frm [i].RuneCount < 4) + if (frm [i].Contains ("y") && frm [i].GetRuneCount () < 4) lf = lf.Replace ("yy", "yyyy"); } return $" {lf}"; @@ -198,17 +198,17 @@ namespace Terminal.Gui { newText.Add (key); if (CursorPosition < fieldLen) newText = newText.Concat (text.GetRange (CursorPosition + 1, text.Count - (CursorPosition + 1))).ToList (); - return SetText (ustring.Make (newText)); + return SetText (StringExtensions.ToString (newText)); } - bool SetText (ustring text) + bool SetText (string text) { - if (text.IsEmpty) { + if (string.IsNullOrEmpty (text)) { return false; } - ustring [] vals = text.Split (ustring.Make (sepChar)); - ustring [] frm = ustring.Make (format).Split (ustring.Make (sepChar)); + string [] vals = text.Split (sepChar); + string [] frm = format.Split (sepChar); bool isValidDate = true; int idx = GetFormatIndex (frm, "y"); int year = Int32.Parse (vals [idx].ToString ()); @@ -245,7 +245,7 @@ namespace Terminal.Gui { return true; } - string GetDate (int month, int day, int year, ustring [] fm) + string GetDate (int month, int day, int year, string [] fm) { string date = " "; for (int i = 0; i < fm.Length; i++) { @@ -269,32 +269,31 @@ namespace Terminal.Gui { return date; } - ustring GetDate (ustring text) + string GetDate (string text) { - ustring [] vals = text.Split (ustring.Make (sepChar)); - ustring [] frm = ustring.Make (format).Split (ustring.Make (sepChar)); - ustring [] date = { null, null, null }; + string [] vals = text.Split (sepChar); + string [] frm = format.Split (sepChar); + string [] date = { null, null, null }; for (int i = 0; i < frm.Length; i++) { if (frm [i].Contains ("M")) { - date [0] = vals [i].TrimSpace (); + date [0] = vals [i].Trim (); } else if (frm [i].Contains ("d")) { - date [1] = vals [i].TrimSpace (); + date [1] = vals [i].Trim (); } else { - var year = vals [i].TrimSpace (); - if (year.RuneCount == 2) { + var year = vals [i].Trim (); + if (year.GetRuneCount () == 2) { var y = DateTime.Now.Year.ToString (); date [2] = y.Substring (0, 2) + year.ToString (); } else { - date [2] = vals [i].TrimSpace (); + date [2] = vals [i].Trim (); } } } - return date [0] + ustring.Make (sepChar) + date [1] + ustring.Make (sepChar) + date [2]; - + return date [0] + sepChar + date [1] + sepChar + date [2]; } - int GetFormatIndex (ustring [] fm, string t) + int GetFormatIndex (string [] fm, string t) { int idx = -1; for (int i = 0; i < fm.Length; i++) { @@ -342,7 +341,7 @@ namespace Terminal.Gui { if (ReadOnly) return true; - if (SetText (TextModel.ToRunes (ustring.Make ((uint)kb.Key)).First ())) + if (SetText (TextModel.ToRunes (((Rune)(uint)kb.Key).ToString ()).First ())) IncCursorPosition (); return true; @@ -379,7 +378,7 @@ namespace Terminal.Gui { if (ReadOnly) return; - SetText ('0'); + SetText ((Rune)'0'); DecCursorPosition (); return; } @@ -390,7 +389,7 @@ namespace Terminal.Gui { if (ReadOnly) return; - SetText ('0'); + SetText ((Rune)'0'); return; } @@ -418,7 +417,7 @@ namespace Terminal.Gui { /// Event arguments public virtual void OnDateChanged (DateTimeEventArgs args) { - DateChanged?.Invoke (this,args); + DateChanged?.Invoke (this, args); } } } \ No newline at end of file diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index 801419ea8..db7016394 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -8,7 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; -using NStack; +using System.Text; using Terminal.Gui; using static Terminal.Gui.ConfigurationManager; diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 6545d360d..8a6a7f0bc 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using NStack; +using System.Text; using Terminal.Gui.Resources; using static Terminal.Gui.ConfigurationManager; @@ -413,8 +413,8 @@ namespace Terminal.Gui { private string GetToggleSplitterText (bool isExpanded) { return isExpanded ? - new string ((char)CM.Glyphs.LeftArrow, 2) : - new string ((char)CM.Glyphs.RightArrow, 2); + new string ((char)CM.Glyphs.LeftArrow.Value, 2) : + new string ((char)CM.Glyphs.RightArrow.Value, 2); } private void Delete () @@ -549,7 +549,7 @@ namespace Terminal.Gui { /// is true. /// public string Path { - get => this.tbPath.Text.ToString (); + get => this.tbPath.Text; set { this.tbPath.Text = value; this.tbPath.MoveEnd (); @@ -600,7 +600,7 @@ namespace Terminal.Gui { base.OnDrawContent (contentArea); if (!string.IsNullOrWhiteSpace (feedback)) { - var feedbackWidth = feedback.Sum (c => Rune.ColumnWidth (c)); + var feedbackWidth = feedback.EnumerateRunes ().Sum (c => c.GetColumns ()); var feedbackPadLeft = ((Bounds.Width - feedbackWidth) / 2) - 1; feedbackPadLeft = Math.Min (Bounds.Width, feedbackPadLeft); @@ -692,7 +692,7 @@ namespace Terminal.Gui { this.tbPath.FocusFirst (); this.tbPath.SelectAll (); - if (ustring.IsNullOrEmpty (Title)) { + if (string.IsNullOrEmpty (Title)) { switch (OpenMode) { case OpenMode.File: this.Title = $"{Strings.fdOpen} {(MustExist ? Strings.fdExisting + " " : "")}{Strings.fdFile}"; @@ -802,7 +802,7 @@ namespace Terminal.Gui { return; } - if (!this.IsCompatibleWithOpenMode (this.tbPath.Text.ToString (), out string reason)) { + if (!this.IsCompatibleWithOpenMode (this.tbPath.Text, out string reason)) { if (reason != null) { feedback = reason; SetNeedsDisplay (); diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs index 8d4ec3061..9e9b4f33d 100644 --- a/Terminal.Gui/Views/FrameView.cs +++ b/Terminal.Gui/Views/FrameView.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using System.Text.Json.Serialization; -using NStack; +using System.Text; using static Terminal.Gui.ConfigurationManager; namespace Terminal.Gui { @@ -16,7 +16,7 @@ namespace Terminal.Gui { /// Frame. /// Title. /// Views. - public FrameView (Rect frame, ustring title = null, View [] views = null) : base (frame) + public FrameView (Rect frame, string title = null, View [] views = null) : base (frame) { SetInitialProperties (frame, title, views); } @@ -25,7 +25,7 @@ namespace Terminal.Gui { /// Initializes a new instance of the class using layout. /// /// Title. - public FrameView (ustring title) + public FrameView (string title) { SetInitialProperties (Rect.Empty, title, null); } @@ -46,7 +46,7 @@ namespace Terminal.Gui { [SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))] public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single; - void SetInitialProperties (Rect frame, ustring title, View [] views = null) + void SetInitialProperties (Rect frame, string title, View [] views = null) { this.Title = title; Border.Thickness = new Thickness (1); diff --git a/Terminal.Gui/Views/GraphView/Annotations.cs b/Terminal.Gui/Views/GraphView/Annotations.cs index 9c92cc40a..643b5acc6 100644 --- a/Terminal.Gui/Views/GraphView/Annotations.cs +++ b/Terminal.Gui/Views/GraphView/Annotations.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Views/GraphView/Axis.cs b/Terminal.Gui/Views/GraphView/Axis.cs index e1f197710..49e93c5db 100644 --- a/Terminal.Gui/Views/GraphView/Axis.cs +++ b/Terminal.Gui/Views/GraphView/Axis.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text; namespace Terminal.Gui { @@ -402,7 +403,7 @@ namespace Terminal.Gui { for (int i = 0; i < toRender.Length; i++) { graph.Move (0, startDrawingAtY + i); - Application.Driver.AddRune (toRender [i]); + Application.Driver.AddRune ((Rune)toRender [i]); } } diff --git a/Terminal.Gui/Views/GraphView/GraphCellToRender.cs b/Terminal.Gui/Views/GraphView/GraphCellToRender.cs index 46586a747..9d4fe121c 100644 --- a/Terminal.Gui/Views/GraphView/GraphCellToRender.cs +++ b/Terminal.Gui/Views/GraphView/GraphCellToRender.cs @@ -1,4 +1,5 @@ using System; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Views/GraphView/GraphView.cs b/Terminal.Gui/Views/GraphView/GraphView.cs index 2af54976e..9fe3e8533 100644 --- a/Terminal.Gui/Views/GraphView/GraphView.cs +++ b/Terminal.Gui/Views/GraphView/GraphView.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; @@ -156,7 +156,7 @@ namespace Terminal.Gui { if (AxisX.Visible && AxisY.Visible) { Move (axisIntersection.X, axisIntersection.Y); - AddRune (axisIntersection.X, axisIntersection.Y, '\u253C'); + AddRune (axisIntersection.X, axisIntersection.Y, (Rune)'\u253C'); } SetDriverColorToGraphColor (); diff --git a/Terminal.Gui/Views/GraphView/Series.cs b/Terminal.Gui/Views/GraphView/Series.cs index 3715dd2fa..c6618cc4f 100644 --- a/Terminal.Gui/Views/GraphView/Series.cs +++ b/Terminal.Gui/Views/GraphView/Series.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index 8fd8286b8..e01a41fd5 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace Terminal.Gui { /// @@ -238,7 +239,7 @@ namespace Terminal.Gui { Driver.AddStr (offset >= n && !edited ? " " : string.Format ("{0:x2}", value)); SetAttribute (GetNormalColor ()); - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } Driver.AddStr (block + 1 == nblocks ? " " : "| "); } @@ -248,14 +249,14 @@ namespace Terminal.Gui { var b = GetData (data, offset, out bool edited); Rune c; if (offset >= n && !edited) - c = ' '; + c = (Rune)' '; else { if (b < 32) - c = '.'; + c = (Rune)'.'; else if (b > 127) - c = '.'; + c = (Rune)'.'; else - c = b; + Rune.DecodeFromUtf8 (new ReadOnlySpan (b), out c, out _); } if (offset + displayStart == position || edited) SetAttribute (leftSide ? trackingColor : activeColor); diff --git a/Terminal.Gui/Views/HistoryTextItem.cs b/Terminal.Gui/Views/HistoryTextItem.cs index f28f4a11f..db0605f6e 100644 --- a/Terminal.Gui/Views/HistoryTextItem.cs +++ b/Terminal.Gui/Views/HistoryTextItem.cs @@ -1,7 +1,7 @@ // TextView.cs: multi-line text editing using System; using System.Collections.Generic; -using Rune = System.Rune; +using System.Text; namespace Terminal.Gui { partial class HistoryText { diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index de3f5374d..9ea34be11 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -6,7 +6,7 @@ // using System; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -30,25 +30,25 @@ namespace Terminal.Gui { } /// - public Label (ustring text, bool autosize = true) : base (text) + public Label (string text, bool autosize = true) : base (text) { SetInitialProperties (autosize); } /// - public Label (Rect rect, ustring text, bool autosize = false) : base (rect, text) + public Label (Rect rect, string text, bool autosize = false) : base (rect, text) { SetInitialProperties (autosize); } /// - public Label (int x, int y, ustring text, bool autosize = true) : base (x, y, text) + public Label (int x, int y, string text, bool autosize = true) : base (x, y, text) { SetInitialProperties (autosize); } /// - public Label (ustring text, TextDirection direction, bool autosize = true) + public Label (string text, TextDirection direction, bool autosize = true) : base (text, direction) { SetInitialProperties (autosize); diff --git a/Terminal.Gui/Views/LineView.cs b/Terminal.Gui/Views/LineView.cs index 8dcb834a2..2ada7c011 100644 --- a/Terminal.Gui/Views/LineView.cs +++ b/Terminal.Gui/Views/LineView.cs @@ -1,4 +1,5 @@ using System; +using System.Text; namespace Terminal.Gui { @@ -73,7 +74,7 @@ namespace Terminal.Gui { Move (0, 0); Driver.SetAttribute (GetNormalColor ()); - var hLineWidth = Math.Max (1, Rune.ColumnWidth (CM.Glyphs.HLine)); + var hLineWidth = Math.Max (1, CM.Glyphs.HLine.GetColumns ()); var dEnd = Orientation == Orientation.Horizontal ? Bounds.Width : diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index da2627b28..59f0e9a71 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -76,8 +76,8 @@ namespace Terminal.Gui { /// /// /// can display any object that implements the interface. - /// values are converted into values before rendering, and other values are - /// converted into by calling and then converting to . + /// values are converted into values before rendering, and other values are + /// converted into by calling and then converting to . /// /// /// To change the contents of the ListView, set the property (when @@ -376,7 +376,7 @@ namespace Terminal.Gui { Move (0, row); if (source == null || item >= source.Count) { for (int c = 0; c < f.Width; c++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } else { var rowEventArgs = new ListViewRowEventArgs (item); OnRowRender (rowEventArgs); @@ -387,7 +387,7 @@ namespace Terminal.Gui { if (allowsMarking) { Driver.AddRune (source.IsMarked (item) ? (AllowsMultipleSelection ? CM.Glyphs.Checked : CM.Glyphs.Selected) : (AllowsMultipleSelection ? CM.Glyphs.UnChecked : CM.Glyphs.UnSelected)); - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } Source.Render (this, Driver, isSelected, item, col, row, f.Width - col, start); } @@ -853,8 +853,8 @@ namespace Terminal.Gui { for (int i = 0; i < src.Count; i++) { var t = src [i]; int l; - if (t is ustring u) { - l = TextFormatter.GetTextWidth (u); + if (t is string u) { + l = u.GetColumns (); } else if (t is string s) { l = s.Length; } else { @@ -869,13 +869,13 @@ namespace Terminal.Gui { return maxLength; } - void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width, int start = 0) + void RenderUstr (ConsoleDriver driver, string ustr, int col, int line, int width, int start = 0) { var u = TextFormatter.ClipAndJustify (ustr, width, TextAlignment.Left); driver.AddStr (u); - width -= TextFormatter.GetTextWidth (u); + width -= u.GetColumns (); while (width-- > 0) { - driver.AddRune (' '); + driver.AddRune ((Rune)' '); } } @@ -885,9 +885,9 @@ namespace Terminal.Gui { container.Move (col, line); var t = src? [item]; if (t == null) { - RenderUstr (driver, ustring.Make (""), col, line, width); + RenderUstr (driver, "", col, line, width); } else { - if (t is ustring u) { + if (t is string u) { RenderUstr (driver, u, col, line, width, start); } else if (t is string s) { RenderUstr (driver, s, col, line, width, start); @@ -927,7 +927,7 @@ namespace Terminal.Gui { for (int i = 0; i < src.Count; i++) { var t = src [i]; - if (t is ustring u) { + if (t is string u) { if (u.ToUpper ().StartsWith (search.ToUpperInvariant ())) { return i; } diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 02bb86475..d0519ef10 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -1,5 +1,5 @@ using System; -using NStack; +using System.Text; using System.Linq; using System.Collections.Generic; @@ -31,7 +31,7 @@ namespace Terminal.Gui { /// MenuItems can also have a checked indicator (see ). /// public class MenuItem { - ustring title; + string title; ShortcutHelper shortcutHelper; bool allowNullChecked; MenuItemCheckStyle checkType; @@ -58,7 +58,7 @@ namespace Terminal.Gui { /// Function to determine if the action can currently be executed. /// The of this menu item. /// The keystroke combination. - public MenuItem (ustring title, ustring help, Action action, Func canExecute = null, MenuItem parent = null, Key shortcut = Key.Null) + public MenuItem (string title, string help, Action action, Func canExecute = null, MenuItem parent = null, Key shortcut = Key.Null) { Title = title ?? ""; Help = help ?? ""; @@ -107,13 +107,13 @@ namespace Terminal.Gui { /// /// Gets the text describing the keystroke combination defined by . /// - public ustring ShortcutTag => ShortcutHelper.GetShortcutTag (shortcutHelper.Shortcut); + public string ShortcutTag => ShortcutHelper.GetShortcutTag (shortcutHelper.Shortcut); /// /// Gets or sets the title of the menu item . /// /// The title. - public ustring Title { + public string Title { get { return title; } set { if (title != value) { @@ -127,7 +127,7 @@ namespace Terminal.Gui { /// Gets or sets the help text for the menu item. The help text is drawn to the right of the . /// /// The help text. - public ustring Help { get; set; } + public string Help { get; set; } /// /// Gets or sets the action to be invoked when the menu item is triggered. @@ -162,8 +162,8 @@ namespace Terminal.Gui { TitleLength + 2 + // space after Title - BUGBUG: This should be 1 (Checked == true || CheckType.HasFlag (MenuItemCheckStyle.Checked) || CheckType.HasFlag (MenuItemCheckStyle.Radio) ? 2 : 0) + // check glyph + space - (Help.ConsoleWidth > 0 ? 2 + Help.ConsoleWidth : 0) + // Two spaces before Help - (ShortcutTag.ConsoleWidth > 0 ? 2 + ShortcutTag.ConsoleWidth : 0); // Pad two spaces before shortcut tag (which are also aligned right) + (Help.GetColumns () > 0 ? 2 + Help.GetColumns () : 0) + // Two spaces before Help + (ShortcutTag.GetColumns () > 0 ? 2 + ShortcutTag.GetColumns () : 0); // Pad two spaces before shortcut tag (which are also aligned right) /// /// Sets or gets whether the shows a check indicator or not. See . @@ -256,11 +256,11 @@ namespace Terminal.Gui { { bool nextIsHot = false; foreach (var x in title) { - if (x == MenuBar.HotKeySpecifier) { + if (x == MenuBar.HotKeySpecifier.Value) { nextIsHot = true; } else { if (nextIsHot) { - HotKey = Char.ToUpper ((char)x); + HotKey = (Rune)Char.ToUpper ((char)x); break; } nextIsHot = false; @@ -269,13 +269,13 @@ namespace Terminal.Gui { } } - int GetMenuBarItemLength (ustring title) + int GetMenuBarItemLength (string title) { int len = 0; - foreach (var ch in title) { + foreach (var ch in title.EnumerateRunes ()) { if (ch == MenuBar.HotKeySpecifier) continue; - len += Math.Max (Rune.ColumnWidth (ch), 1); + len += Math.Max (ch.GetColumns (), 1); } return len; @@ -295,7 +295,7 @@ namespace Terminal.Gui { /// Action to invoke when the menu item is activated. /// Function to determine if the action can currently be executed. /// The parent of this if exist, otherwise is null. - public MenuBarItem (ustring title, ustring help, Action action, Func canExecute = null, MenuItem parent = null) : base (title, help, action, canExecute, parent) + public MenuBarItem (string title, string help, Action action, Func canExecute = null, MenuItem parent = null) : base (title, help, action, canExecute, parent) { Initialize (title, null, null, true); } @@ -306,7 +306,7 @@ namespace Terminal.Gui { /// Title for the menu item. /// The items in the current menu. /// The parent of this if exist, otherwise is null. - public MenuBarItem (ustring title, MenuItem [] children, MenuItem parent = null) + public MenuBarItem (string title, MenuItem [] children, MenuItem parent = null) { Initialize (title, children, parent); } @@ -317,7 +317,7 @@ namespace Terminal.Gui { /// Title for the menu item. /// The list of items in the current menu. /// The parent of this if exist, otherwise is null. - public MenuBarItem (ustring title, List children, MenuItem parent = null) + public MenuBarItem (string title, List children, MenuItem parent = null) { Initialize (title, children, parent); } @@ -333,7 +333,7 @@ namespace Terminal.Gui { /// public MenuBarItem () : this (children: new MenuItem [] { }) { } - void Initialize (ustring title, object children, MenuItem parent = null, bool isTopLevel = false) + void Initialize (string title, object children, MenuItem parent = null, bool isTopLevel = false) { if (!isTopLevel && children == null) { throw new ArgumentNullException (nameof (children), "The parameter cannot be null. Use an empty array instead."); @@ -414,10 +414,10 @@ namespace Terminal.Gui { return -1; } - void SetTitle (ustring title) + void SetTitle (string title) { if (title == null) - title = ustring.Empty; + title = string.Empty; Title = title; } @@ -612,7 +612,7 @@ namespace Terminal.Gui { else if (p == Frame.Width - 3 && barItems.SubMenu (barItems.Children [i]) != null) Driver.AddRune (CM.Glyphs.RightArrow); else - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } if (item == null) { @@ -623,7 +623,7 @@ namespace Terminal.Gui { continue; } - ustring textToDraw; + string textToDraw = null; var nullCheckedChar = CM.Glyphs.NullChecked; var checkChar = CM.Glyphs.Selected; var uncheckedChar = CM.Glyphs.UnSelected; @@ -635,11 +635,11 @@ namespace Terminal.Gui { // Support Checked even though CheckType wasn't set if (item.CheckType == MenuItemCheckStyle.Checked && item.Checked == null) { - textToDraw = ustring.Make (new Rune [] { nullCheckedChar, ' ' }) + item.Title; + textToDraw = $"{nullCheckedChar} {item.Title}"; } else if (item.Checked == true) { - textToDraw = ustring.Make (new Rune [] { checkChar, ' ' }) + item.Title; + textToDraw = $"{checkChar} {item.Title}"; } else if (item.CheckType.HasFlag (MenuItemCheckStyle.Checked) || item.CheckType.HasFlag (MenuItemCheckStyle.Radio)) { - textToDraw = ustring.Make (new Rune [] { uncheckedChar, ' ' }) + item.Title; + textToDraw = $"{uncheckedChar} {item.Title}"; } else { textToDraw = item.Title; } @@ -667,7 +667,7 @@ namespace Terminal.Gui { } // The help string - var l = item.ShortcutTag.ConsoleWidth == 0 ? item.Help.ConsoleWidth : item.Help.ConsoleWidth + item.ShortcutTag.ConsoleWidth + 2; + var l = item.ShortcutTag.GetColumns () == 0 ? item.Help.GetColumns () : item.Help.GetColumns () + item.ShortcutTag.GetColumns () + 2; var col = Frame.Width - l - 3; ViewToScreen (col, i, out vtsCol, out vtsRow, false); if (vtsCol < Driver.Cols) { @@ -675,8 +675,8 @@ namespace Terminal.Gui { Driver.AddStr (item.Help); // The shortcut tag string - if (!item.ShortcutTag.IsEmpty) { - Driver.Move (vtsCol + l - item.ShortcutTag.ConsoleWidth, vtsRow); + if (!string.IsNullOrEmpty (item.ShortcutTag)) { + Driver.Move (vtsCol + l - item.ShortcutTag.GetColumns (), vtsRow); Driver.AddStr (item.ShortcutTag); } } @@ -760,7 +760,7 @@ namespace Terminal.Gui { foreach (var item in barItems.Children) { idx++; if (item == null) continue; - if (item.IsEnabled () && item.HotKey == x) { + if (item.IsEnabled () && item.HotKey.Value == x) { current = idx; RunSelected (); return true; @@ -1050,15 +1050,15 @@ namespace Terminal.Gui { } } - static ustring shortcutDelimiter = "+"; + static string shortcutDelimiter = "+"; /// /// Sets or gets the shortcut delimiter separator. The default is "+". /// - public static ustring ShortcutDelimiter { + public static string ShortcutDelimiter { get => shortcutDelimiter; set { if (shortcutDelimiter != value) { - shortcutDelimiter = value == ustring.Empty ? " " : value; + shortcutDelimiter = value == string.Empty ? " " : value; } } } @@ -1066,7 +1066,7 @@ namespace Terminal.Gui { /// /// The specifier character for the hotkey to all menus. /// - new public static Rune HotKeySpecifier => '_'; + new public static Rune HotKeySpecifier => (Rune)'_'; private bool useSubMenusSingleFrame; @@ -1238,7 +1238,7 @@ namespace Terminal.Gui { Move (0, 0); Driver.SetAttribute (GetNormalColor ()); for (int i = 0; i < Frame.Width; i++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); Move (1, 0); int pos = 0; @@ -1255,8 +1255,8 @@ namespace Terminal.Gui { normalColor = GetNormalColor (); } // Note Help on MenuBar is drawn with parens around it - DrawHotString (menu.Help.IsEmpty ? $" {menu.Title} " : $" {menu.Title} ({menu.Help}) ", hotColor, normalColor); - pos += leftPadding + menu.TitleLength + (menu.Help.ConsoleWidth > 0 ? leftPadding + menu.Help.ConsoleWidth + parensAroundHelp : 0) + rightPadding; + DrawHotString (string.IsNullOrEmpty (menu.Help) ? $" {menu.Title} " : $" {menu.Title} ({menu.Help}) ", hotColor, normalColor); + pos += leftPadding + menu.TitleLength + (menu.Help.GetColumns () > 0 ? leftPadding + menu.Help.GetColumns () + parensAroundHelp : 0) + rightPadding; } PositionCursor (); } @@ -1274,7 +1274,7 @@ namespace Terminal.Gui { Move (pos + 1, 0); return; } else { - pos += leftPadding + Menus [i].TitleLength + (Menus [i].Help.ConsoleWidth > 0 ? Menus [i].Help.ConsoleWidth + parensAroundHelp : 0) + rightPadding; + pos += leftPadding + Menus [i].TitleLength + (Menus [i].Help.GetColumns () > 0 ? Menus [i].Help.GetColumns () + parensAroundHelp : 0) + rightPadding; } } } @@ -1429,7 +1429,7 @@ namespace Terminal.Gui { // This positions the submenu horizontally aligned with the first character of the // text belonging to the menu for (int i = 0; i < index; i++) - pos += Menus [i].TitleLength + (Menus [i].Help.ConsoleWidth > 0 ? Menus [i].Help.ConsoleWidth + 2 : 0) + leftPadding + rightPadding; + pos += Menus [i].TitleLength + (Menus [i].Help.GetColumns () > 0 ? Menus [i].Help.GetColumns () + 2 : 0) + leftPadding + rightPadding; var locationOffset = Point.Empty; // if SuperView is null then it's from a ContextMenu @@ -1807,8 +1807,8 @@ namespace Terminal.Gui { for (int i = 0; i < Menus.Length; i++) { // TODO: this code is duplicated, hotkey should be part of the MenuBarItem var mi = Menus [i]; - int p = mi.Title.IndexOf (MenuBar.HotKeySpecifier); - if (p != -1 && p + 1 < mi.Title.RuneCount) { + int p = mi.Title.IndexOf (MenuBar.HotKeySpecifier.ToString ()); + if (p != -1 && p + 1 < mi.Title.GetRuneCount ()) { if (Char.ToUpperInvariant ((char)mi.Title [p + 1]) == c) { ProcessMenu (i, mi); return true; @@ -1916,8 +1916,8 @@ namespace Terminal.Gui { foreach (var mi in Menus [selected].Children) { if (mi == null) continue; - int p = mi.Title.IndexOf (MenuBar.HotKeySpecifier); - if (p != -1 && p + 1 < mi.Title.RuneCount) { + int p = mi.Title.IndexOf (MenuBar.HotKeySpecifier.ToString ()); + if (p != -1 && p + 1 < mi.Title.GetRuneCount ()) { if (mi.Title [p + 1] == c) { Selected (mi); return true; @@ -1981,7 +1981,7 @@ namespace Terminal.Gui { } int cx = me.X - locationOffset.X; for (int i = 0; i < Menus.Length; i++) { - if (cx >= pos && cx < pos + leftPadding + Menus [i].TitleLength + Menus [i].Help.ConsoleWidth + rightPadding) { + if (cx >= pos && cx < pos + leftPadding + Menus [i].TitleLength + Menus [i].Help.GetColumns () + rightPadding) { if (me.Flags == MouseFlags.Button1Clicked) { if (Menus [i].IsTopLevel) { ViewToScreen (i, 0, out int rx, out int ry); diff --git a/Terminal.Gui/Views/MessageBox.cs b/Terminal.Gui/Views/MessageBox.cs index aa40a9e33..1ab1bd567 100644 --- a/Terminal.Gui/Views/MessageBox.cs +++ b/Terminal.Gui/Views/MessageBox.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using Terminal.Gui; @@ -9,7 +9,7 @@ namespace Terminal.Gui { /// MessageBox displays a modal message to the user, with a title, a message and a series of options that the user can choose from. /// /// - /// The difference between the and + /// The difference between the and /// method is the default set of colors used for the message box. /// /// @@ -36,9 +36,9 @@ namespace Terminal.Gui { /// Message to display, might contain multiple lines. /// Array of buttons to add. /// - /// Use instead; it automatically sizes the MessageBox based on the contents. + /// Use instead; it automatically sizes the MessageBox based on the contents. /// - public static int Query (int width, int height, ustring title, ustring message, params ustring [] buttons) + public static int Query (int width, int height, string title, string message, params string [] buttons) { return QueryFull (false, width, height, title, message, 0, true, buttons); } @@ -54,7 +54,7 @@ namespace Terminal.Gui { /// The message box will be vertically and horizontally centered in the container and the size will be automatically determined /// from the size of the message and buttons. /// - public static int Query (ustring title, ustring message, params ustring [] buttons) + public static int Query (string title, string message, params string [] buttons) { return QueryFull (false, 0, 0, title, message, 0, true, buttons); } @@ -69,9 +69,9 @@ namespace Terminal.Gui { /// Message to display, might contain multiple lines. /// Array of buttons to add. /// - /// Use instead; it automatically sizes the MessageBox based on the contents. + /// Use instead; it automatically sizes the MessageBox based on the contents. /// - public static int ErrorQuery (int width, int height, ustring title, ustring message, params ustring [] buttons) + public static int ErrorQuery (int width, int height, string title, string message, params string [] buttons) { return QueryFull (true, width, height, title, message, 0, true, buttons); } @@ -87,7 +87,7 @@ namespace Terminal.Gui { /// The message box will be vertically and horizontally centered in the container and the size will be automatically determined /// from the size of the title, message. and buttons. /// - public static int ErrorQuery (ustring title, ustring message, params ustring [] buttons) + public static int ErrorQuery (string title, string message, params string [] buttons) { return QueryFull (true, 0, 0, title, message, 0, true, buttons); } @@ -103,9 +103,9 @@ namespace Terminal.Gui { /// Index of the default button. /// Array of buttons to add. /// - /// Use instead; it automatically sizes the MessageBox based on the contents. + /// Use instead; it automatically sizes the MessageBox based on the contents. /// - public static int Query (int width, int height, ustring title, ustring message, int defaultButton = 0, params ustring [] buttons) + public static int Query (int width, int height, string title, string message, int defaultButton = 0, params string [] buttons) { return QueryFull (false, width, height, title, message, defaultButton, true, buttons); } @@ -122,7 +122,7 @@ namespace Terminal.Gui { /// The message box will be vertically and horizontally centered in the container and the size will be automatically determined /// from the size of the message and buttons. /// - public static int Query (ustring title, ustring message, int defaultButton = 0, params ustring [] buttons) + public static int Query (string title, string message, int defaultButton = 0, params string [] buttons) { return QueryFull (false, 0, 0, title, message, defaultButton, true, buttons); } @@ -139,9 +139,9 @@ namespace Terminal.Gui { /// If wrap the message or not. /// Array of buttons to add. /// - /// Use instead; it automatically sizes the MessageBox based on the contents. + /// Use instead; it automatically sizes the MessageBox based on the contents. /// - public static int Query (int width, int height, ustring title, ustring message, int defaultButton = 0, bool wrapMessagge = true, params ustring [] buttons) + public static int Query (int width, int height, string title, string message, int defaultButton = 0, bool wrapMessagge = true, params string [] buttons) { return QueryFull (false, width, height, title, message, defaultButton, wrapMessagge, buttons); } @@ -159,7 +159,7 @@ namespace Terminal.Gui { /// The message box will be vertically and horizontally centered in the container and the size will be automatically determined /// from the size of the message and buttons. /// - public static int Query (ustring title, ustring message, int defaultButton = 0, bool wrapMessage = true, params ustring [] buttons) + public static int Query (string title, string message, int defaultButton = 0, bool wrapMessage = true, params string [] buttons) { return QueryFull (false, 0, 0, title, message, defaultButton, wrapMessage, buttons); } @@ -175,9 +175,9 @@ namespace Terminal.Gui { /// Index of the default button. /// Array of buttons to add. /// - /// Use instead; it automatically sizes the MessageBox based on the contents. + /// Use instead; it automatically sizes the MessageBox based on the contents. /// - public static int ErrorQuery (int width, int height, ustring title, ustring message, int defaultButton = 0, params ustring [] buttons) + public static int ErrorQuery (int width, int height, string title, string message, int defaultButton = 0, params string [] buttons) { return QueryFull (true, width, height, title, message, defaultButton, true, buttons); } @@ -194,7 +194,7 @@ namespace Terminal.Gui { /// The message box will be vertically and horizontally centered in the container and the size will be automatically determined /// from the size of the title, message. and buttons. /// - public static int ErrorQuery (ustring title, ustring message, int defaultButton = 0, params ustring [] buttons) + public static int ErrorQuery (string title, string message, int defaultButton = 0, params string [] buttons) { return QueryFull (true, 0, 0, title, message, defaultButton, true, buttons); } @@ -211,9 +211,9 @@ namespace Terminal.Gui { /// If wrap the message or not. /// Array of buttons to add. /// - /// Use instead; it automatically sizes the MessageBox based on the contents. + /// Use instead; it automatically sizes the MessageBox based on the contents. /// - public static int ErrorQuery (int width, int height, ustring title, ustring message, int defaultButton = 0, bool wrapMessagge = true, params ustring [] buttons) + public static int ErrorQuery (int width, int height, string title, string message, int defaultButton = 0, bool wrapMessagge = true, params string [] buttons) { return QueryFull (true, width, height, title, message, defaultButton, wrapMessagge, buttons); } @@ -231,7 +231,7 @@ namespace Terminal.Gui { /// The message box will be vertically and horizontally centered in the container and the size will be automatically determined /// from the size of the title, message. and buttons. /// - public static int ErrorQuery (ustring title, ustring message, int defaultButton = 0, bool wrapMessagge = true, params ustring [] buttons) + public static int ErrorQuery (string title, string message, int defaultButton = 0, bool wrapMessagge = true, params string [] buttons) { return QueryFull (true, 0, 0, title, message, defaultButton, wrapMessagge, buttons); } @@ -242,8 +242,8 @@ namespace Terminal.Gui { [SerializableConfigurationProperty (Scope = typeof (ThemeScope))] public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single; - static int QueryFull (bool useErrorColors, int width, int height, ustring title, ustring message, - int defaultButton = 0, bool wrapMessage = true, params ustring [] buttons) + static int QueryFull (bool useErrorColors, int width, int height, string title, string message, + int defaultButton = 0, bool wrapMessage = true, params string [] buttons) { // Create button array for Dialog int count = 0; diff --git a/Terminal.Gui/Views/OpenDialog.cs b/Terminal.Gui/Views/OpenDialog.cs index bcf4d908d..4e16831fe 100644 --- a/Terminal.Gui/Views/OpenDialog.cs +++ b/Terminal.Gui/Views/OpenDialog.cs @@ -11,7 +11,7 @@ using System; using System.Collections.Generic; -using NStack; +using System.Text; using System.IO; using System.Linq; using Terminal.Gui.Resources; @@ -68,7 +68,7 @@ namespace Terminal.Gui { /// The title. /// The allowed types. /// The open mode. - public OpenDialog (ustring title, List allowedTypes = null, OpenMode openMode = OpenMode.File) + public OpenDialog (string title, List allowedTypes = null, OpenMode openMode = OpenMode.File) { this.OpenMode = openMode; Title = title; diff --git a/Terminal.Gui/Views/ProgressBar.cs b/Terminal.Gui/Views/ProgressBar.cs index 78cd28d92..f2daf0d91 100644 --- a/Terminal.Gui/Views/ProgressBar.cs +++ b/Terminal.Gui/Views/ProgressBar.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; namespace Terminal.Gui { /// @@ -184,7 +184,7 @@ namespace Terminal.Gui { } /// - public override ustring Text { + public override string Text { get => GetPercentageText (); set { base.Text = SetPercentageText (value); @@ -206,7 +206,7 @@ namespace Terminal.Gui { } } - ustring GetPercentageText () + string GetPercentageText () { switch (progressBarStyle) { case ProgressBarStyle.Blocks: @@ -220,7 +220,7 @@ namespace Terminal.Gui { return base.Text; } - ustring SetPercentageText (ustring value) + string SetPercentageText (string value) { switch (progressBarStyle) { case ProgressBarStyle.Blocks: @@ -288,7 +288,7 @@ namespace Terminal.Gui { if (Array.IndexOf (activityPos, i) != -1) Driver.AddRune (SegmentCharacter); else - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } else { Move (padding, padding); int mid = (int)(fraction * fWidth); @@ -296,7 +296,7 @@ namespace Terminal.Gui { for (i = 0; i < mid & i < fWidth; i++) Driver.AddRune (SegmentCharacter); for (; i < fWidth; i++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } DrawText (fWidth); diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index 62888880c..db4656f4f 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; @@ -17,14 +17,14 @@ namespace Terminal.Gui { /// /// Initializes a new instance of the class using layout. /// - public RadioGroup () : this (radioLabels: new ustring [] { }) { } + public RadioGroup () : this (radioLabels: new string [] { }) { } /// /// Initializes a new instance of the class using layout. /// /// The radio labels; an array of strings that can contain hotkeys using an underscore before the letter. /// The index of the item to be selected, the value is clamped to the number of items. - public RadioGroup (ustring [] radioLabels, int selected = 0) : base () + public RadioGroup (string [] radioLabels, int selected = 0) : base () { SetInitalProperties (Rect.Empty, radioLabels, selected); } @@ -35,7 +35,7 @@ namespace Terminal.Gui { /// Boundaries for the radio group. /// The radio labels; an array of strings that can contain hotkeys using an underscore before the letter. /// The index of item to be selected, the value is clamped to the number of items. - public RadioGroup (Rect rect, ustring [] radioLabels, int selected = 0) : base (rect) + public RadioGroup (Rect rect, string [] radioLabels, int selected = 0) : base (rect) { SetInitalProperties (rect, radioLabels, selected); } @@ -48,14 +48,14 @@ namespace Terminal.Gui { /// The y coordinate. /// The radio labels; an array of strings that can contain hotkeys using an underscore before the letter. /// The item to be selected, the value is clamped to the number of items. - public RadioGroup (int x, int y, ustring [] radioLabels, int selected = 0) : + public RadioGroup (int x, int y, string [] radioLabels, int selected = 0) : this (MakeRect (x, y, radioLabels != null ? radioLabels.ToList () : null), radioLabels, selected) { } - void SetInitalProperties (Rect rect, ustring [] radioLabels, int selected) + void SetInitalProperties (Rect rect, string [] radioLabels, int selected) { if (radioLabels == null) { - this.radioLabels = new List (); + this.radioLabels = new List (); } else { this.radioLabels = radioLabels.ToList (); } @@ -116,7 +116,7 @@ namespace Terminal.Gui { } } - void SetWidthHeight (List radioLabels) + void SetWidthHeight (List radioLabels) { switch (displayMode) { case DisplayModeLayout.Vertical: @@ -141,7 +141,7 @@ namespace Terminal.Gui { } } - static Rect MakeRect (int x, int y, List radioLabels) + static Rect MakeRect (int x, int y, List radioLabels) { if (radioLabels == null) { return new Rect (x, y, 0, 0); @@ -150,18 +150,18 @@ namespace Terminal.Gui { int width = 0; foreach (var s in radioLabels) { - width = Math.Max (s.ConsoleWidth + 2, width); + width = Math.Max (s.GetColumns () + 2, width); } return new Rect (x, y, width, radioLabels.Count); } - List radioLabels = new List (); + List radioLabels = new List (); /// /// The radio labels to display /// /// The radio labels. - public ustring [] RadioLabels { + public string [] RadioLabels { get => radioLabels.ToArray (); set { var prevCount = radioLabels.Count; @@ -183,7 +183,7 @@ namespace Terminal.Gui { int length = 0; for (int i = 0; i < radioLabels.Count; i++) { start += length; - length = radioLabels [i].ConsoleWidth + 2 + (i < radioLabels.Count - 1 ? horizontalSpace : 0); + length = radioLabels [i].GetColumns () + 2 + (i < radioLabels.Count - 1 ? horizontalSpace : 0); horizontal.Add ((start, length)); } } @@ -206,7 +206,7 @@ namespace Terminal.Gui { } var rl = radioLabels [i]; Driver.SetAttribute (GetNormalColor ()); - Driver.AddStr (ustring.Make (new Rune [] { i == selected ? CM.Glyphs.Selected : CM.Glyphs.UnSelected, ' ' })); + Driver.AddStr ($"{(i == selected ? CM.Glyphs.Selected : CM.Glyphs.UnSelected)} "); TextFormatter.FindHotKey (rl, HotKeySpecifier, true, out int hotPos, out Key hotKey); if (hotPos != -1 && (hotKey != Key.Null || hotKey != Key.Unknown)) { var rlRunes = rl.ToRunes (); @@ -301,7 +301,7 @@ namespace Terminal.Gui { if (c == HotKeySpecifier) { nextIsHot = true; } else { - if ((nextIsHot && Rune.ToUpper (c) == key) || (key == (uint)hotKey)) { + if ((nextIsHot && Rune.ToUpperInvariant (c).Value == key) || (key == (uint)hotKey)) { SelectedItem = i; cursor = i; if (!HasFocus) diff --git a/Terminal.Gui/Views/SaveDialog.cs b/Terminal.Gui/Views/SaveDialog.cs index fe968628f..b5d689311 100644 --- a/Terminal.Gui/Views/SaveDialog.cs +++ b/Terminal.Gui/Views/SaveDialog.cs @@ -11,7 +11,7 @@ using System; using System.Collections.Generic; -using NStack; +using System.Text; using Terminal.Gui.Resources; namespace Terminal.Gui { @@ -38,7 +38,7 @@ namespace Terminal.Gui { /// /// The title. /// The allowed types. - public SaveDialog (ustring title, List allowedTypes = null) + public SaveDialog (string title, List allowedTypes = null) { //: base (title, prompt: Strings.fdSave, nameFieldLabel: $"{Strings.fdSaveAs}:", message: message, allowedTypes) { } Title = title; @@ -54,7 +54,7 @@ namespace Terminal.Gui { /// if the user canceled the . /// /// The name of the file. - public ustring FileName { + public string FileName { get { if (Canceled) return null; diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index 471232cc5..0665acf54 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -6,6 +6,7 @@ // using System; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs index 9cf90e274..a67d3dd05 100644 --- a/Terminal.Gui/Views/StatusBar.cs +++ b/Terminal.Gui/Views/StatusBar.cs @@ -8,7 +8,7 @@ // Add mouse support using System; using System.Collections.Generic; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -27,7 +27,7 @@ namespace Terminal.Gui { /// Shortcut to activate the . /// Title for the . /// Action to invoke when the is activated. - public StatusItem (Key shortcut, ustring title, Action action) + public StatusItem (Key shortcut, string title, Action action) { Title = title ?? ""; Shortcut = shortcut; @@ -48,7 +48,7 @@ namespace Terminal.Gui { /// A set to `~F1~ Help` will render as *F1* using and /// *Help* as . /// - public ustring Title { get; set; } + public string Title { get; set; } /// /// Gets or sets the action to be invoked when the statusbar item is triggered @@ -96,15 +96,15 @@ namespace Terminal.Gui { Height = 1; } - static ustring shortcutDelimiter = "-"; + static string shortcutDelimiter = "-"; /// /// Used for change the shortcut delimiter separator. /// - public static ustring ShortcutDelimiter { + public static string ShortcutDelimiter { get => shortcutDelimiter; set { if (shortcutDelimiter != value) { - shortcutDelimiter = value == ustring.Empty ? " " : value; + shortcutDelimiter = value == string.Empty ? " " : value; } } } @@ -122,24 +122,24 @@ namespace Terminal.Gui { Move (0, 0); Driver.SetAttribute (GetNormalColor ()); for (int i = 0; i < Frame.Width; i++) - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); Move (1, 0); var scheme = GetNormalColor (); Driver.SetAttribute (scheme); for (int i = 0; i < Items.Length; i++) { var title = Items [i].Title.ToString (); - for (int n = 0; n < Items [i].Title.RuneCount; n++) { + for (int n = 0; n < Items [i].Title.GetRuneCount (); n++) { if (title [n] == '~') { scheme = ToggleScheme (scheme); continue; } - Driver.AddRune (title [n]); + Driver.AddRune ((Rune)title [n]); } if (i + 1 < Items.Length) { - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); Driver.AddRune (CM.Glyphs.VLine); - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } } } @@ -173,7 +173,7 @@ namespace Terminal.Gui { return true; } - int GetItemTitleLength (ustring title) + int GetItemTitleLength (string title) { int len = 0; foreach (var ch in title) { diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 7bb2bf335..0f827428d 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Data; @@ -336,9 +336,9 @@ namespace Terminal.Gui { foreach (var tab in Tabs.Skip (TabScrollOffset)) { // while there is space for the tab - var tabTextWidth = tab.Text.Sum (c => Rune.ColumnWidth (c)); + var tabTextWidth = tab.Text.EnumerateRunes ().Sum (c => c.GetColumns ()); - string text = tab.Text.ToString (); + string text = tab.Text; // The maximum number of characters to use for the tab name as specified // by the user (MaxTabTextWidth). But not more than the width of the view @@ -352,7 +352,7 @@ namespace Terminal.Gui { } if (tabTextWidth > maxWidth) { - text = tab.Text.ToString ().Substring (0, (int)maxWidth); + text = tab.Text.Substring (0, (int)maxWidth); tabTextWidth = (int)maxWidth; } @@ -750,13 +750,13 @@ namespace Terminal.Gui { /// A single tab in a /// public class Tab { - private ustring text; + private string text; /// /// The text to display in a /// /// - public ustring Text { get => text ?? "Unamed"; set => text = value; } + public string Text { get => text ?? "Unamed"; set => text = value; } /// /// The control to display when the tab is selected diff --git a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs index 14072b7e1..405727955 100644 --- a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs +++ b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs @@ -1,6 +1,7 @@ using System; using System.Data; using System.Linq; +using System.Text; namespace Terminal.Gui { diff --git a/Terminal.Gui/Views/TableView/ListTableSource.cs b/Terminal.Gui/Views/TableView/ListTableSource.cs index 265a396af..81dc22ba4 100644 --- a/Terminal.Gui/Views/TableView/ListTableSource.cs +++ b/Terminal.Gui/Views/TableView/ListTableSource.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections; using System.Data; using System.Linq; @@ -136,10 +135,8 @@ namespace Terminal.Gui { int maxLength = 0; foreach (var t in List) { int l; - if (t is ustring u) { - l = TextFormatter.GetTextWidth (u); - } else if (t is string s) { - l = s.Length; + if (t is string s) { + l = s.GetColumns (); } else { l = t.ToString ().Length; } diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index c75fe311c..6363d33ef 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections; using System.Collections.Generic; @@ -657,7 +657,7 @@ namespace Terminal.Gui { /// /// Override to provide custom multi colouring to cells. Use to - /// with . The driver will already be + /// with . The driver will already be /// in the correct place when rendering and you must render the full /// or the view will not look right. For simpler provision of color use /// For changing the content that is rendered use @@ -675,7 +675,7 @@ namespace Terminal.Gui { if (render.Length > 0) { // invert the color of the current cell for the first character Driver.SetAttribute (Driver.MakeAttribute (cellColor.Background, cellColor.Foreground)); - Driver.AddRune (render [0]); + Driver.AddRune ((Rune)render [0]); if (render.Length > 1) { Driver.SetAttribute (cellColor); @@ -695,7 +695,7 @@ namespace Terminal.Gui { var renderLines = isHeader ? style.ShowVerticalHeaderLines : style.ShowVerticalCellLines; - Rune symbol = renderLines ? CM.Glyphs.VLine : SeparatorSymbol; + Rune symbol = renderLines ? CM.Glyphs.VLine : (Rune)SeparatorSymbol; AddRune (col, row, symbol); } @@ -719,10 +719,10 @@ namespace Terminal.Gui { return new string (' ', availableHorizontalSpace); // if value is not wide enough - if (representation.Sum (c => Rune.ColumnWidth (c)) < availableHorizontalSpace) { + if (representation.EnumerateRunes ().Sum (c => c.GetColumns ()) < availableHorizontalSpace) { // pad it out with spaces to the given alignment - int toPad = availableHorizontalSpace - (representation.Sum (c => Rune.ColumnWidth (c)) + 1 /*leave 1 space for cell boundary*/); + int toPad = availableHorizontalSpace - (representation.EnumerateRunes ().Sum (c => c.GetColumns ()) + 1 /*leave 1 space for cell boundary*/); switch (colStyle?.GetAlignment (originalCellValue) ?? TextAlignment.Left) { @@ -742,7 +742,7 @@ namespace Terminal.Gui { } // value is too wide - return new string (representation.TakeWhile (c => (availableHorizontalSpace -= Rune.ColumnWidth (c)) > 0).ToArray ()); + return new string (representation.TakeWhile (c => (availableHorizontalSpace -= ((Rune)c).GetColumns ()) > 0).ToArray ()); } @@ -1594,7 +1594,7 @@ namespace Terminal.Gui { /// Invokes the event /// /// - protected virtual void OnCellToggled(CellToggledEventArgs args) + protected virtual void OnCellToggled (CellToggledEventArgs args) { CellToggled?.Invoke (this, args); } @@ -1716,7 +1716,7 @@ namespace Terminal.Gui { /// private int CalculateMaxCellWidth (int col, int rowsToRender, ColumnStyle colStyle) { - int spaceRequired = table.ColumnNames [col].Sum (c => Rune.ColumnWidth (c)); + int spaceRequired = table.ColumnNames [col].EnumerateRunes ().Sum (c => c.GetColumns ()); // if table has no rows if (RowOffset < 0) @@ -1728,7 +1728,7 @@ namespace Terminal.Gui { //expand required space if cell is bigger than the last biggest cell or header spaceRequired = Math.Max ( spaceRequired, - GetRepresentation (Table [i, col], colStyle).Sum (c => Rune.ColumnWidth (c))); + GetRepresentation (Table [i, col], colStyle).EnumerateRunes ().Sum (c => c.GetColumns ())); } // Don't require more space than the style allows diff --git a/Terminal.Gui/Views/TextChangedEventArgs.cs b/Terminal.Gui/Views/TextChangedEventArgs.cs index 942a2b267..50d118f74 100644 --- a/Terminal.Gui/Views/TextChangedEventArgs.cs +++ b/Terminal.Gui/Views/TextChangedEventArgs.cs @@ -6,7 +6,7 @@ // using System; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -18,7 +18,7 @@ namespace Terminal.Gui { /// Creates a new instance of the class /// /// - public TextChangedEventArgs (ustring oldValue) + public TextChangedEventArgs (string oldValue) { OldValue = oldValue; } @@ -26,6 +26,6 @@ namespace Terminal.Gui { /// /// The old value before the text changed /// - public ustring OldValue { get; } + public string OldValue { get; } } } diff --git a/Terminal.Gui/Views/TextChangingEventArgs.cs b/Terminal.Gui/Views/TextChangingEventArgs.cs index db0b5c8a5..09d7a01bc 100644 --- a/Terminal.Gui/Views/TextChangingEventArgs.cs +++ b/Terminal.Gui/Views/TextChangingEventArgs.cs @@ -6,7 +6,7 @@ // using System; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -16,7 +16,7 @@ namespace Terminal.Gui { /// /// The new text to be replaced. /// - public ustring NewText { get; set; } + public string NewText { get; set; } /// /// Flag which allows to cancel the new text value. /// @@ -26,7 +26,7 @@ namespace Terminal.Gui { /// Initializes a new instance of /// /// The new to be replaced. - public TextChangingEventArgs (ustring newText) + public TextChangingEventArgs (string newText) { NewText = newText; } diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 875f33872..ea7131361 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -10,9 +10,9 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; -using NStack; +using System.Text; using Terminal.Gui.Resources; -using Rune = System.Rune; + namespace Terminal.Gui { /// @@ -25,7 +25,7 @@ namespace Terminal.Gui { List text; int first, point; int selectedStart = -1; // -1 represents there is no text selection. - ustring selectedText; + string selectedText; HistoryText historyText = new HistoryText (); CultureInfo currentCulture; @@ -34,7 +34,7 @@ namespace Terminal.Gui { /// been entered yet and the does not yet have /// input focus. /// - public ustring Caption { get; set; } + public string Caption { get; set; } /// /// Gets or sets the foreground to use when @@ -64,16 +64,10 @@ namespace Terminal.Gui { /// This event is raised when the changes. /// /// - /// The passed is a containing the old value. + /// The passed is a containing the old value. /// public event EventHandler TextChanged; - /// - /// Initializes a new instance of the class using positioning. - /// - /// Initial text contents. - public TextField (string text) : this (ustring.Make (text)) { } - /// /// Initializes a new instance of the class using positioning. /// @@ -83,9 +77,9 @@ namespace Terminal.Gui { /// Initializes a new instance of the class using positioning. /// /// Initial text contents. - public TextField (ustring text) : base (text) + public TextField (string text) : base (text) { - Initialize (text, text.RuneCount + 1); + Initialize (text, text.GetRuneCount () + 1); } /// @@ -95,12 +89,12 @@ namespace Terminal.Gui { /// The y coordinate. /// The width. /// Initial text contents. - public TextField (int x, int y, int w, ustring text) : base (new Rect (x, y, w, 1)) + public TextField (int x, int y, int w, string text) : base (new Rect (x, y, w, 1)) { Initialize (text, w); } - void Initialize (ustring text, int w) + void Initialize (string text, int w) { Height = 1; @@ -108,7 +102,7 @@ namespace Terminal.Gui { text = ""; this.text = TextModel.ToRunes (text.Split ("\n") [0]); - point = text.RuneCount; + point = text.GetRuneCount (); first = point > w + 1 ? point - w + 1 : 0; CanFocus = true; Used = true; @@ -251,7 +245,7 @@ namespace Terminal.Gui { if (obj == null) return; - Text = ustring.Make (obj?.Lines [obj.CursorPosition.Y]); + Text = StringExtensions.ToString (obj?.Lines [obj.CursorPosition.Y]); CursorPosition = obj.CursorPosition.X; Adjust (); } @@ -294,7 +288,7 @@ namespace Terminal.Gui { get => base.Frame; set { if (value.Height > 1) { - base.Frame = new Rect(value.X, value.Y, value.Width, 1); + base.Frame = new Rect (value.X, value.Y, value.Width, 1); Height = 1; } else { base.Frame = value; @@ -308,13 +302,13 @@ namespace Terminal.Gui { /// /// /// - public new ustring Text { + public new string Text { get { - return ustring.Make (text); + return StringExtensions.ToString (text); } set { - var oldText = ustring.Make (text); + var oldText = StringExtensions.ToString (text); if (oldText == value) return; @@ -403,7 +397,7 @@ namespace Terminal.Gui { for (int idx = first < 0 ? 0 : first; idx < text.Count; idx++) { if (idx == point) break; - var cols = Rune.ColumnWidth (text [idx]); + var cols = text [idx].GetColumns (); TextModel.SetCol (ref col, Frame.Width - 1, cols); } var pos = point - first + Math.Min (Frame.X, 0); @@ -456,7 +450,7 @@ namespace Terminal.Gui { var roc = GetReadOnlyColor (); for (int idx = p; idx < tcount; idx++) { var rune = text [idx]; - var cols = Rune.ColumnWidth (rune); + var cols = ((Rune)rune).GetColumns (); if (idx == point && HasFocus && !Used && length == 0 && !ReadOnly) { Driver.SetAttribute (selColor); } else if (ReadOnly) { @@ -474,14 +468,14 @@ namespace Terminal.Gui { if (!TextModel.SetCol (ref col, width, cols)) { break; } - if (idx + 1 < tcount && col + Rune.ColumnWidth (text [idx + 1]) > width) { + if (idx + 1 < tcount && col + text [idx + 1].GetColumns () > width) { break; } } Driver.SetAttribute (ColorScheme.Focus); for (int i = col; i < width; i++) { - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } PositionCursor (); @@ -514,8 +508,8 @@ namespace Terminal.Gui { Move (0, 0); var render = Caption; - if (render.ConsoleWidth > Bounds.Width) { - render = render.RuneSubstring (0, Bounds.Width); + if (render.GetColumns () > Bounds.Width) { + render = render [..Bounds.Width]; } Driver.AddStr (render); @@ -574,7 +568,7 @@ namespace Terminal.Gui { void SetText (List newText) { - Text = ustring.Make (newText); + Text = StringExtensions.ToString (newText); } void SetText (IEnumerable newText) @@ -591,7 +585,7 @@ namespace Terminal.Gui { void SetClipboard (IEnumerable text) { if (!Secret) - Clipboard.Contents = ustring.Make (text.ToList ()); + Clipboard.Contents = StringExtensions.ToString (text.ToList ()); } int oldCursorPos; @@ -655,7 +649,7 @@ namespace Terminal.Gui { if (!useOldCursorPos) { oldCursorPos = point; } - var kbstr = TextModel.ToRunes (ustring.Make ((uint)kb.Key)); + var kbstr = TextModel.ToRunes (((Rune)(uint)kb.Key).ToString ()); if (Used) { point++; if (point == newText.Count + 1) { @@ -742,7 +736,7 @@ namespace Terminal.Gui { historyText.Redo (); - //if (ustring.IsNullOrEmpty (Clipboard.Contents)) + //if (string.IsNullOrEmpty (Clipboard.Contents)) // return true; //var clip = TextModel.ToRunes (Clipboard.Contents); //if (clip == null) @@ -912,7 +906,7 @@ namespace Terminal.Gui { Adjust (); } else { var newText = DeleteSelectedText (); - Text = ustring.Make (newText); + Text = StringExtensions.ToString (newText); Adjust (); } } @@ -935,7 +929,7 @@ namespace Terminal.Gui { Adjust (); } else { var newText = DeleteSelectedText (); - Text = ustring.Make (newText); + Text = StringExtensions.ToString (newText); Adjust (); } } @@ -1005,7 +999,7 @@ namespace Terminal.Gui { /// /// The selected text. /// - public ustring SelectedText { + public string SelectedText { get => Secret ? null : selectedText; private set => selectedText = value; } @@ -1059,8 +1053,8 @@ namespace Terminal.Gui { EnsureHasFocus (); int x = PositionCursor (ev); int sbw = x; - if (x == text.Count || (x > 0 && (char)text [x - 1] != ' ') - || (x > 0 && (char)text [x] == ' ')) { + if (x == text.Count || (x > 0 && (char)text [x - 1].Value != ' ') + || (x > 0 && (char)text [x].Value == ' ')) { var newPosBw = GetModel ().WordBackward (x, 0); if (newPosBw == null) return true; @@ -1135,7 +1129,7 @@ namespace Terminal.Gui { length = Math.Abs (x + direction <= text.Count ? x + direction - selectedStart : text.Count - selectedStart); SetSelectedStartSelectedLength (); if (start > -1 && length > 0) { - selectedText = length > 0 ? ustring.Make (text).ToString ().Substring ( + selectedText = length > 0 ? StringExtensions.ToString (text).ToString ().Substring ( start < 0 ? 0 : start, length > text.Count ? text.Count : length) : ""; if (first > start) { first = start; @@ -1195,22 +1189,22 @@ namespace Terminal.Gui { Clipboard.Contents = SelectedText; var newText = DeleteSelectedText (); - Text = ustring.Make (newText); + Text = StringExtensions.ToString (newText); Adjust (); } List DeleteSelectedText () { - ustring actualText = Text; + string actualText = Text; SetSelectedStartSelectedLength (); int selStart = SelectedStart > -1 ? start : point; (var _, var len) = TextModel.DisplaySize (text, 0, selStart, false); (var _, var len2) = TextModel.DisplaySize (text, selStart, selStart + length, false); - (var _, var len3) = TextModel.DisplaySize (text, selStart + length, actualText.RuneCount, false); - var newText = actualText [0, len] + - actualText [len + len2, len + len2 + len3]; + (var _, var len3) = TextModel.DisplaySize (text, selStart + length, actualText.GetRuneCount (), false); + var newText = actualText [..len] + + actualText.Substring (len + len2, len3); ClearAllSelection (); - point = selStart >= newText.RuneCount ? newText.RuneCount : selStart; + point = selStart >= newText.GetRuneCount () ? newText.GetRuneCount () : selStart; return newText.ToRuneList (); } @@ -1219,21 +1213,21 @@ namespace Terminal.Gui { /// public virtual void Paste () { - if (ReadOnly || ustring.IsNullOrEmpty (Clipboard.Contents)) { + if (ReadOnly || string.IsNullOrEmpty (Clipboard.Contents)) { return; } SetSelectedStartSelectedLength (); int selStart = start == -1 ? CursorPosition : start; - ustring actualText = Text; + string actualText = Text; (int _, int len) = TextModel.DisplaySize (text, 0, selStart, false); (var _, var len2) = TextModel.DisplaySize (text, selStart, selStart + length, false); - (var _, var len3) = TextModel.DisplaySize (text, selStart + length, actualText.RuneCount, false); - ustring cbTxt = Clipboard.Contents.Split ("\n") [0] ?? ""; - Text = actualText [0, len] + + (var _, var len3) = TextModel.DisplaySize (text, selStart + length, actualText.GetRuneCount (), false); + string cbTxt = Clipboard.Contents.Split ("\n") [0] ?? ""; + Text = actualText [..len] + cbTxt + - actualText [len + len2, len + len2 + len3]; - point = selStart + cbTxt.RuneCount; + actualText.Substring (len + len2, len3); + point = selStart + cbTxt.GetRuneCount (); ClearAllSelection (); SetNeedsDisplay (); Adjust (); @@ -1244,7 +1238,7 @@ namespace Terminal.Gui { /// /// The new text to be replaced. /// Returns the - public virtual TextChangingEventArgs OnTextChanging (ustring newText) + public virtual TextChangingEventArgs OnTextChanging (string newText) { var ev = new TextChangingEventArgs (newText); TextChanging?.Invoke (this, ev); diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index f5b9578d7..fc9d0455c 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -5,7 +5,7 @@ // José Miguel Perricone (jmperricone@hotmail.com) // -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.ComponentModel; @@ -83,12 +83,12 @@ namespace Terminal.Gui { /// /// Set the input text and get the current value. /// - ustring Text { get; set; } + string Text { get; set; } /// /// Gets the formatted string for display. /// - ustring DisplayText { get; } + string DisplayText { get; } } ////////////////////////////////////////////////////////////////////////////// @@ -117,13 +117,13 @@ namespace Terminal.Gui { /// /// Mask property /// - public ustring Mask { + public string Mask { get { return provider?.Mask; } set { var current = provider != null ? provider.ToString (false, false) : string.Empty; - provider = new MaskedTextProvider (value == ustring.Empty ? "&&&&&&" : value.ToString ()); + provider = new MaskedTextProvider (value == string.Empty ? "&&&&&&" : value.ToString ()); if (string.IsNullOrEmpty (current) == false) { provider.Set (current); } @@ -131,7 +131,7 @@ namespace Terminal.Gui { } /// - public ustring Text { + public string Text { get { return provider.ToString (); } @@ -147,7 +147,7 @@ namespace Terminal.Gui { public bool Fixed => true; /// - public ustring DisplayText => provider.ToDisplayString (); + public string DisplayText => provider.ToDisplayString (); /// public int Cursor (int pos) @@ -230,9 +230,9 @@ namespace Terminal.Gui { /// /// Regex pattern property. /// - public ustring Pattern { + public string Pattern { get { - return ustring.Make (pattern); + return StringExtensions.ToString (pattern); } set { pattern = value.ToRuneList (); @@ -242,18 +242,18 @@ namespace Terminal.Gui { } /// - public ustring Text { + public string Text { get { - return ustring.Make (text); + return StringExtensions.ToString (text); } set { - text = value != ustring.Empty ? value.ToRuneList () : null; + text = value != string.Empty ? value.ToRuneList () : null; SetupText (); } } /// - public ustring DisplayText => Text; + public string DisplayText => Text; /// public bool IsValid { @@ -272,7 +272,7 @@ namespace Terminal.Gui { bool Validate (List text) { - var match = regex.Match (ustring.Make (text).ToString ()); + var match = regex.Match (StringExtensions.ToString (text)); return match.Success; } @@ -331,9 +331,9 @@ namespace Terminal.Gui { public bool InsertAt (char ch, int pos) { var aux = text.ToList (); - aux.Insert (pos, ch); + aux.Insert (pos, (Rune)ch); if (Validate (aux) || ValidateOnInput == false) { - text.Insert (pos, ch); + text.Insert (pos, (Rune)ch); return true; } return false; @@ -353,7 +353,7 @@ namespace Terminal.Gui { /// private void CompileMask () { - regex = new Regex (ustring.Make (pattern).ToString (), RegexOptions.Compiled); + regex = new Regex (StringExtensions.ToString (pattern), RegexOptions.Compiled); } } #endregion @@ -419,7 +419,7 @@ namespace Terminal.Gui { set { provider = value; if (provider.Fixed == true) { - this.Width = provider.DisplayText == ustring.Empty ? 10 : Text.Length; + this.Width = provider.DisplayText == string.Empty ? 10 : Text.Length; } HomeKeyHandler (); SetNeedsDisplay (); @@ -446,10 +446,10 @@ namespace Terminal.Gui { /// /// Text /// - public new ustring Text { + public new string Text { get { if (provider == null) { - return ustring.Empty; + return string.Empty; } return provider.Text; @@ -519,20 +519,20 @@ namespace Terminal.Gui { // Left Margin Driver.SetAttribute (textColor); for (int i = 0; i < margin_left; i++) { - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } // Content Driver.SetAttribute (textColor); // Content for (int i = 0; i < provider.DisplayText.Length; i++) { - Driver.AddRune (provider.DisplayText [i]); + Driver.AddRune ((Rune)provider.DisplayText [i]); } // Right Margin Driver.SetAttribute (textColor); for (int i = 0; i < margin_right; i++) { - Driver.AddRune (' '); + Driver.AddRune ((Rune)' '); } } @@ -627,7 +627,7 @@ namespace Terminal.Gui { var key = new Rune ((uint)kb.KeyValue); - var inserted = provider.InsertAt ((char)key, cursorPosition); + var inserted = provider.InsertAt ((char)key.Value, cursorPosition); if (inserted) { CursorRight (); diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 413b829e9..ea55988fb 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -7,9 +7,7 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; -using NStack; using Terminal.Gui.Resources; -using Rune = System.Rune; namespace Terminal.Gui { class TextModel { @@ -36,9 +34,9 @@ namespace Terminal.Gui { return true; } - // Turns the ustring into runes, this does not split the + // Turns the string into runes, this does not split the // contents on a newline if it is present. - internal static List ToRunes (ustring str) + internal static List ToRunes (string str) { List runes = new List (); foreach (var x in str.ToRunes ()) { @@ -48,35 +46,36 @@ namespace Terminal.Gui { } // Splits a string into a List that contains a List for each line - public static List> StringToRunes (ustring content) + public static List> StringToRunes (string content) { var lines = new List> (); int start = 0, i = 0; var hasCR = false; + var runes = content.EnumerateRunes ().ToList (); // ASCII code 13 = Carriage Return. // ASCII code 10 = Line Feed. - for (; i < content.Length; i++) { - if (content [i] == 13) { + for (; i < runes.Count; i++) { + if (runes [i].Value == 13) { hasCR = true; continue; } - if (content [i] == 10) { + if (runes [i].Value == 10) { if (i - start > 0) - lines.Add (ToRunes (content [start, hasCR ? i - 1 : i])); + lines.Add (runes.GetRange (start, hasCR ? i - 1 - start : i - start)); else - lines.Add (ToRunes (ustring.Empty)); + lines.Add (ToRunes (string.Empty)); start = i + 1; hasCR = false; } } if (i - start >= 0) - lines.Add (ToRunes (content [start, null])); + lines.Add (runes.GetRange (start, i - start)); return lines; } void Append (List line) { - var str = ustring.Make (line.ToArray ()); + var str = StringExtensions.ToString (line.ToArray ()); _lines.Add (ToRunes (str)); } @@ -110,7 +109,7 @@ namespace Terminal.Gui { OnLinesLoaded (); } - public void LoadString (ustring content) + public void LoadString (string content) { _lines = StringToRunes (content); @@ -126,7 +125,7 @@ namespace Terminal.Gui { { var sb = new StringBuilder (); for (int i = 0; i < _lines.Count; i++) { - sb.Append (ustring.Make (_lines [i])); + sb.Append (StringExtensions.ToString (_lines [i])); if ((i + 1) < _lines.Count) { sb.AppendLine (); } @@ -205,7 +204,7 @@ namespace Terminal.Gui { last = last < _lines.Count ? last : _lines.Count; for (int i = first; i < last; i++) { var line = GetLine (i); - var tabSum = line.Sum (r => r == '\t' ? Math.Max (tabWidth - 1, 0) : 0); + var tabSum = line.Sum (r => r.Value == '\t' ? Math.Max (tabWidth - 1, 0) : 0); var l = line.Count + tabSum; if (l > maxLength) { maxLength = l; @@ -234,8 +233,8 @@ namespace Terminal.Gui { var pX = x + start; for (int i = start; i < t.Count; i++) { var r = t [i]; - size += Rune.ColumnWidth (r); - if (r == '\t') { + size += r.GetColumns (); + if (r.Value == '\t') { size += tabWidth + 1; } if (i == pX || (size > pX)) { @@ -258,9 +257,9 @@ namespace Terminal.Gui { int i = start == -1 ? 0 : start; for (; i < tcount; i++) { var rune = t [i]; - size += Rune.ColumnWidth (rune); - len += Rune.RuneLen (rune); - if (rune == '\t') { + size += rune.GetColumns (); + len += rune.GetEncodingLength (Encoding.Unicode); + if (rune.Value == '\t') { size += tabWidth + 1; len += tabWidth - 1; } @@ -273,9 +272,9 @@ namespace Terminal.Gui { bool IsWideRune (Rune r, int tWidth, out int s, out int l) { - s = Rune.ColumnWidth (r); - l = Rune.RuneLen (r); - if (r == '\t') { + s = r.GetColumns (); + l = r.GetEncodingLength (); + if (r.Value == '\t') { s += tWidth + 1; l += tWidth - 1; } @@ -298,8 +297,8 @@ namespace Terminal.Gui { for (int i = tcount; i >= 0; i--) { var rune = t [i]; - size += Rune.ColumnWidth (rune); - if (rune == '\t') { + size += rune.GetColumns (); + if (rune.Value == '\t') { size += tabWidth + 1; } if (size > width) { @@ -318,7 +317,7 @@ namespace Terminal.Gui { (Point startPointToFind, Point currentPointToFind, bool found) _toFind; - internal (Point current, bool found) FindNextText (ustring text, out bool gaveFullTurn, bool matchCase = false, bool matchWholeWord = false) + internal (Point current, bool found) FindNextText (string text, out bool gaveFullTurn, bool matchCase = false, bool matchWholeWord = false) { if (text == null || _lines.Count == 0) { gaveFullTurn = false; @@ -337,7 +336,7 @@ namespace Terminal.Gui { return foundPos; } - internal (Point current, bool found) FindPreviousText (ustring text, out bool gaveFullTurn, bool matchCase = false, bool matchWholeWord = false) + internal (Point current, bool found) FindPreviousText (string text, out bool gaveFullTurn, bool matchCase = false, bool matchWholeWord = false) { if (text == null || _lines.Count == 0) { gaveFullTurn = false; @@ -358,7 +357,7 @@ namespace Terminal.Gui { return foundPos; } - internal (Point current, bool found) ReplaceAllText (ustring text, bool matchCase = false, bool matchWholeWord = false, ustring textToReplace = null) + internal (Point current, bool found) ReplaceAllText (string text, bool matchCase = false, bool matchWholeWord = false, string textToReplace = null) { bool found = false; Point pos = Point.Empty; @@ -395,7 +394,7 @@ namespace Terminal.Gui { string GetText (List x) { - var txt = ustring.Make (x).ToString (); + var txt = StringExtensions.ToString (x); if (!matchCase) { txt = txt.ToUpper (); } @@ -405,16 +404,16 @@ namespace Terminal.Gui { return (pos, found); } - ustring ReplaceText (List source, ustring textToReplace, string matchText, int col) + string ReplaceText (List source, string textToReplace, string matchText, int col) { - var origTxt = ustring.Make (source); + var origTxt = StringExtensions.ToString (source); (int _, int len) = TextModel.DisplaySize (source, 0, col, false); - (var _, var len2) = TextModel.DisplaySize (source, col, col + matchText.Length, false); - (var _, var len3) = TextModel.DisplaySize (source, col + matchText.Length, origTxt.RuneCount, false); + (int _, int len2) = TextModel.DisplaySize (source, col, col + matchText.Length, false); + (int _, int len3) = TextModel.DisplaySize (source, col + matchText.Length, origTxt.GetRuneCount (), false); - return origTxt [0, len] + - textToReplace.ToString () + - origTxt [len + len2, len + len2 + len3]; + return origTxt [..len] + + textToReplace + + origTxt.Substring (len + len2, len3); } bool ApplyToFind ((Point current, bool found) foundPos) @@ -434,11 +433,11 @@ namespace Terminal.Gui { return gaveFullTurn; } - (Point current, bool found) GetFoundNextTextPoint (ustring text, int linesCount, bool matchCase, bool matchWholeWord, Point start) + (Point current, bool found) GetFoundNextTextPoint (string text, int linesCount, bool matchCase, bool matchWholeWord, Point start) { for (int i = start.Y; i < linesCount; i++) { var x = _lines [i]; - var txt = ustring.Make (x).ToString (); + var txt = StringExtensions.ToString (x); if (!matchCase) { txt = txt.ToUpper (); } @@ -459,11 +458,11 @@ namespace Terminal.Gui { return (Point.Empty, false); } - (Point current, bool found) GetFoundPreviousTextPoint (ustring text, int linesCount, bool matchCase, bool matchWholeWord, Point start) + (Point current, bool found) GetFoundPreviousTextPoint (string text, int linesCount, bool matchCase, bool matchWholeWord, Point start) { for (int i = linesCount; i >= 0; i--) { var x = _lines [i]; - var txt = ustring.Make (x).ToString (); + var txt = StringExtensions.ToString (x); if (!matchCase) { txt = txt.ToUpper (); } @@ -495,8 +494,8 @@ namespace Terminal.Gui { var start = index > 0 ? index - 1 : 0; var end = index + txt.Length; - if ((start == 0 || Rune.IsWhiteSpace (source [start])) - && (end == source.Length || Rune.IsWhiteSpace (source [end]))) { + if ((start == 0 || Rune.IsWhiteSpace ((Rune)source [start])) + && (end == source.Length || Rune.IsWhiteSpace ((Rune)source [end]))) { return true; } @@ -519,7 +518,7 @@ namespace Terminal.Gui { if (line.Count > 0) { return line [col > line.Count - 1 ? line.Count - 1 : col]; } else { - return 0; + return default; } } @@ -546,7 +545,7 @@ namespace Terminal.Gui { return true; } } - rune = 0; + rune = default; return false; } @@ -560,7 +559,7 @@ namespace Terminal.Gui { return true; } if (row == 0) { - rune = 0; + rune = default; return false; } while (row > 0) { @@ -572,7 +571,7 @@ namespace Terminal.Gui { return true; } } - rune = 0; + rune = default; return false; } @@ -758,7 +757,7 @@ namespace Terminal.Gui { List _historyTextItems = new List (); int _idxHistoryText = -1; - ustring _originalText; + string _originalText; public bool IsFromHistory { get; private set; } @@ -919,7 +918,7 @@ namespace Terminal.Gui { ChangeText?.Invoke (this, lines); } - public void Clear (ustring text) + public void Clear (string text) { _historyTextItems.Clear (); _idxHistoryText = -1; @@ -927,7 +926,7 @@ namespace Terminal.Gui { OnChangeText (null); } - public bool IsDirty (ustring text) + public bool IsDirty (string text) { return _originalText != text; } @@ -974,7 +973,7 @@ namespace Terminal.Gui { for (int i = 0; i < Model.Count; i++) { var line = Model.GetLine (i); var wrappedLines = ToListRune ( - TextFormatter.Format (ustring.Make (line), width, TextAlignment.Left, true, preserveTrailingSpaces, tabWidth)); + TextFormatter.Format (StringExtensions.ToString (line), width, TextAlignment.Left, true, preserveTrailingSpaces, tabWidth)); int sumColWidth = 0; for (int j = 0; j < wrappedLines.Count; j++) { var wrapLine = wrappedLines [j]; @@ -1031,7 +1030,7 @@ namespace Terminal.Gui { return wrappedModel; } - public List> ToListRune (List textList) + public List> ToListRune (List textList) { var runesList = new List> (); @@ -1598,7 +1597,7 @@ namespace Terminal.Gui { //historyText.Clear (Text); if (!_multiline && !IsInitialized) { - _currentColumn = Text.RuneCount; + _currentColumn = Text.GetRuneCount (); _leftColumn = _currentColumn > Frame.Width + 1 ? _currentColumn - Frame.Width + 1 : 0; } } @@ -1687,7 +1686,7 @@ namespace Terminal.Gui { /// The event is fired whenever this property is set. Note, however, /// that Text is not set by as the user types. /// - public override ustring Text { + public override string Text { get { if (_wordWrap) { return _wrapManager.Model.ToString (); @@ -1814,10 +1813,10 @@ namespace Terminal.Gui { /// /// The selected text. /// - public ustring SelectedText { + public string SelectedText { get { if (!_selecting || (_model.Count == 1 && _model.GetLine (0).Count == 0)) { - return ustring.Empty; + return string.Empty; } return GetSelectedRegion (); @@ -2002,7 +2001,7 @@ namespace Terminal.Gui { set { _historyText.Clear (Text); } - } + } /// /// Indicates whatever the text has history changes or not. @@ -2121,8 +2120,8 @@ namespace Terminal.Gui { for (int idx = _leftColumn; idx < line.Count; idx++) { if (idx >= _currentColumn) break; - var cols = Rune.ColumnWidth (line [idx]); - if (line [idx] == '\t') { + var cols = line [idx].GetColumns (); + if (line [idx].Value == '\t') { cols += TabWidth + 1; } if (!TextModel.SetCol (ref col, Frame.Width, cols)) { @@ -2147,7 +2146,7 @@ namespace Terminal.Gui { for (int row = top; row < bottom; row++) { Move (left, row); for (int col = left; col < right; col++) - AddRune (col, row, ' '); + AddRune (col, row, (Rune)' '); } } @@ -2298,15 +2297,15 @@ namespace Terminal.Gui { } // - // Returns a ustring with the text in the selected + // Returns a string with the text in the selected // region. // - ustring GetRegion (int? sRow = null, int? sCol = null, int? cRow = null, int? cCol = null, TextModel model = null) + string GetRegion (int? sRow = null, int? sCol = null, int? cRow = null, int? cCol = null, TextModel model = null) { long start, end; GetEncodedRegionBounds (out start, out end, sRow, sCol, cRow, cCol); if (start == end) { - return ustring.Empty; + return string.Empty; } int startRow = (int)(start >> 32); var maxrow = ((int)(end >> 32)); @@ -2317,14 +2316,14 @@ namespace Terminal.Gui { if (startRow == maxrow) return StringFromRunes (line.GetRange (startCol, endCol - startCol)); - ustring res = StringFromRunes (line.GetRange (startCol, line.Count - startCol)); + string res = StringFromRunes (line.GetRange (startCol, line.Count - startCol)); for (int row = startRow + 1; row < maxrow; row++) { - res = res + ustring.Make (Environment.NewLine) + StringFromRunes (model == null + res = res + Environment.NewLine + StringFromRunes (model == null ? this._model.GetLine (row) : model.GetLine (row)); } line = model == null ? this._model.GetLine (maxrow) : model.GetLine (maxrow); - res = res + ustring.Make (Environment.NewLine) + StringFromRunes (line.GetRange (0, endCol)); + res = res + Environment.NewLine + StringFromRunes (line.GetRange (0, endCol)); return res; } @@ -2419,8 +2418,8 @@ namespace Terminal.Gui { /// The text to replace. /// trueIf is replacing.falseotherwise. /// trueIf the text was found.falseotherwise. - public bool FindNextText (ustring textToFind, out bool gaveFullTurn, bool matchCase = false, - bool matchWholeWord = false, ustring textToReplace = null, bool replace = false) + public bool FindNextText (string textToFind, out bool gaveFullTurn, bool matchCase = false, + bool matchWholeWord = false, string textToReplace = null, bool replace = false) { if (_model.Count == 0) { gaveFullTurn = false; @@ -2444,8 +2443,8 @@ namespace Terminal.Gui { /// The text to replace. /// trueIf the text was found.falseotherwise. /// trueIf the text was found.falseotherwise. - public bool FindPreviousText (ustring textToFind, out bool gaveFullTurn, bool matchCase = false, - bool matchWholeWord = false, ustring textToReplace = null, bool replace = false) + public bool FindPreviousText (string textToFind, out bool gaveFullTurn, bool matchCase = false, + bool matchWholeWord = false, string textToReplace = null, bool replace = false) { if (_model.Count == 0) { gaveFullTurn = false; @@ -2475,8 +2474,8 @@ namespace Terminal.Gui { /// The match whole word setting. /// The text to replace. /// trueIf the text was found.falseotherwise. - public bool ReplaceAllText (ustring textToFind, bool matchCase = false, bool matchWholeWord = false, - ustring textToReplace = null) + public bool ReplaceAllText (string textToFind, bool matchCase = false, bool matchWholeWord = false, + string textToReplace = null) { if (_isReadOnly || _model.Count == 0) { return false; @@ -2489,25 +2488,25 @@ namespace Terminal.Gui { return SetFoundText (textToFind, foundPos, textToReplace, false, true); } - bool SetFoundText (ustring text, (Point current, bool found) foundPos, - ustring textToReplace = null, bool replace = false, bool replaceAll = false) + bool SetFoundText (string text, (Point current, bool found) foundPos, + string textToReplace = null, bool replace = false, bool replaceAll = false) { if (foundPos.found) { StartSelecting (); _selectionStartColumn = foundPos.current.X; _selectionStartRow = foundPos.current.Y; if (!replaceAll) { - _currentColumn = _selectionStartColumn + text.RuneCount; + _currentColumn = _selectionStartColumn + text.GetRuneCount (); } else { - _currentColumn = _selectionStartColumn + textToReplace.RuneCount; + _currentColumn = _selectionStartColumn + textToReplace.GetRuneCount (); } _currentRow = foundPos.current.Y; if (!_isReadOnly && replace) { Adjust (); ClearSelectedRegion (); - InsertText (textToReplace); + InsertAllText (textToReplace); StartSelecting (); - _selectionStartColumn = _currentColumn - textToReplace.RuneCount; + _selectionStartColumn = _currentColumn - textToReplace.GetRuneCount (); } else { UpdateWrapModel (); SetNeedsDisplay (); @@ -2591,7 +2590,7 @@ namespace Terminal.Gui { UnwrappedCursorPosition?.Invoke (this, new PointEventArgs (new Point ((int)col, (int)row))); } - ustring GetSelectedRegion () + string GetSelectedRegion () { var cRow = _currentRow; var cCol = _currentColumn; @@ -2625,8 +2624,8 @@ namespace Terminal.Gui { Move (0, row); for (int idxCol = _leftColumn; idxCol < lineRuneCount; idxCol++) { - var rune = idxCol >= lineRuneCount ? ' ' : line [idxCol]; - var cols = Rune.ColumnWidth (rune); + var rune = idxCol >= lineRuneCount ? (Rune)' ' : line [idxCol]; + var cols = rune.GetColumns (); if (idxCol < line.Count && _selecting && PointInSelection (idxCol, idxRow)) { SetSelectionColor (line, idxCol); } else if (idxCol == _currentColumn && idxRow == _currentRow && !_selecting && !Used @@ -2638,23 +2637,23 @@ namespace Terminal.Gui { SetNormalColor (line, idxCol); } - if (rune == '\t') { + if (rune.Value == '\t') { cols += TabWidth + 1; if (col + cols > right) { cols = right - col; } for (int i = 0; i < cols; i++) { if (col + i < right) { - AddRune (col + i, row, ' '); + AddRune (col + i, row, (Rune)' '); } } } else { - AddRune (col, row, rune); + AddRune (col, row, (Rune)rune); } if (!TextModel.SetCol (ref col, contentArea.Right, cols)) { break; } - if (idxCol + 1 < lineRuneCount && col + Rune.ColumnWidth (line [idxCol + 1]) > right) { + if (idxCol + 1 < lineRuneCount && col + line [idxCol + 1].GetColumns () > right) { break; } } @@ -2711,14 +2710,14 @@ namespace Terminal.Gui { set { base.CanFocus = value; } } - void SetClipboard (ustring text) + void SetClipboard (string text) { if (text != null) { Clipboard.Contents = text; } } - void AppendClipboard (ustring text) + void AppendClipboard (string text) { Clipboard.Contents += text; } @@ -2770,20 +2769,20 @@ namespace Terminal.Gui { } } - ustring StringFromRunes (List runes) + string StringFromRunes (List runes) { if (runes == null) throw new ArgumentNullException (nameof (runes)); int size = 0; foreach (var rune in runes) { - size += Utf8.RuneLen (rune); + size += rune.GetEncodingLength (); } var encoded = new byte [size]; int offset = 0; foreach (var rune in runes) { - offset += Utf8.EncodeRune (rune, encoded, offset); + offset += rune.Encode (encoded, offset); } - return ustring.Make (encoded); + return StringExtensions.ToString (encoded); } /// @@ -2794,9 +2793,9 @@ namespace Terminal.Gui { /// public List GetCurrentLine () => _model.GetLine (_currentRow); - void InsertText (ustring text) + void InsertAllText (string text) { - if (ustring.IsNullOrEmpty (text)) { + if (string.IsNullOrEmpty (text)) { return; } @@ -3349,7 +3348,7 @@ namespace Terminal.Gui { SetWrapModel (); var currentLine = GetCurrentLine (); - if (currentLine.Count > 0 && currentLine [_currentColumn - 1] == '\t') { + if (currentLine.Count > 0 && currentLine [_currentColumn - 1].Value == '\t') { _historyText.Add (new List> () { new List (currentLine) }, CursorPosition); @@ -3587,7 +3586,7 @@ namespace Terminal.Gui { _model.RemoveLine (_currentRow); if (_model.Count > 0 || _lastWasKill) { - var val = ustring.Make (Environment.NewLine); + var val = Environment.NewLine; if (_lastWasKill) { AppendClipboard (val); } else { @@ -3613,7 +3612,7 @@ namespace Terminal.Gui { } else { var restCount = _currentColumn; var rest = currentLine.GetRange (0, restCount); - var val = ustring.Empty; + var val = string.Empty; val += StringFromRunes (rest); if (_lastWasKill) { AppendClipboard (val); @@ -3669,7 +3668,7 @@ namespace Terminal.Gui { HistoryText.LineStatus.Removed); } if (_model.Count > 0 || _lastWasKill) { - var val = ustring.Make (Environment.NewLine); + var val = Environment.NewLine; if (_lastWasKill) { AppendClipboard (val); } else { @@ -3683,7 +3682,7 @@ namespace Terminal.Gui { } else { var restCount = currentLine.Count - _currentColumn; var rest = currentLine.GetRange (_currentColumn, restCount); - var val = ustring.Empty; + var val = string.Empty; val += StringFromRunes (rest); if (_lastWasKill) { AppendClipboard (val); @@ -3915,14 +3914,14 @@ namespace Terminal.Gui { _currentColumn = 0; } else { if (Used) { - Insert ((uint)kb.Key); + Insert ((Rune)(uint)kb.Key); _currentColumn++; if (_currentColumn >= _leftColumn + Frame.Width) { _leftColumn++; SetNeedsDisplay (); } } else { - Insert ((uint)kb.Key); + Insert ((Rune)(uint)kb.Key); _currentColumn++; } } @@ -4122,7 +4121,7 @@ namespace Terminal.Gui { _copyWithoutSelection = false; } else { var currentLine = GetCurrentLine (); - SetClipboard (ustring.Make (currentLine)); + SetClipboard (StringExtensions.ToString (currentLine)); _copyWithoutSelection = true; } UpdateWrapModel (); @@ -4182,7 +4181,7 @@ namespace Terminal.Gui { ClearRegion (); } _copyWithoutSelection = false; - InsertText (contents); + InsertAllText (contents); if (_selecting) { _historyText.ReplaceLast (new List> () { new List (GetCurrentLine ()) }, CursorPosition, @@ -4424,8 +4423,8 @@ namespace Terminal.Gui { } ProcessMouseClick (ev, out List line); (int col, int row)? newPos; - if (_currentColumn == line.Count || (_currentColumn > 0 && (line [_currentColumn - 1] != ' ' - || line [_currentColumn] == ' '))) { + if (_currentColumn == line.Count || (_currentColumn > 0 && (line [_currentColumn - 1].Value != ' ' + || line [_currentColumn].Value == ' '))) { newPos = _model.WordBackward (_currentColumn, _currentRow); if (newPos.HasValue) { diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index c305fd799..117891cda 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; @@ -66,7 +66,7 @@ namespace Terminal.Gui { /// The that is/has been replaced. /// The new to be replaced. /// true if an event handler cancelled the Title change. - public virtual bool OnTitleChanging (ustring oldTitle, ustring newTitle) + public virtual bool OnTitleChanging (string oldTitle, string newTitle) { var args = new TitleEventArgs (oldTitle, newTitle); TitleChanging?.Invoke (this, args); @@ -84,7 +84,7 @@ namespace Terminal.Gui { /// /// The that is/has been replaced. /// The new to be replaced. - public virtual void OnTitleChanged (ustring oldTitle, ustring newTitle) + public virtual void OnTitleChanged (string oldTitle, string newTitle) { var args = new TitleEventArgs (oldTitle, newTitle); TitleChanged?.Invoke (this, args); @@ -467,7 +467,7 @@ namespace Terminal.Gui { var title = titleToRender.GetTrimmedTitle (); for (int i = 0; i < title.Length; i++) { - AddRune (renderAt.X + i, renderAt.Y, title [i]); + AddRune (renderAt.X + i, renderAt.Y, (Rune)title [i]); } } } diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index 128e5b726..062e69745 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -7,7 +7,7 @@ using System; using System.Globalization; using System.Linq; -using NStack; +using System.Text; namespace Terminal.Gui { /// @@ -174,19 +174,19 @@ namespace Terminal.Gui { newText.Add (key); if (CursorPosition < fieldLen) newText = newText.Concat (text.GetRange (CursorPosition + 1, text.Count - (CursorPosition + 1))).ToList (); - return SetText (ustring.Make (newText)); + return SetText (StringExtensions.ToString (newText)); } - bool SetText (ustring text) + bool SetText (string text) { - if (text.IsEmpty) { + if (string.IsNullOrEmpty (text)) { return false; } - ustring [] vals = text.Split (ustring.Make (sepChar)); + string [] vals = text.Split (sepChar); bool isValidTime = true; - int hour = Int32.Parse (vals [0].ToString ()); - int minute = Int32.Parse (vals [1].ToString ()); + int hour = Int32.Parse (vals [0]); + int minute = Int32.Parse (vals [1]); int second = isShort ? 0 : vals.Length > 2 ? Int32.Parse (vals [2].ToString ()) : 0; if (hour < 0) { isValidTime = false; @@ -260,7 +260,7 @@ namespace Terminal.Gui { if (ReadOnly) return true; - if (SetText (TextModel.ToRunes (ustring.Make ((uint)kb.Key)).First ())) + if (SetText (TextModel.ToRunes (((Rune)(uint)kb.Key).ToString ()).First ())) IncCursorPosition (); return true; @@ -297,7 +297,7 @@ namespace Terminal.Gui { if (ReadOnly) return; - SetText ('0'); + SetText ((Rune)'0'); DecCursorPosition (); return; } @@ -308,7 +308,7 @@ namespace Terminal.Gui { if (ReadOnly) return; - SetText ('0'); + SetText ((Rune)'0'); return; } @@ -336,7 +336,7 @@ namespace Terminal.Gui { /// The event arguments public virtual void OnTimeChanged (DateTimeEventArgs args) { - TimeChanged?.Invoke (this,args); + TimeChanged?.Invoke (this, args); } } } \ No newline at end of file diff --git a/Terminal.Gui/Views/TreeView/Branch.cs b/Terminal.Gui/Views/TreeView/Branch.cs index 27964067a..795e06268 100644 --- a/Terminal.Gui/Views/TreeView/Branch.cs +++ b/Terminal.Gui/Views/TreeView/Branch.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; namespace Terminal.Gui { class Branch where T : class { @@ -73,8 +74,8 @@ namespace Terminal.Gui { public virtual int GetWidth (ConsoleDriver driver) { return - GetLinePrefix (driver).Sum (Rune.ColumnWidth) + - Rune.ColumnWidth (GetExpandableSymbol (driver)) + + GetLinePrefix (driver).Sum (r => r.GetColumns ()) + + GetExpandableSymbol (driver).GetColumns () + (tree.AspectGetter (Model) ?? "").Length; } @@ -111,7 +112,7 @@ namespace Terminal.Gui { toSkip--; } else { driver.AddRune (r); - availableWidth -= Rune.ColumnWidth (r); + availableWidth -= r.GetColumns (); } } @@ -140,7 +141,7 @@ namespace Terminal.Gui { toSkip--; } else { driver.AddRune (expansion); - availableWidth -= Rune.ColumnWidth (expansion); + availableWidth -= expansion.GetColumns (); } // horizontal scrolling has already skipped the prefix but now must also skip some of the line body @@ -153,9 +154,9 @@ namespace Terminal.Gui { } // If body of line is too long - if (lineBody.Sum (l => Rune.ColumnWidth (l)) > availableWidth) { + if (lineBody.EnumerateRunes ().Sum (l => l.GetColumns ()) > availableWidth) { // remaining space is zero and truncate the line - lineBody = new string (lineBody.TakeWhile (c => (availableWidth -= Rune.ColumnWidth (c)) >= 0).ToArray ()); + lineBody = new string (lineBody.TakeWhile (c => (availableWidth -= ((Rune)c).GetColumns ()) >= 0).ToArray ()); availableWidth = 0; } else { @@ -246,17 +247,17 @@ namespace Terminal.Gui { /// public Rune GetExpandableSymbol (ConsoleDriver driver) { - var leafSymbol = tree.Style.ShowBranchLines ? CM.Glyphs.HLine : ' '; + var leafSymbol = tree.Style.ShowBranchLines ? CM.Glyphs.HLine : (Rune)' '; if (IsExpanded) { - return tree.Style.CollapseableSymbol ?? leafSymbol; + return tree.Style.CollapseableSymbol ?? (Rune)leafSymbol; } if (CanExpand ()) { - return tree.Style.ExpandableSymbol ?? leafSymbol; + return tree.Style.ExpandableSymbol ?? (Rune)leafSymbol; } - return leafSymbol; + return (Rune)leafSymbol; } /// @@ -402,12 +403,12 @@ namespace Terminal.Gui { } // if we could theoretically expand - if (!IsExpanded && tree.Style.ExpandableSymbol != null) { + if (!IsExpanded && tree.Style.ExpandableSymbol != default) { return x == GetLinePrefix (driver).Count (); } // if we could theoretically collapse - if (IsExpanded && tree.Style.CollapseableSymbol != null) { + if (IsExpanded && tree.Style.CollapseableSymbol != default) { return x == GetLinePrefix (driver).Count (); } diff --git a/Terminal.Gui/Views/TreeView/TreeStyle.cs b/Terminal.Gui/Views/TreeView/TreeStyle.cs index a0c2061be..dbb5d1e13 100644 --- a/Terminal.Gui/Views/TreeView/TreeStyle.cs +++ b/Terminal.Gui/Views/TreeView/TreeStyle.cs @@ -1,4 +1,5 @@ using System; +using System.Text; namespace Terminal.Gui { /// diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 3d5cbe889..d4e7f4bea 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -2,7 +2,7 @@ // by phillip.piper@gmail.com). Phillip has explicitly granted permission for his design // and code to be used in this library under the MIT license. -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -156,7 +156,7 @@ namespace Terminal.Gui { /// Error message to display when the control is not properly initialized at draw time /// (nodes added but no tree builder set). /// - public static ustring NoBuilderError = "ERROR: TreeBuilder Not Set"; + public static string NoBuilderError = "ERROR: TreeBuilder Not Set"; private Key objectActivationKey = Key.Enter; /// diff --git a/Terminal.Gui/Views/Window.cs b/Terminal.Gui/Views/Window.cs index a35badfb7..0358c12a8 100644 --- a/Terminal.Gui/Views/Window.cs +++ b/Terminal.Gui/Views/Window.cs @@ -1,7 +1,7 @@ using System; using System.Collections; using System.Text.Json.Serialization; -using NStack; +using System.Text; using Terminal.Gui; using static Terminal.Gui.ConfigurationManager; diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index 42785b00e..2acd040af 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using NStack; +using System.Text; using Terminal.Gui.Resources; namespace Terminal.Gui { @@ -21,7 +21,7 @@ namespace Terminal.Gui { /// /// /// using Terminal.Gui; - /// using NStack; + /// using System.Text; /// /// Application.Init(); /// @@ -77,7 +77,7 @@ namespace Terminal.Gui { ///// The title of the . ///// ///// The Title is only displayed when the is used as a modal pop-up (see . - //public new ustring Title { + //public new string Title { // // BUGBUG: v2 - No need for this as View now has Title w/ notifications. // get => title; // set { @@ -91,7 +91,7 @@ namespace Terminal.Gui { // } //} - //private ustring title = ustring.Empty; + //private string title = string.Empty; // The contentView works like the ContentView in FrameView. private View contentView = new View () { Data = "WizardContentView" }; @@ -101,7 +101,7 @@ namespace Terminal.Gui { /// the help pane will not be visible and the content will fill the entire WizardStep. /// /// The help text is displayed using a read-only . - public ustring HelpText { + public string HelpText { get => helpTextView.Text; set { helpTextView.Text = value; @@ -116,13 +116,13 @@ namespace Terminal.Gui { /// steps after the first step. /// /// The default text is "Back" - public ustring BackButtonText { get; set; } = ustring.Empty; + public string BackButtonText { get; set; } = string.Empty; /// /// Sets or gets the text for the next/finish button. /// /// The default text is "Next..." if the Pane is not the last pane. Otherwise it is "Finish" - public ustring NextButtonText { get; set; } = ustring.Empty; + public string NextButtonText { get; set; } = string.Empty; /// /// Initializes a new instance of the class using positioning. @@ -308,7 +308,7 @@ namespace Terminal.Gui { private void Wizard_TitleChanged (object sender, TitleEventArgs e) { - if (ustring.IsNullOrEmpty (wizardTitle)) { + if (string.IsNullOrEmpty (wizardTitle)) { wizardTitle = e.NewTitle; } } @@ -531,7 +531,7 @@ namespace Terminal.Gui { ///// ///// The Title is only displayed when the is set to false. ///// - //public new ustring Title { + //public new string Title { // get { // // The base (Dialog) Title holds the full title ("Wizard Title - Step Title") // return base.Title; @@ -541,7 +541,7 @@ namespace Terminal.Gui { // base.Title = $"{wizardTitle}{(steps.Count > 0 && currentStep != null ? " - " + currentStep.Title : string.Empty)}"; // } //} - private ustring wizardTitle = ustring.Empty; + private string wizardTitle = string.Empty; /// /// Raised when the Back button in the is clicked. The Back button is always @@ -664,14 +664,14 @@ namespace Terminal.Gui { Title = $"{wizardTitle}{(steps.Count > 0 ? " - " + CurrentStep.Title : string.Empty)}"; // Configure the Back button - backBtn.Text = CurrentStep.BackButtonText != ustring.Empty ? CurrentStep.BackButtonText : Strings.wzBack; // "_Back"; + backBtn.Text = CurrentStep.BackButtonText != string.Empty ? CurrentStep.BackButtonText : Strings.wzBack; // "_Back"; backBtn.Visible = (CurrentStep != GetFirstStep ()); // Configure the Next/Finished button if (CurrentStep == GetLastStep ()) { - nextfinishBtn.Text = CurrentStep.NextButtonText != ustring.Empty ? CurrentStep.NextButtonText : Strings.wzFinish; // "Fi_nish"; + nextfinishBtn.Text = CurrentStep.NextButtonText != string.Empty ? CurrentStep.NextButtonText : Strings.wzFinish; // "Fi_nish"; } else { - nextfinishBtn.Text = CurrentStep.NextButtonText != ustring.Empty ? CurrentStep.NextButtonText : Strings.wzNext; // "_Next..."; + nextfinishBtn.Text = CurrentStep.NextButtonText != string.Empty ? CurrentStep.NextButtonText : Strings.wzNext; // "_Next..."; } SizeStep (CurrentStep); diff --git a/UICatalog/Scenario.cs b/UICatalog/Scenario.cs index f82a76d9c..43b171a58 100644 --- a/UICatalog/Scenario.cs +++ b/UICatalog/Scenario.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index ad5128c08..b1dd7ebc2 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -85,6 +84,7 @@ namespace UICatalog.Scenarios { Height = Dim.Fill (0), AllowsMarking = false, ColorScheme = Colors.TopLevel, + SelectedItem = 0 }; _classListView.OpenSelectedItem += (s, a) => { _settingsPane.SetFocus (); @@ -119,7 +119,7 @@ namespace UICatalog.Scenarios { }; _settingsPane.Add (_computedCheckBox); - var radioItems = new ustring [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" }; + var radioItems = new string [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" }; _locationFrame = new FrameView ("Location (Pos)") { X = Pos.Left (_computedCheckBox), Y = Pos.Bottom (_computedCheckBox), @@ -138,7 +138,7 @@ namespace UICatalog.Scenarios { _xText = new TextField ($"{_xVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 }; _xText.TextChanged += (s, args) => { try { - _xVal = int.Parse (_xText.Text.ToString ()); + _xVal = int.Parse (_xText.Text); DimPosChanged (_curView); } catch { @@ -148,13 +148,13 @@ namespace UICatalog.Scenarios { _locationFrame.Add (_xRadioGroup); - radioItems = new ustring [] { "Percent(y)", "AnchorEnd(y)", "Center", "At(y)" }; + radioItems = new string [] { "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 }; _yText.TextChanged += (s,args) => { try { - _yVal = int.Parse (_yText.Text.ToString ()); + _yVal = int.Parse (_yText.Text); DimPosChanged (_curView); } catch { @@ -175,7 +175,7 @@ namespace UICatalog.Scenarios { Width = 40, }; - radioItems = new ustring [] { "Percent(width)", "Fill(width)", "Sized(width)" }; + radioItems = new string [] { "Percent(width)", "Fill(width)", "Sized(width)" }; label = new Label ("width:") { X = 0, Y = 0 }; _sizeFrame.Add (label); _wRadioGroup = new RadioGroup (radioItems) { @@ -188,11 +188,11 @@ namespace UICatalog.Scenarios { try { switch (_wRadioGroup.SelectedItem) { case 0: - _wVal = Math.Min (int.Parse (_wText.Text.ToString ()), 100); + _wVal = Math.Min (int.Parse (_wText.Text), 100); break; case 1: case 2: - _wVal = int.Parse (_wText.Text.ToString ()); + _wVal = int.Parse (_wText.Text); break; } DimPosChanged (_curView); @@ -203,7 +203,7 @@ namespace UICatalog.Scenarios { _sizeFrame.Add (_wText); _sizeFrame.Add (_wRadioGroup); - radioItems = new ustring [] { "Percent(height)", "Fill(height)", "Sized(height)" }; + radioItems = new string [] { "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 }; @@ -211,11 +211,11 @@ namespace UICatalog.Scenarios { try { switch (_hRadioGroup.SelectedItem) { case 0: - _hVal = Math.Min (int.Parse (_hText.Text.ToString ()), 100); + _hVal = Math.Min (int.Parse (_hText.Text), 100); break; case 1: case 2: - _hVal = int.Parse (_hText.Text.ToString ()); + _hVal = int.Parse (_hText.Text); break; } DimPosChanged (_curView); @@ -341,7 +341,7 @@ namespace UICatalog.Scenarios { void UpdateTitle (View view) { - _hostPane.Title = $"{view.GetType ().Name} - {view.X.ToString ()}, {view.Y.ToString ()}, {view.Width.ToString ()}, {view.Height.ToString ()}"; + _hostPane.Title = $"{view.GetType ().Name} - {view.X}, {view.Y}, {view.Width}, {view.Height}"; } List GetAllViewClassesCollection () @@ -388,7 +388,7 @@ namespace UICatalog.Scenarios { // If the view supports a Text property, set it so we have something to look at if (view.GetType ().GetProperty ("Text") != null) { try { - view.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (view, new [] { ustring.Make ("Test Text") }); + view.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (view, new [] { "Test Text" }); } catch (TargetInvocationException e) { MessageBox.ErrorQuery ("Exception", e.InnerException.Message, "Ok"); view = null; @@ -397,8 +397,8 @@ namespace UICatalog.Scenarios { // If the view supports a Title property, set it so we have something to look at if (view != null && view.GetType ().GetProperty ("Title") != null) { - if (view.GetType ().GetProperty ("Title").PropertyType == typeof (ustring)) { - view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { ustring.Make ("Test Title") }); + if (view.GetType ().GetProperty ("Title").PropertyType == typeof (string)) { + view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { "Test Title" }); } else { view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { "Test Title" }); } @@ -406,7 +406,7 @@ namespace UICatalog.Scenarios { // If the view supports a Source property, set it so we have something to look at if (view != null && view.GetType ().GetProperty ("Source") != null && view.GetType ().GetProperty ("Source").PropertyType == typeof (Terminal.Gui.IListDataSource)) { - var source = new ListWrapper (new List () { ustring.Make ("Test Text #1"), ustring.Make ("Test Text #2"), ustring.Make ("Test Text #3") }); + var source = new ListWrapper (new List () { "Test Text #1", "Test Text #2", "Test Text #3" }); view?.GetType ().GetProperty ("Source")?.GetSetMethod ()?.Invoke (view, new [] { source }); } diff --git a/UICatalog/Scenarios/Animation.cs b/UICatalog/Scenarios/Animation.cs index 1efddb16e..1a1724b2e 100644 --- a/UICatalog/Scenarios/Animation.cs +++ b/UICatalog/Scenarios/Animation.cs @@ -196,7 +196,7 @@ namespace UICatalog.Scenarios { for (int y = 0; y < lines.Length; y++) { var line = lines [y]; for (int x = 0; x < line.Length; x++) { - AddRune (x, y, line [x]); + AddRune (x, y, (Rune)line [x]); } } } diff --git a/UICatalog/Scenarios/Buttons.cs b/UICatalog/Scenarios/Buttons.cs index 313f15477..cf67752e7 100644 --- a/UICatalog/Scenarios/Buttons.cs +++ b/UICatalog/Scenarios/Buttons.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; @@ -40,7 +40,7 @@ namespace UICatalog.Scenarios { }; Win.Add (swapButton); - static void DoMessage (Button button, ustring txt) + static void DoMessage (Button button, string txt) { button.Clicked += (s,e) => { var btnText = button.Text.ToString (); @@ -178,7 +178,7 @@ namespace UICatalog.Scenarios { }; Win.Add (label); - var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) { + var radioGroup = new RadioGroup (new string [] { "Left", "Right", "Centered", "Justified" }) { X = 4, Y = Pos.Bottom (label) + 1, SelectedItem = 2, @@ -186,17 +186,17 @@ namespace UICatalog.Scenarios { Win.Add (radioGroup); // Demo changing hotkey - ustring MoveHotkey (ustring txt) + string MoveHotkey (string txt) { // Remove the '_' var runes = txt.ToRuneList (); - var i = runes.IndexOf ('_'); - ustring start = ""; + var i = runes.IndexOf ((Rune)'_'); + string start = ""; if (i > -1) { - start = ustring.Make (runes.GetRange (0, i)); + start = StringExtensions.ToString (runes.GetRange (0, i)); } - txt = start + ustring.Make (runes.GetRange (i + 1, runes.Count - (i + 1))); + txt = start + StringExtensions.ToString (runes.GetRange (i + 1, runes.Count - (i + 1))); runes = txt.ToRuneList (); @@ -207,8 +207,8 @@ namespace UICatalog.Scenarios { } // Slip in the '_' - start = ustring.Make (runes.GetRange (0, i)); - return start + ustring.Make ('_') + ustring.Make (runes.GetRange (i, runes.Count - i)); + start = StringExtensions.ToString (runes.GetRange (0, i)); + return start + '_' + StringExtensions.ToString (runes.GetRange (i, runes.Count - i)); } var mhkb = "Click to Change th_is Button's Hotkey"; @@ -223,7 +223,7 @@ namespace UICatalog.Scenarios { }; Win.Add (moveHotKeyBtn); - var muhkb = ustring.Make (" ~  s  gui.cs   master ↑10 = Сохранить"); + var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить"; var moveUnicodeHotKeyBtn = new Button (muhkb) { X = Pos.Left (absoluteFrame) + 1, Y = Pos.Bottom (radioGroup) + 1, diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index f05cd5ec3..8c5f9593a 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -2,14 +2,12 @@ //#define BASE_DRAW_CONTENT using Microsoft.VisualBasic; -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Terminal.Gui; using Terminal.Gui.Resources; -using Rune = System.Rune; namespace UICatalog.Scenarios { /// @@ -40,36 +38,16 @@ namespace UICatalog.Scenarios { Win.Add (jumpEdit); var errorLabel = new Label ("") { X = Pos.Right (jumpEdit) + 1, Y = Pos.Y (_charMap), ColorScheme = Colors.ColorSchemes ["error"] }; Win.Add (errorLabel); - jumpEdit.TextChanged += (s, e) => { - uint result = 0; - if (jumpEdit.Text.Length == 0) return; - try { - result = Convert.ToUInt32 (jumpEdit.Text.ToString (), 10); - } catch (OverflowException) { - errorLabel.Text = $"Invalid (overflow)"; - return; - } catch (FormatException) { - try { - result = Convert.ToUInt32 (jumpEdit.Text.ToString (), 16); - } catch (OverflowException) { - errorLabel.Text = $"Invalid (overflow)"; - return; - } catch (FormatException) { - errorLabel.Text = $"Invalid (can't parse)"; - return; - } - } - errorLabel.Text = $"U+{result:x4}"; - _charMap.SelectedGlyph = result; - }; - var radioItems = new (ustring radioLabel, uint start, uint end) [UnicodeRange.Ranges.Count]; + var radioItems = new (string radioLabel, uint start, uint end) [UnicodeRange.Ranges.Count]; - for (var i = 0; i < UnicodeRange.Ranges.Count; i++) { - var range = UnicodeRange.Ranges [i]; + var ranges = UnicodeRange.Ranges.OrderBy (o => o.Start).ToList (); + + for (var i = 0; i < ranges.Count; i++) { + var range = ranges [i]; radioItems [i] = CreateRadio (range.Category, range.Start, range.End); } - (ustring radioLabel, uint start, uint end) CreateRadio (ustring title, uint start, uint end) + (string radioLabel, uint start, uint end) CreateRadio (string title, uint start, uint end) { return ($"{title} (U+{start:x5}-{end:x5})", start, end); } @@ -90,6 +68,34 @@ namespace UICatalog.Scenarios { Win.Add (jumpList); + jumpEdit.TextChanged += (s, e) => { + uint result = 0; + if (jumpEdit.Text.Length == 0) return; + try { + result = Convert.ToUInt32 (jumpEdit.Text, 10); + } catch (OverflowException) { + errorLabel.Text = $"Invalid (overflow)"; + return; + } catch (FormatException) { + try { + result = Convert.ToUInt32 (jumpEdit.Text, 16); + } catch (OverflowException) { + errorLabel.Text = $"Invalid (overflow)"; + return; + } catch (FormatException) { + errorLabel.Text = $"Invalid (can't parse)"; + return; + } + } + errorLabel.Text = $"U+{result:x4}"; + var foundIndex = ranges.FindIndex (x => x.Start <= result && x.End >= result); + if (foundIndex > -1 && jumpList.SelectedItem != foundIndex) { + jumpList.SelectedItem = foundIndex; + } + // Ensure the typed glyph is elected after jumpList + _charMap.SelectedGlyph = result; + }; + //jumpList.Refresh (); _charMap.SetFocus (); @@ -247,6 +253,8 @@ namespace UICatalog.Scenarios { } } + private Point _cursorPos; + public override void OnDrawContentComplete (Rect contentArea) { Rect viewport = new Rect (ContentOffset, @@ -280,16 +288,16 @@ namespace UICatalog.Scenarios { Driver.SetAttribute (GetNormalColor ()); for (int col = 0; col < 16; col++) { uint glyph = (uint)((uint)val + col); - var rune = new Rune (glyph); - //if (rune >= 0x00D800 && rune <= 0x00DFFF) { - // if (col == 0) { - // Driver.AddStr ("Reserved for surrogate pairs."); - // } - // continue; - //} + Rune rune; + if (char.IsSurrogate ((char)glyph)) { + rune = Rune.ReplacementChar; + } else { + rune = new Rune (glyph); + } Move (firstColumnX + (col * COLUMN_WIDTH) + 1, y + 1); if (glyph == SelectedGlyph) { Driver.SetAttribute (HasFocus ? ColorScheme.HotFocus : ColorScheme.HotNormal); + _cursorPos = new Point (firstColumnX + (col * COLUMN_WIDTH) + 1, y + 1); } else { Driver.SetAttribute (GetNormalColor ()); } @@ -304,6 +312,18 @@ namespace UICatalog.Scenarios { Driver.Clip = oldClip; } + public override void PositionCursor () + { + if (_cursorPos.Y < Bounds.Height && SelectedGlyph >= -ContentOffset.Y + _cursorPos.Y - 1 + && SelectedGlyph <= (-ContentOffset.Y + _cursorPos.Y - (ShowHorizontalScrollIndicator ? 1 : 0)) * 16 - 1) { + + Application.Driver.SetCursorVisibility (CursorVisibility.Default); + Move (_cursorPos.X, _cursorPos.Y); + } else { + Application.Driver.SetCursorVisibility (CursorVisibility.Invisible); + } + } + ContextMenu _contextMenu = new ContextMenu (); void Handle_MouseClick (object sender, MouseEventEventArgs args) { diff --git a/UICatalog/Scenarios/ComputedLayout.cs b/UICatalog/Scenarios/ComputedLayout.cs index 7e5468ebf..48136db6e 100644 --- a/UICatalog/Scenarios/ComputedLayout.cs +++ b/UICatalog/Scenarios/ComputedLayout.cs @@ -1,9 +1,7 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { diff --git a/UICatalog/Scenarios/CsvEditor.cs b/UICatalog/Scenarios/CsvEditor.cs index b2a3c3cb8..37fb78c68 100644 --- a/UICatalog/Scenarios/CsvEditor.cs +++ b/UICatalog/Scenarios/CsvEditor.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Globalization; using System.IO; using System.Text.RegularExpressions; -using NStack; +using System.Text; using Terminal.Gui; using CsvHelper; using System.Collections.Generic; @@ -336,7 +336,7 @@ namespace UICatalog.Scenarios { var newColIdx = Math.Min (Math.Max (0, tableView.SelectedColumn + 1), tableView.Table.Columns); - int result = MessageBox.Query ("Column Type", "Pick a data type for the column", new ustring [] { "Date", "Integer", "Double", "Text", "Cancel" }); + int result = MessageBox.Query ("Column Type", "Pick a data type for the column", new string [] { "Date", "Integer", "Double", "Text", "Cancel" }); if (result <= -1 || result >= 4) return; diff --git a/UICatalog/Scenarios/Dialogs.cs b/UICatalog/Scenarios/Dialogs.cs index 9e5399a52..4a76b5b1e 100644 --- a/UICatalog/Scenarios/Dialogs.cs +++ b/UICatalog/Scenarios/Dialogs.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using Terminal.Gui; @@ -108,7 +108,7 @@ namespace UICatalog.Scenarios { }; frame.Add (label); - var styleRadioGroup = new RadioGroup (new ustring [] { "Center", "Justify", "Left", "Right" }) { + var styleRadioGroup = new RadioGroup (new string [] { "Center", "Justify", "Left", "Right" }) { X = Pos.Right (label) + 1, Y = Pos.Top (label), }; diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs index a671e6494..f77905391 100644 --- a/UICatalog/Scenarios/DynamicMenuBar.cs +++ b/UICatalog/Scenarios/DynamicMenuBar.cs @@ -1,11 +1,10 @@ -using NStack; +using System.Text; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Reflection; using System.Runtime.CompilerServices; -using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { @@ -20,12 +19,12 @@ namespace UICatalog.Scenarios { } public class DynamicMenuItemList { - public ustring Title { get; set; } + public string Title { get; set; } public MenuItem MenuItem { get; set; } public DynamicMenuItemList () { } - public DynamicMenuItemList (ustring title, MenuItem menuItem) + public DynamicMenuItemList (string title, MenuItem menuItem) { Title = title; MenuItem = menuItem; @@ -35,24 +34,24 @@ namespace UICatalog.Scenarios { } public class DynamicMenuItem { - public ustring title = "_New"; - public ustring help = ""; - public ustring action = ""; + public string title = "_New"; + public string help = ""; + public string action = ""; public bool isTopLevel; public bool hasSubMenu; public MenuItemCheckStyle checkStyle; - public ustring shortcut; + public string shortcut; public bool allowNullChecked; public DynamicMenuItem () { } - public DynamicMenuItem (ustring title, bool hasSubMenu = false) + public DynamicMenuItem (string title, bool hasSubMenu = false) { this.title = title; this.hasSubMenu = hasSubMenu; } - public DynamicMenuItem (ustring title, ustring help, ustring action, bool isTopLevel, bool hasSubMenu, MenuItemCheckStyle checkStyle = MenuItemCheckStyle.NoCheck, ustring shortcut = null, bool allowNullChecked = false) + public DynamicMenuItem (string title, string help, string action, bool isTopLevel, bool hasSubMenu, MenuItemCheckStyle checkStyle = MenuItemCheckStyle.NoCheck, string shortcut = null, bool allowNullChecked = false) { this.title = title; this.help = help; @@ -278,10 +277,10 @@ namespace UICatalog.Scenarios { if (_currentMenuBarItem.Parent != null) { DataContext.Parent = _currentMenuBarItem.Title; } else { - DataContext.Parent = ustring.Empty; + DataContext.Parent = string.Empty; } } else { - DataContext.Parent = ustring.Empty; + DataContext.Parent = string.Empty; } }; @@ -305,7 +304,7 @@ namespace UICatalog.Scenarios { }; _btnOk.Clicked += (s, e) => { - if (ustring.IsNullOrEmpty (_frmMenuDetails._txtTitle.Text) && _currentEditMenuBarItem != null) { + if (string.IsNullOrEmpty (_frmMenuDetails._txtTitle.Text) && _currentEditMenuBarItem != null) { MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok"); } else if (_currentEditMenuBarItem != null) { var menuItem = new DynamicMenuItem (_frmMenuDetails._txtTitle.Text, _frmMenuDetails._txtHelp.Text, @@ -483,7 +482,7 @@ namespace UICatalog.Scenarios { DataContext.Menus = new List (); _currentMenuBarItem = null; _currentSelectedMenuBar = -1; - _lblMenuBar.Text = ustring.Empty; + _lblMenuBar.Text = string.Empty; } else { _lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title; } @@ -530,7 +529,7 @@ namespace UICatalog.Scenarios { _currentMenuBarItem = menuBarItem; DataContext.Menus = new List (); SetListViewSource (_currentMenuBarItem, true); - _lblParent.Text = ustring.Empty; + _lblParent.Text = string.Empty; } void SetListViewSource (MenuItem _currentMenuBarItem, bool fill = false) @@ -644,7 +643,7 @@ namespace UICatalog.Scenarios { this.hasParent = hasParent; } - public DynamicMenuBarDetails (ustring title) : base (title) + public DynamicMenuBarDetails (string title) : base (title) { var _lblTitle = new Label ("Title:") { Y = 1 @@ -704,7 +703,7 @@ namespace UICatalog.Scenarios { }; Add (_ckbNullCheck); - var _rChkLabels = new ustring [] { "NoCheck", "Checked", "Radio" }; + var _rChkLabels = new string [] { "NoCheck", "Checked", "Radio" }; _rbChkStyle = new RadioGroup (_rChkLabels) { X = Pos.Left (_lblTitle), Y = Pos.Bottom (_ckbSubMenu) + 1, @@ -862,7 +861,7 @@ namespace UICatalog.Scenarios { IsDefault = true, }; _btnOk.Clicked += (s, e) => { - if (ustring.IsNullOrEmpty (_txtTitle.Text)) { + if (string.IsNullOrEmpty (_txtTitle.Text)) { MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok"); } else { valid = true; @@ -871,7 +870,7 @@ namespace UICatalog.Scenarios { }; var _btnCancel = new Button ("Cancel"); _btnCancel.Clicked += (s, e) => { - _txtTitle.Text = ustring.Empty; + _txtTitle.Text = string.Empty; Application.RequestStop (); }; var _dialog = new Dialog (_btnOk, _btnCancel) { Title = "Enter the menu details." }; @@ -909,7 +908,7 @@ namespace UICatalog.Scenarios { _menuItem = menuItem; _txtTitle.Text = menuItem?.Title ?? ""; _txtHelp.Text = menuItem?.Help ?? ""; - _txtAction.Text = menuItem != null && menuItem.Action != null ? GetTargetAction (menuItem.Action) : ustring.Empty; + _txtAction.Text = menuItem != null && menuItem.Action != null ? GetTargetAction (menuItem.Action) : string.Empty; _ckbIsTopLevel.Checked = IsTopLevel (menuItem); _ckbSubMenu.Checked = HasSubMenus (menuItem); _ckbNullCheck.Checked = menuItem.AllowNullChecked; @@ -931,7 +930,7 @@ namespace UICatalog.Scenarios { _txtShortcut.Text = ""; } - ustring GetTargetAction (Action action) + string GetTargetAction (Action action) { var me = action.Target; @@ -944,7 +943,7 @@ namespace UICatalog.Scenarios { v = field.GetValue (me); } } - return v == null || !(v is DynamicMenuItem item) ? ustring.Empty : item.action; + return v == null || !(v is DynamicMenuItem item) ? string.Empty : item.action; } bool IsTopLevel (MenuItem menuItem) @@ -1013,11 +1012,11 @@ namespace UICatalog.Scenarios { public class DynamicMenuItemModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - private ustring menuBar; - private ustring parent; + private string menuBar; + private string parent; private List menus; - public ustring MenuBar { + public string MenuBar { get => menuBar; set { if (value != menuBar) { @@ -1027,7 +1026,7 @@ namespace UICatalog.Scenarios { } } - public ustring Parent { + public string Parent { get => parent; set { if (value != parent) { @@ -1123,7 +1122,7 @@ namespace UICatalog.Scenarios { public object Convert (object value, object parameter = null) { var data = Encoding.ASCII.GetBytes (value.ToString ()); - return ustring.Make (data); + return StringExtensions.ToString (data); } } } diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs index c2aed4e80..ded4bea7b 100644 --- a/UICatalog/Scenarios/DynamicStatusBar.cs +++ b/UICatalog/Scenarios/DynamicStatusBar.cs @@ -1,11 +1,10 @@ -using NStack; +using System.Text; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Reflection; using System.Runtime.CompilerServices; -using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { @@ -19,12 +18,12 @@ namespace UICatalog.Scenarios { } public class DynamicStatusItemList { - public ustring Title { get; set; } + public string Title { get; set; } public StatusItem StatusItem { get; set; } public DynamicStatusItemList () { } - public DynamicStatusItemList (ustring title, StatusItem statusItem) + public DynamicStatusItemList (string title, StatusItem statusItem) { Title = title; StatusItem = statusItem; @@ -34,18 +33,18 @@ namespace UICatalog.Scenarios { } public class DynamicStatusItem { - public ustring title = "New"; - public ustring action = ""; - public ustring shortcut; + public string title = "New"; + public string action = ""; + public string shortcut; public DynamicStatusItem () { } - public DynamicStatusItem (ustring title) + public DynamicStatusItem (string title) { this.title = title; } - public DynamicStatusItem (ustring title, ustring action, ustring shortcut = null) + public DynamicStatusItem (string title, string action, string shortcut = null) { this.title = title; this.action = action; @@ -193,7 +192,7 @@ namespace UICatalog.Scenarios { }; _btnOk.Clicked += (s,e) => { - if (ustring.IsNullOrEmpty (_frmStatusBarDetails._txtTitle.Text) && _currentEditStatusItem != null) { + if (string.IsNullOrEmpty (_frmStatusBarDetails._txtTitle.Text) && _currentEditStatusItem != null) { MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok"); } else if (_currentEditStatusItem != null) { _frmStatusBarDetails._txtTitle.Text = SetTitleText ( @@ -330,7 +329,7 @@ namespace UICatalog.Scenarios { //_frmStatusBarDetails.Initialized += (s, e) => _frmStatusBarDetails.Enabled = false; } - public static ustring SetTitleText (ustring title, ustring shortcut) + public static string SetTitleText (string title, string shortcut) { var txt = title; var split = title.ToString ().Split ('~'); @@ -356,7 +355,7 @@ namespace UICatalog.Scenarios { _statusItem = statusItem; } - public DynamicStatusBarDetails (ustring title) : base (title) + public DynamicStatusBarDetails (string title) : base (title) { var _lblTitle = new Label ("Title:") { Y = 1 @@ -474,10 +473,10 @@ namespace UICatalog.Scenarios { IsDefault = true, }; _btnOk.Clicked += (s,e) => { - if (ustring.IsNullOrEmpty (_txtTitle.Text)) { + if (string.IsNullOrEmpty (_txtTitle.Text)) { MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok"); } else { - if (!ustring.IsNullOrEmpty (_txtShortcut.Text)) { + if (!string.IsNullOrEmpty (_txtShortcut.Text)) { _txtTitle.Text = DynamicStatusBarSample.SetTitleText ( _txtTitle.Text, _txtShortcut.Text); } @@ -487,7 +486,7 @@ namespace UICatalog.Scenarios { }; var _btnCancel = new Button ("Cancel"); _btnCancel.Clicked += (s,e) => { - _txtTitle.Text = ustring.Empty; + _txtTitle.Text = string.Empty; Application.RequestStop (); }; var _dialog = new Dialog (_btnOk, _btnCancel) { Title = "Enter the menu details." }; @@ -517,7 +516,7 @@ namespace UICatalog.Scenarios { } _statusItem = statusItem; _txtTitle.Text = statusItem?.Title ?? ""; - _txtAction.Text = statusItem != null && statusItem.Action != null ? GetTargetAction (statusItem.Action) : ustring.Empty; + _txtAction.Text = statusItem != null && statusItem.Action != null ? GetTargetAction (statusItem.Action) : string.Empty; _txtShortcut.Text = ShortcutHelper.GetShortcutTag (statusItem.Shortcut, StatusBar.ShortcutDelimiter) ?? ""; } @@ -528,7 +527,7 @@ namespace UICatalog.Scenarios { _txtShortcut.Text = ""; } - ustring GetTargetAction (Action action) + string GetTargetAction (Action action) { var me = action.Target; @@ -541,7 +540,7 @@ namespace UICatalog.Scenarios { v = field.GetValue (me); } } - return v == null || !(v is DynamicStatusItem item) ? ustring.Empty : item.action; + return v == null || !(v is DynamicStatusItem item) ? string.Empty : item.action; } public Action CreateAction (DynamicStatusItem item) @@ -553,10 +552,10 @@ namespace UICatalog.Scenarios { public class DynamicStatusItemModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - private ustring statusBar; + private string statusBar; private List items; - public ustring StatusBar { + public string StatusBar { get => statusBar; set { if (value != statusBar) { @@ -652,7 +651,7 @@ namespace UICatalog.Scenarios { public object Convert (object value, object parameter = null) { var data = Encoding.ASCII.GetBytes (value.ToString ()); - return ustring.Make (data); + return StringExtensions.ToString (data); } } } diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 3a4908073..106001b44 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -38,7 +38,7 @@ namespace UICatalog.Scenarios { _cultureInfos = Application.SupportedCultures; ConfigurationManager.Themes.Theme = Theme; ConfigurationManager.Apply (); - + Win = new Window () { Title = _fileName ?? "Untitled", X = 0, @@ -62,7 +62,7 @@ namespace UICatalog.Scenarios { var siCursorPosition = new StatusItem (Key.Null, "", null); - _textView.UnwrappedCursorPosition += (s,e) => { + _textView.UnwrappedCursorPosition += (s, e) => { siCursorPosition.Title = $"Ln {e.Point.Y + 1}, Col {e.Point.X + 1}"; }; @@ -131,7 +131,7 @@ namespace UICatalog.Scenarios { _scrollBar = new ScrollBarView (_textView, true); - _scrollBar.ChangedPosition += (s,e) => { + _scrollBar.ChangedPosition += (s, e) => { _textView.TopRow = _scrollBar.Position; if (_textView.TopRow != _scrollBar.Position) { _scrollBar.Position = _textView.TopRow; @@ -139,7 +139,7 @@ namespace UICatalog.Scenarios { _textView.SetNeedsDisplay (); }; - _scrollBar.OtherScrollBarView.ChangedPosition += (s,e) => { + _scrollBar.OtherScrollBarView.ChangedPosition += (s, e) => { _textView.LeftColumn = _scrollBar.OtherScrollBarView.Position; if (_textView.LeftColumn != _scrollBar.OtherScrollBarView.Position) { _scrollBar.OtherScrollBarView.Position = _textView.LeftColumn; @@ -147,7 +147,7 @@ namespace UICatalog.Scenarios { _textView.SetNeedsDisplay (); }; - _scrollBar.VisibleChanged += (s,e) => { + _scrollBar.VisibleChanged += (s, e) => { if (_scrollBar.Visible && _textView.RightOffset == 0) { _textView.RightOffset = 1; } else if (!_scrollBar.Visible && _textView.RightOffset == 1) { @@ -155,7 +155,7 @@ namespace UICatalog.Scenarios { } }; - _scrollBar.OtherScrollBarView.VisibleChanged += (s,e) => { + _scrollBar.OtherScrollBarView.VisibleChanged += (s, e) => { if (_scrollBar.OtherScrollBarView.Visible && _textView.BottomOffset == 0) { _textView.BottomOffset = 1; } else if (!_scrollBar.OtherScrollBarView.Visible && _textView.BottomOffset == 1) { @@ -163,7 +163,7 @@ namespace UICatalog.Scenarios { } }; - _textView.DrawContent += (s,e) => { + _textView.DrawContent += (s, e) => { _scrollBar.Size = _textView.Lines; _scrollBar.Position = _textView.TopRow; if (_scrollBar.OtherScrollBarView != null) { @@ -199,7 +199,7 @@ namespace UICatalog.Scenarios { } }; - Application.Top.Closed += (s,e) => Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US"); + Application.Top.Closed += (s, e) => Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US"); } private void DisposeWinDialog () @@ -222,7 +222,7 @@ namespace UICatalog.Scenarios { Win.Title = "Untitled.txt"; _fileName = null; _originalText = new System.IO.MemoryStream ().ToArray (); - _textView.Text = _originalText; + _textView.Text = Encoding.Unicode.GetString (_originalText); } private void LoadFile () @@ -231,7 +231,7 @@ namespace UICatalog.Scenarios { // FIXED: BUGBUG: #452 TextView.LoadFile keeps file open and provides no way of closing it _textView.LoadFile (_fileName); //_textView.Text = System.IO.File.ReadAllText (_fileName); - _originalText = _textView.Text.ToByteArray (); + _originalText = Encoding.Unicode.GetBytes(_textView.Text); Win.Title = _fileName; _saved = true; } @@ -345,7 +345,7 @@ namespace UICatalog.Scenarios { private bool CanCloseFile () { - if (_textView.Text == _originalText) { + if (_textView.Text == Encoding.Unicode.GetString (_originalText)) { //System.Diagnostics.Debug.Assert (!_textView.IsDirty); return true; } @@ -427,7 +427,7 @@ namespace UICatalog.Scenarios { Win.Title = title; _fileName = file; System.IO.File.WriteAllText (_fileName, _textView.Text.ToString ()); - _originalText = _textView.Text.ToByteArray (); + _originalText = Encoding.Unicode.GetBytes(_textView.Text); _saved = true; _textView.ClearHistoryChanges (); MessageBox.Query ("Save File", "File was successfully saved.", "Ok"); @@ -768,8 +768,8 @@ namespace UICatalog.Scenarios { private void SetFindText () { - _textToFind = !_textView.SelectedText.IsEmpty - ? _textView.SelectedText.ToString () + _textToFind = !string.IsNullOrEmpty(_textView.SelectedText) + ? _textView.SelectedText : string.IsNullOrEmpty (_textToFind) ? "" : _textToFind; _textToReplace = string.IsNullOrEmpty (_textToReplace) ? "" : _textToReplace; @@ -778,7 +778,7 @@ namespace UICatalog.Scenarios { private View FindTab () { var d = new View (); - d.DrawContent += (s,e) => { + d.DrawContent += (s, e) => { foreach (var v in d.Subviews) { v.SetNeedsDisplay (); } @@ -807,30 +807,30 @@ namespace UICatalog.Scenarios { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (label), Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty(txtToFind.Text), TextAlignment = TextAlignment.Centered, IsDefault = true, AutoSize = false }; - btnFindNext.Clicked += (s,e) => FindNext (); + btnFindNext.Clicked += (s, e) => FindNext (); d.Add (btnFindNext); var btnFindPrevious = new Button ("Find _Previous") { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (btnFindNext) + 1, Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty(txtToFind.Text), TextAlignment = TextAlignment.Centered, AutoSize = false }; - btnFindPrevious.Clicked += (s,e) => FindPrevious (); + btnFindPrevious.Clicked += (s, e) => FindPrevious (); d.Add (btnFindPrevious); txtToFind.TextChanged += (s, e) => { _textToFind = txtToFind.Text.ToString (); _textView.FindTextChanged (); - btnFindNext.Enabled = !txtToFind.Text.IsEmpty; - btnFindPrevious.Enabled = !txtToFind.Text.IsEmpty; + btnFindNext.Enabled = !string.IsNullOrEmpty(txtToFind.Text); + btnFindPrevious.Enabled = !string.IsNullOrEmpty(txtToFind.Text); }; var btnCancel = new Button ("Cancel") { @@ -840,7 +840,7 @@ namespace UICatalog.Scenarios { TextAlignment = TextAlignment.Centered, AutoSize = false }; - btnCancel.Clicked += (s,e) => { + btnCancel.Clicked += (s, e) => { DisposeWinDialog (); }; d.Add (btnCancel); @@ -870,7 +870,7 @@ namespace UICatalog.Scenarios { private View ReplaceTab () { var d = new View (); - d.DrawContent += (s,e) => { + d.DrawContent += (s, e) => { foreach (var v in d.Subviews) { v.SetNeedsDisplay (); } @@ -899,12 +899,12 @@ namespace UICatalog.Scenarios { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (label), Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty(txtToFind.Text), TextAlignment = TextAlignment.Centered, IsDefault = true, AutoSize = false }; - btnFindNext.Clicked += (s,e) => ReplaceNext (); + btnFindNext.Clicked += (s, e) => ReplaceNext (); d.Add (btnFindNext); label = new Label ("Replace:") { @@ -928,30 +928,30 @@ namespace UICatalog.Scenarios { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (btnFindNext) + 1, Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty(txtToFind.Text), TextAlignment = TextAlignment.Centered, AutoSize = false }; - btnFindPrevious.Clicked += (s,e) => ReplacePrevious (); + btnFindPrevious.Clicked += (s, e) => ReplacePrevious (); d.Add (btnFindPrevious); var btnReplaceAll = new Button ("Replace _All") { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (btnFindPrevious) + 1, Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty(txtToFind.Text), TextAlignment = TextAlignment.Centered, AutoSize = false }; - btnReplaceAll.Clicked += (s,e) => ReplaceAll (); + btnReplaceAll.Clicked += (s, e) => ReplaceAll (); d.Add (btnReplaceAll); txtToFind.TextChanged += (s, e) => { _textToFind = txtToFind.Text.ToString (); _textView.FindTextChanged (); - btnFindNext.Enabled = !txtToFind.Text.IsEmpty; - btnFindPrevious.Enabled = !txtToFind.Text.IsEmpty; - btnReplaceAll.Enabled = !txtToFind.Text.IsEmpty; + btnFindNext.Enabled = !string.IsNullOrEmpty(txtToFind.Text); + btnFindPrevious.Enabled = !string.IsNullOrEmpty(txtToFind.Text); + btnReplaceAll.Enabled = !string.IsNullOrEmpty(txtToFind.Text); }; var btnCancel = new Button ("Cancel") { @@ -961,7 +961,7 @@ namespace UICatalog.Scenarios { TextAlignment = TextAlignment.Centered, AutoSize = false }; - btnCancel.Clicked += (s,e) => { + btnCancel.Clicked += (s, e) => { DisposeWinDialog (); }; d.Add (btnCancel); diff --git a/UICatalog/Scenarios/FileDialogExamples.cs b/UICatalog/Scenarios/FileDialogExamples.cs index ff978715f..c62874c09 100644 --- a/UICatalog/Scenarios/FileDialogExamples.cs +++ b/UICatalog/Scenarios/FileDialogExamples.cs @@ -62,7 +62,7 @@ namespace UICatalog.Scenarios { Win.Add (new Label ("Caption") { X = x++, Y = y++ }); rgCaption = new RadioGroup { X = x, Y = y }; - rgCaption.RadioLabels = new NStack.ustring [] { "Ok", "Open", "Save" }; + rgCaption.RadioLabels = new string [] { "Ok", "Open", "Save" }; Win.Add (rgCaption); y = 0; @@ -76,7 +76,7 @@ namespace UICatalog.Scenarios { Win.Add (new Label ("OpenMode") { X = x++, Y = y++ }); rgOpenMode = new RadioGroup { X = x, Y = y }; - rgOpenMode.RadioLabels = new NStack.ustring [] { "File", "Directory", "Mixed" }; + rgOpenMode.RadioLabels = new string [] { "File", "Directory", "Mixed" }; Win.Add (rgOpenMode); y = 0; @@ -90,11 +90,11 @@ namespace UICatalog.Scenarios { Win.Add (new Label ("Icons") { X = x++, Y = y++ }); rgIcons = new RadioGroup { X = x, Y = y }; - rgIcons.RadioLabels = new NStack.ustring [] { "None", "Unicode", "Nerd*" }; + rgIcons.RadioLabels = new string [] { "None", "Unicode", "Nerd*" }; Win.Add (rgIcons); - Win.Add(new Label("* Requires installing Nerd fonts"){Y = Pos.AnchorEnd(2)}); - Win.Add(new Label(" (see: https://github.com/devblackops/Terminal-Icons)"){Y = Pos.AnchorEnd(1)}); + Win.Add (new Label ("* Requires installing Nerd fonts") { Y = Pos.AnchorEnd (2) }); + Win.Add (new Label (" (see: https://github.com/devblackops/Terminal-Icons)") { Y = Pos.AnchorEnd (1) }); y = 5; x = 24; @@ -107,7 +107,7 @@ namespace UICatalog.Scenarios { Win.Add (new Label ("Allowed") { X = x++, Y = y++ }); rgAllowedTypes = new RadioGroup { X = x, Y = y }; - rgAllowedTypes.RadioLabels = new NStack.ustring [] { "Any", "Csv (Recommended)", "Csv (Strict)" }; + rgAllowedTypes.RadioLabels = new string [] { "Any", "Csv (Recommended)", "Csv (Strict)" }; Win.Add (rgAllowedTypes); var btn = new Button ($"Run Dialog") { @@ -121,14 +121,11 @@ namespace UICatalog.Scenarios { private void SetupHandler (Button btn) { - btn.Clicked += (s,e) => { - try - { - CreateDialog(); - } - catch(Exception ex) - { - MessageBox.ErrorQuery("Error",ex.ToString(),"Ok"); + btn.Clicked += (s, e) => { + try { + CreateDialog (); + } catch (Exception ex) { + MessageBox.ErrorQuery ("Error", ex.ToString (), "Ok"); } }; @@ -136,83 +133,80 @@ namespace UICatalog.Scenarios { private void CreateDialog () { - - var fd = new FileDialog () { - OpenMode = Enum.Parse ( - rgOpenMode.RadioLabels [rgOpenMode.SelectedItem].ToString ()), - MustExist = cbMustExist.Checked ?? false, - AllowsMultipleSelection = cbAllowMultipleSelection.Checked ?? false, + + var fd = new FileDialog () { + OpenMode = Enum.Parse ( + rgOpenMode.RadioLabels [rgOpenMode.SelectedItem].ToString ()), + MustExist = cbMustExist.Checked ?? false, + AllowsMultipleSelection = cbAllowMultipleSelection.Checked ?? false, + }; + + fd.Style.OkButtonText = rgCaption.RadioLabels [rgCaption.SelectedItem].ToString (); + + // If Save style dialog then give them an overwrite prompt + if (rgCaption.SelectedItem == 2) { + fd.FilesSelected += ConfirmOverwrite; + } + + if (rgIcons.SelectedItem == 1) { + fd.Style.UseUnicodeCharacters = true; + } else if (rgIcons.SelectedItem == 2) { + fd.Style.UseNerdForIcons (); + } + + if (cbCaseSensitive.Checked ?? false) { + + fd.SearchMatcher = new CaseSensitiveSearchMatcher (); + } + + fd.Style.UseColors = cbUseColors.Checked ?? false; + + fd.Style.TreeStyle.ShowBranchLines = cbShowTreeBranchLines.Checked ?? false; + fd.Style.TableStyle.AlwaysShowHeaders = cbAlwaysTableShowHeaders.Checked ?? false; + + var dirInfoFactory = new FileSystem ().DirectoryInfo; + + if (cbDrivesOnlyInTree.Checked ?? false) { + fd.Style.TreeRootGetter = () => { + return System.Environment.GetLogicalDrives () + .Select (d => new FileDialogRootTreeNode (d, dirInfoFactory.New (d))); }; + } - fd.Style.OkButtonText = rgCaption.RadioLabels [rgCaption.SelectedItem].ToString (); + if (rgAllowedTypes.SelectedItem > 0) { + fd.AllowedTypes.Add (new AllowedType ("Data File", ".csv", ".tsv")); - // If Save style dialog then give them an overwrite prompt - if(rgCaption.SelectedItem == 2) { - fd.FilesSelected += ConfirmOverwrite; + if (rgAllowedTypes.SelectedItem == 1) { + fd.AllowedTypes.Insert (1, new AllowedTypeAny ()); } - if(rgIcons.SelectedItem == 1) - { - fd.Style.UseUnicodeCharacters = true; - } - else if(rgIcons.SelectedItem == 2) - { - fd.Style.UseNerdForIcons(); - } + } - if (cbCaseSensitive.Checked ?? false) { + Application.Run (fd); - fd.SearchMatcher = new CaseSensitiveSearchMatcher (); - } - - fd.Style.UseColors = cbUseColors.Checked ?? false; - - fd.Style.TreeStyle.ShowBranchLines = cbShowTreeBranchLines.Checked ?? false; - fd.Style.TableStyle.AlwaysShowHeaders = cbAlwaysTableShowHeaders.Checked ?? false; - - var dirInfoFactory = new FileSystem().DirectoryInfo; - - if (cbDrivesOnlyInTree.Checked ?? false) { - fd.Style.TreeRootGetter = () => { - return System.Environment.GetLogicalDrives () - .Select (d => new FileDialogRootTreeNode (d, dirInfoFactory.New(d))); - }; - } - - if (rgAllowedTypes.SelectedItem > 0) { - fd.AllowedTypes.Add (new AllowedType ("Data File", ".csv", ".tsv")); - - if (rgAllowedTypes.SelectedItem == 1) { - fd.AllowedTypes.Insert (1, new AllowedTypeAny ()); - } - - } - - Application.Run (fd); - - if (fd.Canceled) { - MessageBox.Query ( - "Canceled", - "You canceled navigation and did not pick anything", + if (fd.Canceled) { + MessageBox.Query ( + "Canceled", + "You canceled navigation and did not pick anything", + "Ok"); + } else if (cbAllowMultipleSelection.Checked ?? false) { + MessageBox.Query ( + "Chosen!", + "You chose:" + Environment.NewLine + + string.Join (Environment.NewLine, fd.MultiSelected.Select (m => m)), "Ok"); - } else if (cbAllowMultipleSelection.Checked ?? false) { - MessageBox.Query ( - "Chosen!", - "You chose:" + Environment.NewLine + - string.Join (Environment.NewLine, fd.MultiSelected.Select (m => m)), - "Ok"); - } else { - MessageBox.Query ( - "Chosen!", - "You chose:" + Environment.NewLine + fd.Path, - "Ok"); - } + } else { + MessageBox.Query ( + "Chosen!", + "You chose:" + Environment.NewLine + fd.Path, + "Ok"); + } } private void ConfirmOverwrite (object sender, FilesSelectedEventArgs e) { if (!string.IsNullOrWhiteSpace (e.Dialog.Path)) { - if(File.Exists(e.Dialog.Path)) { + if (File.Exists (e.Dialog.Path)) { int result = MessageBox.Query ("Overwrite?", "File already exists", "Yes", "No"); e.Cancel = result == 1; } diff --git a/UICatalog/Scenarios/Frames.cs b/UICatalog/Scenarios/Frames.cs index de6088f66..77a448af8 100644 --- a/UICatalog/Scenarios/Frames.cs +++ b/UICatalog/Scenarios/Frames.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Linq; using Terminal.Gui; @@ -100,7 +99,7 @@ namespace UICatalog.Scenarios { }; copyTop.Clicked += (s, e) => { Thickness = new Thickness (Thickness.Top); - if (_topEdit.Text.IsEmpty) { + if (string.IsNullOrEmpty (_topEdit.Text)) { _topEdit.Text = "0"; } _bottomEdit.Text = _leftEdit.Text = _rightEdit.Text = _topEdit.Text; @@ -181,7 +180,7 @@ namespace UICatalog.Scenarios { break; } } catch { - if (!e.NewText.IsEmpty) { + if (!string.IsNullOrEmpty(e.NewText)) { e.Cancel = true; } } @@ -194,7 +193,7 @@ namespace UICatalog.Scenarios { private FrameEditor _borderEditor; private FrameEditor _paddingEditor; - public FramesEditor (ustring title, View viewToEdit) + public FramesEditor (string title, View viewToEdit) { this._viewToEdit = viewToEdit; @@ -227,7 +226,7 @@ namespace UICatalog.Scenarios { var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast ().ToList (); var rbBorderStyle = new RadioGroup (borderStyleEnum.Select ( - e => NStack.ustring.Make (e.ToString ())).ToArray ()) { + e => e.ToString ()).ToArray ()) { X = Pos.Right (_borderEditor) - 1, Y = Pos.Top (_borderEditor), diff --git a/UICatalog/Scenarios/GraphViewExample.cs b/UICatalog/Scenarios/GraphViewExample.cs index 1341720f5..ed5d6fb20 100644 --- a/UICatalog/Scenarios/GraphViewExample.cs +++ b/UICatalog/Scenarios/GraphViewExample.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using Terminal.Gui; using Color = Terminal.Gui.Color; @@ -181,7 +182,7 @@ namespace UICatalog.Scenarios { var points2 = new ScatterSeries () { Points = randomPoints, - Fill = new GraphCellToRender ('x', red) + Fill = new GraphCellToRender ((Rune)'x', red) }; var line2 = new PathAnnotation () { @@ -297,8 +298,8 @@ namespace UICatalog.Scenarios { about.Text = "This graph shows the life expectancy at birth of a range of countries"; - var softStiple = new GraphCellToRender ('\u2591'); - var mediumStiple = new GraphCellToRender ('\u2592'); + var softStiple = new GraphCellToRender ((Rune)'\u2591'); + var mediumStiple = new GraphCellToRender ((Rune)'\u2592'); var barSeries = new BarSeries () { Bars = new List () { @@ -492,8 +493,8 @@ namespace UICatalog.Scenarios { } }; - var softStiple = new GraphCellToRender ('\u2591'); - var mediumStiple = new GraphCellToRender ('\u2592'); + var softStiple = new GraphCellToRender ((Rune)'\u2591'); + var mediumStiple = new GraphCellToRender ((Rune)'\u2592'); for (int i = 0; i < malesSeries.Bars.Count; i++) { malesSeries.Bars [i].Fill = i % 2 == 0 ? softStiple : mediumStiple; @@ -559,7 +560,7 @@ namespace UICatalog.Scenarios { graphView.GraphColor = Application.Driver.MakeAttribute (Color.White, Color.Black); - var stiple = new GraphCellToRender ('\u2593'); + var stiple = new GraphCellToRender ((Rune)'\u2593'); Random r = new Random (); var series = new DiscoBarSeries (); diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index 7f9a6a19a..a1bb15f2b 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System.Collections.Generic; using Terminal.Gui; diff --git a/UICatalog/Scenarios/LabelsAsButtons.cs b/UICatalog/Scenarios/LabelsAsButtons.cs index e55a83eb1..d5e5e21f9 100644 --- a/UICatalog/Scenarios/LabelsAsButtons.cs +++ b/UICatalog/Scenarios/LabelsAsButtons.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; @@ -29,14 +29,14 @@ namespace UICatalog.Scenarios { //TODO: Change to use Pos.AnchorEnd() Y = Pos.Bottom (Win) - 3, //IsDefault = true, - HotKeySpecifier = (System.Rune)'_', + 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 = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; swapLabel.Clicked += (s,e) => { @@ -45,7 +45,7 @@ namespace UICatalog.Scenarios { }; Win.Add (swapLabel); - static void DoMessage (Label Label, ustring txt) + static void DoMessage (Label Label, string txt) { Label.Clicked += (s,e) => { var btnText = Label.Text.ToString (); @@ -66,7 +66,7 @@ namespace UICatalog.Scenarios { ColorScheme = colorScheme.Value, X = x, Y = Pos.Y (colorLabelsLabel), - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; DoMessage (colorLabel, colorLabel.Text); @@ -79,7 +79,7 @@ namespace UICatalog.Scenarios { 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 = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }); DoMessage (Label, Label.Text); @@ -88,7 +88,7 @@ namespace UICatalog.Scenarios { Win.Add (Label = new Label ("a Newline\nin the Label") { X = 2, Y = Pos.Bottom (Label) + 1, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, TextAlignment = TextAlignment.Centered, VerticalTextAlignment = VerticalTextAlignment.Middle @@ -98,7 +98,7 @@ namespace UICatalog.Scenarios { var textChanger = new Label ("Te_xt Changer") { X = 2, Y = Pos.Bottom (Label) + 1, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; Win.Add (textChanger); @@ -107,7 +107,7 @@ namespace UICatalog.Scenarios { 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 = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }); @@ -115,7 +115,7 @@ namespace UICatalog.Scenarios { X = 2, Y = Pos.Bottom (Label) + 1, ColorScheme = Colors.Error, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; Win.Add (removeLabel); @@ -142,7 +142,7 @@ namespace UICatalog.Scenarios { Y = Pos.Center () - 1, Width = 30, ColorScheme = Colors.Error, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; moveBtn.Clicked += (s,e) => { @@ -159,7 +159,7 @@ namespace UICatalog.Scenarios { Y = Pos.Center () + 1, Width = 30, ColorScheme = Colors.Error, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, AutoSize = false }; @@ -180,7 +180,7 @@ namespace UICatalog.Scenarios { // 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 = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; moveBtnA.Clicked += (s,e) => { @@ -191,7 +191,7 @@ namespace UICatalog.Scenarios { // 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 = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, AutoSize = false }; @@ -203,12 +203,12 @@ namespace UICatalog.Scenarios { var label = new Label ("Text Alignment (changes the four Labels above): ") { X = 2, Y = Pos.Bottom (computedFrame) + 1, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; Win.Add (label); - var radioGroup = new RadioGroup (new ustring [] { "Left", "Right", "Centered", "Justified" }) { + var radioGroup = new RadioGroup (new string [] { "Left", "Right", "Centered", "Justified" }) { X = 4, Y = Pos.Bottom (label) + 1, SelectedItem = 2, @@ -216,17 +216,17 @@ namespace UICatalog.Scenarios { Win.Add (radioGroup); // Demo changing hotkey - ustring MoveHotkey (ustring txt) + string MoveHotkey (string txt) { // Remove the '_' var runes = txt.ToRuneList (); - var i = runes.IndexOf ('_'); - ustring start = ""; + var i = runes.IndexOf ((Rune)'_'); + string start = ""; if (i > -1) { - start = ustring.Make (runes.GetRange (0, i)); + start = StringExtensions.ToString (runes.GetRange (0, i)); } - txt = start + ustring.Make (runes.GetRange (i + 1, runes.Count - (i + 1))); + txt = start + StringExtensions.ToString (runes.GetRange (i + 1, runes.Count - (i + 1))); runes = txt.ToRuneList (); @@ -237,8 +237,8 @@ namespace UICatalog.Scenarios { } // Slip in the '_' - start = ustring.Make (runes.GetRange (0, i)); - return start + ustring.Make ('_') + ustring.Make (runes.GetRange (i, runes.Count - i)); + 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"; @@ -247,7 +247,7 @@ namespace UICatalog.Scenarios { Y = Pos.Bottom (radioGroup) + 1, Width = Dim.Width (computedFrame) - 2, ColorScheme = Colors.TopLevel, - HotKeySpecifier = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; moveHotKeyBtn.Clicked += (s,e) => { @@ -255,13 +255,13 @@ namespace UICatalog.Scenarios { }; Win.Add (moveHotKeyBtn); - ustring muhkb = " ~  s  gui.cs   master ↑10 = Сохранить"; + 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 = (System.Rune)'_', + HotKeySpecifier = (Rune)'_', CanFocus = true, }; moveUnicodeHotKeyBtn.Clicked += (s,e) => { diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index 9ae3da08f..1b8d9e37d 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -1,8 +1,8 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata.Ecma335; +using System.Text; using Terminal.Gui; using Attribute = Terminal.Gui.Attribute; @@ -73,7 +73,7 @@ namespace UICatalog.Scenarios { _colorPicker.ColorChanged += (s, a) => ColorChanged?.Invoke (a.Color); - _stylePicker = new RadioGroup (Enum.GetNames (typeof (LineStyle)).Select (s => ustring.Make (s)).ToArray ()) { + _stylePicker = new RadioGroup (Enum.GetNames (typeof (LineStyle)).ToArray ()) { X = 0, Y = Pos.Bottom (_colorPicker) }; diff --git a/UICatalog/Scenarios/LineViewExample.cs b/UICatalog/Scenarios/LineViewExample.cs index de29d0125..6214ebf15 100644 --- a/UICatalog/Scenarios/LineViewExample.cs +++ b/UICatalog/Scenarios/LineViewExample.cs @@ -40,7 +40,7 @@ namespace UICatalog.Scenarios { // creates a horizontal line var doubleLine = new LineView () { Y = 3, - LineRune = '\u2550' + LineRune = (Rune)'\u2550' }; Win.Add (doubleLine); @@ -62,7 +62,7 @@ namespace UICatalog.Scenarios { Y = 7, Width = 10, StartingAnchor = CM.Glyphs.LeftTee, - EndingAnchor = '>' + EndingAnchor = (Rune)'>' }; Win.Add (arrowLine); @@ -82,7 +82,7 @@ namespace UICatalog.Scenarios { var verticalArrow = new LineView (Orientation.Vertical) { X = 27, StartingAnchor = CM.Glyphs.TopTee, - EndingAnchor = 'V' + EndingAnchor = (Rune)'V' }; Win.Add (verticalArrow); diff --git a/UICatalog/Scenarios/ListViewWithSelection.cs b/UICatalog/Scenarios/ListViewWithSelection.cs index 4bacde420..623b7e4c9 100644 --- a/UICatalog/Scenarios/ListViewWithSelection.cs +++ b/UICatalog/Scenarios/ListViewWithSelection.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections; using System.Collections.Generic; @@ -202,13 +202,13 @@ namespace UICatalog.Scenarios { } // A slightly adapted method from: https://github.com/gui-cs/Terminal.Gui/blob/fc1faba7452ccbdf49028ac49f0c9f0f42bbae91/Terminal.Gui/Views/ListView.cs#L433-L461 - private void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width, int start = 0) + private void RenderUstr (ConsoleDriver driver, string ustr, int col, int line, int width, int start = 0) { int used = 0; int index = start; while (index < ustr.Length) { - (var rune, var size) = Utf8.DecodeRune (ustr, index, index - ustr.Length); - var count = Rune.ColumnWidth (rune); + (var rune, var size) = ustr.DecodeRune (index, index - ustr.Length); + var count = rune.GetColumns (); if (used + count >= width) break; driver.AddRune (rune); used += count; @@ -216,7 +216,7 @@ namespace UICatalog.Scenarios { } while (used < width) { - driver.AddRune (' '); + driver.AddRune ((Rune)' '); used++; } } diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index 49c937335..061977e99 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -3,7 +3,7 @@ using System.Linq; using System.IO; using System.Collections.Generic; using Terminal.Gui; -using NStack; +using System.Text; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "ListView & ComboBox", Description: "Demonstrates a ListView populating a ComboBox that acts as a filter.")] @@ -13,13 +13,13 @@ namespace UICatalog.Scenarios { public override void Setup () { //TODO: Duplicated code in Demo.cs Consider moving to shared assembly - var items = new List (); + var items = new List (); foreach (var dir in new [] { "/etc", @$"{Environment.GetEnvironmentVariable ("SystemRoot")}\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union(Directory.GetDirectories(dir)) .Select (Path.GetFileName) .Where (x => char.IsLetterOrDigit (x [0])) - .OrderBy (x => x).Select(x => ustring.Make(x)).ToList() ; + .OrderBy (x => x).Select(x => x).ToList() ; } } diff --git a/UICatalog/Scenarios/MessageBoxes.cs b/UICatalog/Scenarios/MessageBoxes.cs index 3db0386a2..bbe1e9c9d 100644 --- a/UICatalog/Scenarios/MessageBoxes.cs +++ b/UICatalog/Scenarios/MessageBoxes.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Text; using Terminal.Gui; @@ -135,7 +134,7 @@ namespace UICatalog.Scenarios { }; frame.Add (label); - var styleRadioGroup = new RadioGroup (new ustring [] { "_Query", "_Error" }) { + var styleRadioGroup = new RadioGroup (new string [] { "_Query", "_Error" }) { X = Pos.Right (label) + 1, Y = Pos.Top (label), }; @@ -194,7 +193,7 @@ namespace UICatalog.Scenarios { int numButtons = int.Parse (numButtonsEdit.Text.ToString ()); int defaultButton = int.Parse (defaultButtonEdit.Text.ToString ()); - var btns = new List (); + var btns = new List (); for (int i = 0; i < numButtons; i++) { //btns.Add(btnText[i % 10]); btns.Add (NumberToWords.Convert (i)); diff --git a/UICatalog/Scenarios/MultiColouredTable.cs b/UICatalog/Scenarios/MultiColouredTable.cs index 101df3d31..3db995f30 100644 --- a/UICatalog/Scenarios/MultiColouredTable.cs +++ b/UICatalog/Scenarios/MultiColouredTable.cs @@ -1,5 +1,6 @@ using System; using System.Data; +using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { @@ -61,9 +62,9 @@ namespace UICatalog.Scenarios { Normal = Application.Driver.MakeAttribute (Color.DarkGray, Color.Black) }; - tableView.Table = new DataTableSource(this.table = dt); + tableView.Table = new DataTableSource (this.table = dt); } - + private void Quit () { Application.RequestStop (); @@ -73,9 +74,9 @@ namespace UICatalog.Scenarios { bool okPressed = false; var ok = new Button ("Ok", is_default: true); - ok.Clicked += (s,e) => { okPressed = true; Application.RequestStop (); }; + ok.Clicked += (s, e) => { okPressed = true; Application.RequestStop (); }; var cancel = new Button ("Cancel"); - cancel.Clicked += (s,e) => { Application.RequestStop (); }; + cancel.Clicked += (s, e) => { Application.RequestStop (); }; var d = new Dialog (ok, cancel) { Title = title }; var lbl = new Label () { @@ -104,7 +105,7 @@ namespace UICatalog.Scenarios { if (e.Table == null) return; - var oldValue = e.Table[e.Row, e.Col].ToString (); + var oldValue = e.Table [e.Row, e.Col].ToString (); if (GetText ("Enter new value", e.Table.ColumnNames [e.Col], oldValue, out string newText)) { try { @@ -120,49 +121,49 @@ namespace UICatalog.Scenarios { class TableViewColors : TableView { protected override void RenderCell (Terminal.Gui.Attribute cellColor, string render, bool isPrimaryCell) { - int unicorns = render.IndexOf ("unicorns",StringComparison.CurrentCultureIgnoreCase); + int unicorns = render.IndexOf ("unicorns", StringComparison.CurrentCultureIgnoreCase); int rainbows = render.IndexOf ("rainbows", StringComparison.CurrentCultureIgnoreCase); - for (int i=0;i= unicorns && i <= unicorns + 8) { + if (unicorns != -1 && i >= unicorns && i <= unicorns + 8) { Driver.SetAttribute (Driver.MakeAttribute (Color.White, cellColor.Background)); } - + if (rainbows != -1 && i >= rainbows && i <= rainbows + 8) { var letterOfWord = i - rainbows; - switch(letterOfWord) { - case 0 : + switch (letterOfWord) { + case 0: Driver.SetAttribute (Driver.MakeAttribute (Color.Red, cellColor.Background)); - break; + break; case 1: Driver.SetAttribute (Driver.MakeAttribute (Color.BrightRed, cellColor.Background)); - break; + break; case 2: Driver.SetAttribute (Driver.MakeAttribute (Color.BrightYellow, cellColor.Background)); - break; + break; case 3: Driver.SetAttribute (Driver.MakeAttribute (Color.Green, cellColor.Background)); - break; + break; case 4: Driver.SetAttribute (Driver.MakeAttribute (Color.BrightGreen, cellColor.Background)); - break; + break; case 5: Driver.SetAttribute (Driver.MakeAttribute (Color.BrightBlue, cellColor.Background)); - break; + break; case 6: Driver.SetAttribute (Driver.MakeAttribute (Color.BrightCyan, cellColor.Background)); - break; + break; case 7: Driver.SetAttribute (Driver.MakeAttribute (Color.Cyan, cellColor.Background)); - break; + break; } - } - - Driver.AddRune (render [i]); + } + + Driver.AddRune ((Rune)render [i]); Driver.SetAttribute (cellColor); - } + } } } } diff --git a/UICatalog/Scenarios/Progress.cs b/UICatalog/Scenarios/Progress.cs index b33d8b0fe..7e55e09f8 100644 --- a/UICatalog/Scenarios/Progress.cs +++ b/UICatalog/Scenarios/Progress.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Threading; using Terminal.Gui; diff --git a/UICatalog/Scenarios/ProgressBarStyles.cs b/UICatalog/Scenarios/ProgressBarStyles.cs index c64c6dfdb..9ff533fa8 100644 --- a/UICatalog/Scenarios/ProgressBarStyles.cs +++ b/UICatalog/Scenarios/ProgressBarStyles.cs @@ -21,7 +21,7 @@ namespace UICatalog.Scenarios { var pbFormatEnum = Enum.GetValues (typeof (ProgressBarFormat)).Cast ().ToList (); - var rbPBFormat = new RadioGroup (pbFormatEnum.Select (e => NStack.ustring.Make (e.ToString ())).ToArray ()) { + var rbPBFormat = new RadioGroup (pbFormatEnum.Select (e => e.ToString ()).ToArray ()) { X = Pos.Center (), Y = 1 }; diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs index d844753a1..fb37d1c48 100644 --- a/UICatalog/Scenarios/Scrolling.cs +++ b/UICatalog/Scenarios/Scrolling.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { @@ -76,23 +77,23 @@ namespace UICatalog.Scenarios { case 0: var er = y.ToString ().ToCharArray (0, 1) [0]; nw += er.ToString ().Length; - Driver.AddRune (er); + Driver.AddRune ((Rune)er); if (y > 9) { er = y.ToString ().ToCharArray (1, 1) [0]; nw += er.ToString ().Length; - Driver.AddRune (er); + Driver.AddRune ((Rune)er); } - r = '.'; + r = (Rune)'.'; break; case 1: - r = 'o'; + r = (Rune)'o'; break; default: - r = 'O'; + r = (Rune)'O'; break; } Driver.AddRune (r); - nw += Rune.RuneLen (r); + nw += r.Utf8SequenceLength; } if (nw > w) w = nw; diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 609c138f9..c1f1f2120 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Text; using System.Threading.Tasks; using Terminal.Gui; using Attribute = Terminal.Gui.Attribute; diff --git a/UICatalog/Scenarios/SpinnerStyles.cs b/UICatalog/Scenarios/SpinnerStyles.cs index 5e07b9471..9ca924d2e 100644 --- a/UICatalog/Scenarios/SpinnerStyles.cs +++ b/UICatalog/Scenarios/SpinnerStyles.cs @@ -99,7 +99,7 @@ namespace UICatalog.Scenarios { }; Win.Add (customField); - var styleArray = styleDict.Select (e => NStack.ustring.Make (e.Value.Key.ToString ())).ToArray (); + var styleArray = styleDict.Select (e => e.Value.Key).ToArray (); if (styleArray.Length < 1) return; diff --git a/UICatalog/Scenarios/SyntaxHighlighting.cs b/UICatalog/Scenarios/SyntaxHighlighting.cs index c59141f26..8d607f92d 100644 --- a/UICatalog/Scenarios/SyntaxHighlighting.cs +++ b/UICatalog/Scenarios/SyntaxHighlighting.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using Terminal.Gui; using Attribute = Terminal.Gui.Attribute; @@ -150,7 +151,7 @@ namespace UICatalog.Scenarios { Driver.SetAttribute (white); } - protected override void SetNormalColor (List line, int idx) + protected override void SetNormalColor (List line, int idx) { if (IsInStringLiteral (line, idx)) { Driver.SetAttribute (magenta); @@ -162,9 +163,9 @@ namespace UICatalog.Scenarios { } } - private bool IsInStringLiteral (List line, int idx) + private bool IsInStringLiteral (List line, int idx) { - string strLine = new string (line.Select (r => (char)r).ToArray ()); + string strLine = new string (line.Select (r => (char)r.Value).ToArray ()); foreach (Match m in Regex.Matches (strLine, "'[^']*'")) { if (idx >= m.Index && idx < m.Index + m.Length) { @@ -175,7 +176,7 @@ namespace UICatalog.Scenarios { return false; } - private bool IsKeyword (List line, int idx) + private bool IsKeyword (List line, int idx) { var word = IdxToWord (line, idx); @@ -186,10 +187,10 @@ namespace UICatalog.Scenarios { return keywords.Contains (word, StringComparer.CurrentCultureIgnoreCase); } - private string IdxToWord (List line, int idx) + private string IdxToWord (List line, int idx) { var words = Regex.Split ( - new string (line.Select (r => (char)r).ToArray ()), + new string (line.Select (r => (char)r.Value).ToArray ()), "\\b"); int count = 0; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index fc4ece454..22037d970 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -5,6 +5,7 @@ using Terminal.Gui; using System.Linq; using System.Globalization; using static Terminal.Gui.TableView; +using System.Text; namespace UICatalog.Scenarios { @@ -212,7 +213,7 @@ namespace UICatalog.Scenarios { private string TrimArrows (string columnName) { - return columnName.TrimEnd ((char)CM.Glyphs.UpArrow, (char)CM.Glyphs.DownArrow); + return columnName.TrimEnd ((char)CM.Glyphs.UpArrow.Value, (char)CM.Glyphs.DownArrow.Value); } private string StripArrows (string columnName) { diff --git a/UICatalog/Scenarios/Text.cs b/UICatalog/Scenarios/Text.cs index 9e905b55a..c1f2d2f01 100644 --- a/UICatalog/Scenarios/Text.cs +++ b/UICatalog/Scenarios/Text.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.IO; using System.Linq; using System.Text; diff --git a/UICatalog/Scenarios/TextAlignments.cs b/UICatalog/Scenarios/TextAlignments.cs index 8d10bdacc..ce0cf4a86 100644 --- a/UICatalog/Scenarios/TextAlignments.cs +++ b/UICatalog/Scenarios/TextAlignments.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { diff --git a/UICatalog/Scenarios/TextAlignmentsAndDirection.cs b/UICatalog/Scenarios/TextAlignmentsAndDirection.cs index 48c58e6a6..b4800cf74 100644 --- a/UICatalog/Scenarios/TextAlignmentsAndDirection.cs +++ b/UICatalog/Scenarios/TextAlignmentsAndDirection.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { @@ -164,12 +165,12 @@ namespace UICatalog.Scenarios { var directionsEnum = Enum.GetValues (typeof (Terminal.Gui.TextDirection)).Cast ().ToList (); - var directionOptions = new RadioGroup (directionsEnum.Select (e => NStack.ustring.Make (e.ToString ())).ToArray ()) { + var directionOptions = new RadioGroup (directionsEnum.Select (e => e.ToString ()).ToArray ()) { X = Pos.Right (container) + 1, Y = Pos.Bottom (justifyCheckbox) + 1, Width = Dim.Fill (10), Height = Dim.Fill (1), - HotKeySpecifier = '\xffff' + HotKeySpecifier = (Rune)'\xffff' }; directionOptions.SelectedItemChanged += (s, ev) => { diff --git a/UICatalog/Scenarios/TextFormatterDemo.cs b/UICatalog/Scenarios/TextFormatterDemo.cs index 697a05f02..2adde7d48 100644 --- a/UICatalog/Scenarios/TextFormatterDemo.cs +++ b/UICatalog/Scenarios/TextFormatterDemo.cs @@ -1,10 +1,9 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using Terminal.Gui; -using Rune = System.Rune; + namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "TextFormatter Demo", Description: "Demos and tests the TextFormatter class.")] @@ -39,7 +38,7 @@ namespace UICatalog.Scenarios { block.AppendLine ("░ ░ ░ ░░░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ "); block.AppendLine (" ░ ░ ░ ░ ░ ░ ░ "); block.AppendLine (" ░ ░ "); - blockText.Text = ustring.Make (block.ToString ()); // .Replace(" ", "\u00A0"); // \u00A0 is 'non-breaking space + blockText.Text = block.ToString (); // .Replace(" ", "\u00A0"); // \u00A0 is 'non-breaking space Win.Add (blockText); var unicodeCheckBox = new CheckBox ("Unicode", Application.Top.HotKeySpecifier == (Rune)' ') { diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index f25c5cb71..3b85252bf 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using Terminal.Gui; namespace UICatalog.Scenarios { @@ -50,10 +51,10 @@ namespace UICatalog.Scenarios { Checked = true, CheckType = MenuItemCheckStyle.Checked }, null /*separator*/, - _miPlusMinus = new MenuItem ("_Plus Minus Symbols", "+ -", () => SetExpandableSymbols('+','-')){Checked = true, CheckType = MenuItemCheckStyle.Radio}, - _miArrowSymbols = new MenuItem ("_Arrow Symbols", "> v", () => SetExpandableSymbols('>','v')){Checked = false, CheckType = MenuItemCheckStyle.Radio}, - _miNoSymbols = new MenuItem ("_No Symbols", "", () => SetExpandableSymbols(null,null)){Checked = false, CheckType = MenuItemCheckStyle.Radio}, - _miUnicodeSymbols = new MenuItem ("_Unicode", "ஹ ﷽", () => SetExpandableSymbols('ஹ','﷽')){Checked = false, CheckType = MenuItemCheckStyle.Radio}, + _miPlusMinus = new MenuItem ("_Plus Minus Symbols", "+ -", () => SetExpandableSymbols((Rune)'+',(Rune)'-')){Checked = true, CheckType = MenuItemCheckStyle.Radio}, + _miArrowSymbols = new MenuItem ("_Arrow Symbols", "> v", () => SetExpandableSymbols((Rune)'>',(Rune)'v')){Checked = false, CheckType = MenuItemCheckStyle.Radio}, + _miNoSymbols = new MenuItem ("_No Symbols", "", () => SetExpandableSymbols(default,null)){Checked = false, CheckType = MenuItemCheckStyle.Radio}, + _miUnicodeSymbols = new MenuItem ("_Unicode", "ஹ ﷽", () => SetExpandableSymbols((Rune)'ஹ',(Rune)'﷽')){Checked = false, CheckType = MenuItemCheckStyle.Radio}, null /*separator*/, _miColoredSymbols = new MenuItem ("_Colored Symbols", "", () => ShowColoredExpandableSymbols()){Checked = false, CheckType = MenuItemCheckStyle.Checked}, _miInvertSymbols = new MenuItem ("_Invert Symbols", "", () => InvertExpandableSymbols()){Checked = false, CheckType = MenuItemCheckStyle.Checked}, @@ -253,12 +254,12 @@ namespace UICatalog.Scenarios { treeViewFiles.SetNeedsDisplay (); } - private void SetExpandableSymbols (Rune? expand, Rune? collapse) + private void SetExpandableSymbols (Rune expand, Rune? collapse) { - _miPlusMinus.Checked = expand == '+'; - _miArrowSymbols.Checked = expand == '>'; - _miNoSymbols.Checked = expand == null; - _miUnicodeSymbols.Checked = expand == 'ஹ'; + _miPlusMinus.Checked = expand.Value == '+'; + _miArrowSymbols.Checked = expand.Value == '>'; + _miNoSymbols.Checked = expand.Value == default; + _miUnicodeSymbols.Checked = expand.Value == 'ஹ'; treeViewFiles.Style.ExpandableSymbol = expand; treeViewFiles.Style.CollapseableSymbol = collapse; diff --git a/UICatalog/Scenarios/Unicode.cs b/UICatalog/Scenarios/Unicode.cs index a89d7dc81..866679a61 100644 --- a/UICatalog/Scenarios/Unicode.cs +++ b/UICatalog/Scenarios/Unicode.cs @@ -1,5 +1,4 @@ -using NStack; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text; using Terminal.Gui; @@ -50,7 +49,7 @@ namespace UICatalog.Scenarios { label = new Label ("Label (CanFocus):") { X = Pos.X (label), Y = Pos.Bottom (label) + 1 }; Win.Add (label); - testlabel = new Label ("Стоял &он, дум великих полн") { X = 20, Y = Pos.Y (label), Width = Dim.Percent (50), CanFocus = true, HotKeySpecifier = new System.Rune ('&') }; + testlabel = new Label ("Стоял &он, дум великих полн") { X = 20, Y = Pos.Y (label), Width = Dim.Percent (50), CanFocus = true, HotKeySpecifier = new Rune ('&') }; Win.Add (testlabel); label = new Label ("Button:") { X = Pos.X (label), Y = Pos.Bottom (label) + 1 }; @@ -99,7 +98,7 @@ namespace UICatalog.Scenarios { label = new Label ("RadioGroup:") { X = Pos.X (label), Y = Pos.Bottom (listView) + 1 }; Win.Add (label); - var radioGroup = new RadioGroup (new ustring [] { "item #1", gitString, "Со_хранить", "𝔽𝕆𝕆𝔹𝔸ℝ" }, selected: 0) { + var radioGroup = new RadioGroup (new string [] { "item #1", gitString, "Со_хранить", "𝔽𝕆𝕆𝔹𝔸ℝ" }, selected: 0) { X = 20, Y = Pos.Y (label), Width = Dim.Percent (60), diff --git a/UICatalog/Scenarios/WizardAsView.cs b/UICatalog/Scenarios/WizardAsView.cs index 5f6468f9a..b7a0b6d0b 100644 --- a/UICatalog/Scenarios/WizardAsView.cs +++ b/UICatalog/Scenarios/WizardAsView.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/UICatalog/Scenarios/Wizards.cs b/UICatalog/Scenarios/Wizards.cs index f837a6988..8f7df9bb9 100644 --- a/UICatalog/Scenarios/Wizards.cs +++ b/UICatalog/Scenarios/Wizards.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -109,7 +108,7 @@ namespace UICatalog.Scenarios { return; } - actionLabel.Text = ustring.Empty; + actionLabel.Text = string.Empty; var wizard = new Wizard () { Title = titleEdit.Text, @@ -178,7 +177,7 @@ namespace UICatalog.Scenarios { frame.Add (new TextField ("This is a TextField inside of the frame.")); secondStep.Add (frame); wizard.StepChanging += (s, args) => { - if (args.OldStep == secondStep && firstNameField.Text.IsEmpty) { + if (args.OldStep == secondStep && string.IsNullOrEmpty(firstNameField.Text)) { args.Cancel = true; var btn = MessageBox.ErrorQuery ("Second Step", "You must enter a First Name to continue", "Ok"); } @@ -229,7 +228,7 @@ namespace UICatalog.Scenarios { }; hideHelpBtn.Clicked += (s, e) => { if (fourthStep.HelpText.Length > 0) { - fourthStep.HelpText = ustring.Empty; + fourthStep.HelpText = string.Empty; } else { fourthStep.HelpText = help; } diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 9ffa9454d..c8bdb2579 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -1,6 +1,5 @@ global using CM = Terminal.Gui.ConfigurationManager; -using NStack; using System; using System.Collections.Generic; using System.Diagnostics; @@ -646,7 +645,7 @@ namespace UICatalog { }; } - Enum GetDiagnosticsEnumValue (ustring title) + Enum GetDiagnosticsEnumValue (string title) { return title!.ToString () switch { FRAME_RULER => ConsoleDriver.DiagnosticFlags.FrameRuler, diff --git a/UnitTests/Configuration/ConfigurationMangerTests.cs b/UnitTests/Configuration/ConfigurationMangerTests.cs index e95433e22..3a2689d02 100644 --- a/UnitTests/Configuration/ConfigurationMangerTests.cs +++ b/UnitTests/Configuration/ConfigurationMangerTests.cs @@ -224,7 +224,6 @@ namespace Terminal.Gui.ConfigurationTests { ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = Key.Q; ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = Key.F; ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = Key.B; - ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue = true; ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true; ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue = true; ConfigurationManager.Settings.Apply (); @@ -233,7 +232,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q, Application.QuitKey); Assert.Equal (Key.F, Application.AlternateForwardKey); Assert.Equal (Key.B, Application.AlternateBackwardKey); - Assert.True (Application.UseSystemConsole); Assert.True (Application.IsMouseDisabled); Assert.True (Application.EnableConsoleScrolling); @@ -246,7 +244,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); Assert.Equal (Key.PageDown | Key.CtrlMask, Application.AlternateForwardKey); Assert.Equal (Key.PageUp | Key.CtrlMask, Application.AlternateBackwardKey); - Assert.False (Application.UseSystemConsole); Assert.False (Application.IsMouseDisabled); Assert.False (Application.EnableConsoleScrolling); @@ -254,7 +251,6 @@ namespace Terminal.Gui.ConfigurationTests { ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = Key.Q; ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = Key.F; ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = Key.B; - ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue = true; ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true; ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue = true; ConfigurationManager.Settings.Apply (); @@ -271,7 +267,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); Assert.Equal (Key.PageDown | Key.CtrlMask, Application.AlternateForwardKey); Assert.Equal (Key.PageUp | Key.CtrlMask, Application.AlternateBackwardKey); - Assert.False (Application.UseSystemConsole); Assert.False (Application.IsMouseDisabled); Assert.False (Application.EnableConsoleScrolling); @@ -289,8 +284,8 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Empty (ConfigurationManager.Settings.Where (cp => cp.Value.PropertyInfo.GetCustomAttribute (typeof (SerializableConfigurationProperty)) == null)); // Application is a static class - PropertyInfo pi = typeof (Application).GetProperty ("UseSystemConsole"); - Assert.Equal (pi, ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyInfo); + PropertyInfo pi = typeof (Application).GetProperty ("QuitKey"); + Assert.Equal (pi, ConfigurationManager.Settings ["Application.QuitKey"].PropertyInfo); // FrameView is not a static class and DefaultBorderStyle is Scope.Scheme pi = typeof (FrameView).GetProperty ("DefaultBorderStyle"); @@ -752,7 +747,6 @@ namespace Terminal.Gui.ConfigurationTests { ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = Key.Q; ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = Key.F; ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = Key.B; - ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue = true; ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true; ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue = true; @@ -765,7 +759,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q | Key.CtrlMask, ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue); Assert.Equal (Key.PageDown | Key.CtrlMask, ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue); Assert.Equal (Key.PageUp | Key.CtrlMask, ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue); - Assert.False ((bool)ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue); Assert.False ((bool)ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue); Assert.False ((bool)ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue); } @@ -791,7 +784,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q, Application.QuitKey); Assert.Equal (Key.F, Application.AlternateForwardKey); Assert.Equal (Key.B, Application.AlternateBackwardKey); - Assert.True (Application.UseSystemConsole); Assert.True (Application.IsMouseDisabled); Assert.True (Application.EnableConsoleScrolling); } @@ -800,7 +792,6 @@ namespace Terminal.Gui.ConfigurationTests { ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = Key.Q; ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = Key.F; ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = Key.B; - ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue = true; ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true; ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue = true; diff --git a/UnitTests/Configuration/SettingsScopeTests.cs b/UnitTests/Configuration/SettingsScopeTests.cs index 06777daf1..2bf36b167 100644 --- a/UnitTests/Configuration/SettingsScopeTests.cs +++ b/UnitTests/Configuration/SettingsScopeTests.cs @@ -24,7 +24,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.True (ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue is Key); Assert.True (ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue is Key); Assert.True (ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue is Key); - Assert.True (ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue is bool); Assert.True (ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue is bool); Assert.True (ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue is bool); @@ -43,7 +42,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q | Key.CtrlMask, (Key)ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue); Assert.Equal (Key.PageDown | Key.CtrlMask, (Key)ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue); Assert.Equal (Key.PageUp | Key.CtrlMask, (Key)ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue); - Assert.False ((bool)ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue); Assert.False ((bool)ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue); Assert.False ((bool)ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue); @@ -51,7 +49,6 @@ namespace Terminal.Gui.ConfigurationTests { ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = Key.Q; ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = Key.F; ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = Key.B; - ConfigurationManager.Settings ["Application.UseSystemConsole"].PropertyValue = true; ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true; ConfigurationManager.Settings ["Application.EnableConsoleScrolling"].PropertyValue = true; @@ -61,7 +58,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.Q, Application.QuitKey); Assert.Equal (Key.F, Application.AlternateForwardKey); Assert.Equal (Key.B, Application.AlternateBackwardKey); - Assert.True (Application.UseSystemConsole); Assert.True (Application.IsMouseDisabled); Assert.True (Application.EnableConsoleScrolling); } @@ -76,7 +72,6 @@ namespace Terminal.Gui.ConfigurationTests { ///Don't set Quitkey updatedSettings["Application.AlternateForwardKey"].PropertyValue = Key.F; updatedSettings["Application.AlternateBackwardKey"].PropertyValue = Key.B; - updatedSettings["Application.UseSystemConsole"].PropertyValue = true; updatedSettings["Application.IsMouseDisabled"].PropertyValue = true; updatedSettings["Application.EnableConsoleScrolling"].PropertyValue = true; @@ -84,7 +79,6 @@ namespace Terminal.Gui.ConfigurationTests { Assert.Equal (Key.End, ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue); Assert.Equal (Key.F, updatedSettings ["Application.AlternateForwardKey"].PropertyValue); Assert.Equal (Key.B, updatedSettings ["Application.AlternateBackwardKey"].PropertyValue); - Assert.True ((bool)updatedSettings ["Application.UseSystemConsole"].PropertyValue); Assert.True ((bool)updatedSettings ["Application.IsMouseDisabled"].PropertyValue); Assert.True ((bool)updatedSettings ["Application.EnableConsoleScrolling"].PropertyValue); } diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index b3595a4ea..d73ff36c4 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -7,7 +7,7 @@ using Terminal.Gui; using Xunit; using System.Globalization; using Xunit.Abstractions; -using NStack; +using System.Text; using static Terminal.Gui.Application; namespace Terminal.Gui.DialogTests { @@ -560,7 +560,7 @@ namespace Terminal.Gui.DialogTests { // Note extra spaces to make dialog even wider // 123456 123456 var buttonRow = $"{CM.Glyphs.VLine} {btn1} {btn2} {btn3} {btn4} {CM.Glyphs.VLine}"; - var width = ustring.Make (buttonRow).ConsoleWidth; + var width = buttonRow.GetColumns (); d.SetBufferSize (width, 3); // Default - Center @@ -570,21 +570,21 @@ namespace Terminal.Gui.DialogTests { // Justify buttonRow = $"{CM.Glyphs.VLine}{btn1} {btn2} {btn3} {btn4}{CM.Glyphs.VLine}"; - Assert.Equal (width, ustring.Make (buttonRow).ConsoleWidth); + Assert.Equal (width, buttonRow.GetColumns ()); (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Justify, new Button (btn1Text), new Button (btn2Text), new Button (btn3Text), new Button (btn4Text)); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); // Right buttonRow = $"{CM.Glyphs.VLine} {btn1} {btn2} {btn3} {btn4}{CM.Glyphs.VLine}"; - Assert.Equal (width, ustring.Make (buttonRow).ConsoleWidth); + Assert.Equal (width, buttonRow.GetColumns ()); (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Right, new Button (btn1Text), new Button (btn2Text), new Button (btn3Text), new Button (btn4Text)); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); // Left buttonRow = $"{CM.Glyphs.VLine}{btn1} {btn2} {btn3} {btn4} {CM.Glyphs.VLine}"; - Assert.Equal (width, ustring.Make (buttonRow).ConsoleWidth); + Assert.Equal (width, buttonRow.GetColumns ()); (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Left, new Button (btn1Text), new Button (btn2Text), new Button (btn3Text), new Button (btn4Text)); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); diff --git a/UnitTests/Dialogs/WizardTests.cs b/UnitTests/Dialogs/WizardTests.cs index 0c133c7ba..21f95edf1 100644 --- a/UnitTests/Dialogs/WizardTests.cs +++ b/UnitTests/Dialogs/WizardTests.cs @@ -7,7 +7,7 @@ using Terminal.Gui; using Xunit; using System.Globalization; using Xunit.Abstractions; -using NStack; +using System.Text; using static Terminal.Gui.Application; namespace Terminal.Gui.DialogTests { @@ -42,7 +42,7 @@ namespace Terminal.Gui.DialogTests { public void WizardStep_Set_Title_Fires_TitleChanging () { var r = new Window (); - Assert.Equal (ustring.Empty, r.Title); + Assert.Equal (string.Empty, r.Title); string expectedAfter = string.Empty; string expectedDuring = string.Empty; @@ -70,7 +70,7 @@ namespace Terminal.Gui.DialogTests { public void WizardStep_Set_Title_Fires_TitleChanged () { var r = new Window (); - Assert.Equal (ustring.Empty, r.Title); + Assert.Equal (string.Empty, r.Title); string expected = string.Empty; r.TitleChanged += (s,args) => { diff --git a/UnitTests/Drawing/LineCanvasTests.cs b/UnitTests/Drawing/LineCanvasTests.cs index cff1953d9..b8cba0802 100644 --- a/UnitTests/Drawing/LineCanvasTests.cs +++ b/UnitTests/Drawing/LineCanvasTests.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Text; using Xunit; @@ -168,7 +167,7 @@ namespace Terminal.Gui.DrawingTests { TestHelpers.AssertEqual (output, @" ╔╡╞╗ ║ ║", - ustring.Make ($"{Environment.NewLine}{lc}")); + $"{Environment.NewLine}{lc}"); } [Fact, SetupFakeDriver] diff --git a/UnitTests/Drawing/RulerTests.cs b/UnitTests/Drawing/RulerTests.cs index cea34d079..c00f4eeee 100644 --- a/UnitTests/Drawing/RulerTests.cs +++ b/UnitTests/Drawing/RulerTests.cs @@ -1,5 +1,5 @@ using Terminal.Gui; -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Xml.Linq; diff --git a/UnitTests/Drawing/StraightLineTests.cs b/UnitTests/Drawing/StraightLineTests.cs index 49e2c1d6d..c67c30fbc 100644 --- a/UnitTests/Drawing/StraightLineTests.cs +++ b/UnitTests/Drawing/StraightLineTests.cs @@ -1,5 +1,4 @@ -using NStack; -using System; +using System; using System.Collections.Generic; using System.Text; using Xunit; diff --git a/UnitTests/Drawing/ThicknessTests.cs b/UnitTests/Drawing/ThicknessTests.cs index 0230d43f1..6848c953d 100644 --- a/UnitTests/Drawing/ThicknessTests.cs +++ b/UnitTests/Drawing/ThicknessTests.cs @@ -1,5 +1,5 @@ using Terminal.Gui; -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Xml.Linq; @@ -403,7 +403,7 @@ namespace Terminal.Gui.DrawingTests { var t = new Thickness (0, 0, 0, 0); var r = new Rect (5, 5, 40, 15); ConsoleDriver.Diagnostics |= ConsoleDriver.DiagnosticFlags.FramePadding; - Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), ' '); + Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), (Rune)' '); t.Draw (r, "Test"); ConsoleDriver.Diagnostics = ConsoleDriver.DiagnosticFlags.Off; TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -412,7 +412,7 @@ namespace Terminal.Gui.DrawingTests { t = new Thickness (1, 1, 1, 1); r = new Rect (5, 5, 40, 15); ConsoleDriver.Diagnostics |= ConsoleDriver.DiagnosticFlags.FramePadding; - Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), ' '); + Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), (Rune)' '); t.Draw (r, "Test"); ConsoleDriver.Diagnostics = ConsoleDriver.DiagnosticFlags.Off; TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -435,7 +435,7 @@ namespace Terminal.Gui.DrawingTests { t = new Thickness (1, 2, 3, 4); r = new Rect (5, 5, 40, 15); ConsoleDriver.Diagnostics |= ConsoleDriver.DiagnosticFlags.FramePadding; - Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), ' '); + Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), (Rune)' '); t.Draw (r, "Test"); ConsoleDriver.Diagnostics = ConsoleDriver.DiagnosticFlags.Off; TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -458,7 +458,7 @@ namespace Terminal.Gui.DrawingTests { t = new Thickness (-1, 1, 1, 1); r = new Rect (5, 5, 40, 15); ConsoleDriver.Diagnostics |= ConsoleDriver.DiagnosticFlags.FramePadding; - Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), ' '); + Application.Driver.FillRect (new Rect (0, 0, Application.Driver.Cols, Application.Driver.Rows), (Rune)' '); t.Draw (r, "Test"); ConsoleDriver.Diagnostics = ConsoleDriver.DiagnosticFlags.Off; TestHelpers.AssertDriverContentsWithFrameAre (@" diff --git a/UnitTests/TestHelpers.cs b/UnitTests/TestHelpers.cs index 67d39c84b..896f3a4a1 100644 --- a/UnitTests/TestHelpers.cs +++ b/UnitTests/TestHelpers.cs @@ -8,10 +8,9 @@ using Terminal.Gui; using System.Text.RegularExpressions; using System.Reflection; using System.Diagnostics; -using Rune = System.Rune; + using Attribute = Terminal.Gui.Attribute; using Microsoft.VisualStudio.TestPlatform.Utilities; -using NStack; using Xunit.Sdk; // This class enables test functions annotated with the [AutoInitShutdown] attribute to @@ -121,13 +120,13 @@ class TestHelpers { for (int r = 0; r < driver.Rows; r++) { for (int c = 0; c < driver.Cols; c++) { - Rune rune = contents [r, c, 0]; - if (Rune.DecodeSurrogatePair (rune, out char [] spair)) { + Rune rune = (Rune)contents [r, c, 0]; + if (rune.DecodeSurrogatePair (out char [] spair)) { sb.Append (spair); } else { - sb.Append ((char)rune); + sb.Append ((char)rune.Value); } - if (Rune.ColumnWidth (rune) > 1) { + if (rune.GetColumns () > 1) { c++; } } @@ -181,15 +180,15 @@ class TestHelpers { var runes = new List (); for (int c = 0; c < driver.Cols; c++) { var rune = (Rune)contents [r, c, 0]; - if (rune != ' ') { + if (rune != (Rune)' ') { if (x == -1) { x = c; y = r; for (int i = 0; i < c; i++) { - runes.InsertRange (i, new List () { ' ' }); + runes.InsertRange (i, new List () { (Rune)' ' }); } } - if (Rune.ColumnWidth (rune) > 1) { + if (rune.GetColumns () > 1) { c++; } if (c + 1 > w) { @@ -218,7 +217,7 @@ class TestHelpers { List row = lines [r]; for (int c = row.Count - 1; c >= 0; c--) { var rune = row [c]; - if (rune != ' ' || (row.Sum (x => Rune.ColumnWidth (x)) == w)) { + if (rune != (Rune)' ' || (row.Sum (x => x.GetColumns ()) == w)) { break; } row.RemoveAt (c); @@ -227,7 +226,7 @@ class TestHelpers { // Convert Rune list to string for (int r = 0; r < lines.Count; r++) { - var line = NStack.ustring.Make (lines [r]).ToString (); + var line = Terminal.Gui.StringExtensions.ToString (lines [r]).ToString (); if (r == lines.Count - 1) { sb.Append (line); } else { @@ -371,28 +370,6 @@ class TestHelpers { Assert.Equal (expectedLook, actualLook); } - - /// - /// Verifies two strings are equivalent. If the assert fails, output will be generated to standard - /// output showing the expected and actual look. - /// - /// Uses on . - /// A string containing the expected look. Newlines should be specified as "\r\n" as - /// they will be converted to to make tests platform independent. - /// - public static void AssertEqual (ITestOutputHelper output, string expectedLook, ustring actualLook) - { - // Convert newlines to platform-specific newlines - expectedLook = ReplaceNewLinesToPlatformSpecific (expectedLook); - - // If test is about to fail show user what things looked like - if (!string.Equals (expectedLook, actualLook.ToString ())) { - output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); - output?.WriteLine ("But Was:" + Environment.NewLine + actualLook.ToString ()); - } - - Assert.Equal (expectedLook, actualLook); - } #pragma warning restore xUnit1013 // Public method should be marked as test private static string ReplaceNewLinesToPlatformSpecific (string toReplace) diff --git a/UnitTests/Text/RuneTests.cs b/UnitTests/Text/RuneTests.cs new file mode 100644 index 000000000..c4df9a413 --- /dev/null +++ b/UnitTests/Text/RuneTests.cs @@ -0,0 +1,714 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using Xunit; + +namespace Terminal.Gui.TextTests; + +public class RuneTests { + + // IsCombiningMark tests + [Theory] + [InlineData (0x0338, true)] // Combining Long Solidus Overlay (U+0338) (e.g. ≠) + [InlineData (0x0300, true)] // Combining Grave Accent + [InlineData (0x0301, true)] // Combining acute accent (é) + [InlineData (0x0302, true)] // Combining Circumflex Accent + [InlineData (0x0328, true)] // Combining ogonek (a small hook or comma shape) U+0328 + [InlineData (0x00E9, false)] // Latin Small Letter E with Acute, Unicode U+00E9 é + [InlineData (0x0061, false)] // Latin Small Letter A is U+0061. + public void TestIsCombiningMark (int codepoint, bool expected) + { + var rune = new Rune (codepoint); + Assert.Equal (expected, rune.IsCombiningMark ()); + } + + [Theory] + [InlineData (0x0000001F, 0x241F)] + [InlineData (0x0000007F, 0x247F)] + [InlineData (0x0000009F, 0x249F)] + [InlineData (0x0001001A, 0x1001A)] + public void MakePrintable_Converts_Control_Chars_To_Proper_Unicode (int code, int expected) + { + var actual = ((Rune)code).MakePrintable (); + Assert.Equal (expected, actual.Value); + } + + [Theory] + [InlineData (0x20)] + [InlineData (0x7E)] + [InlineData (0xA0)] + [InlineData (0x010020)] + public void MakePrintable_Does_Not_Convert_Ansi_Chars_To_Unicode (int code) + { + var actual = ((Rune)code).MakePrintable (); + Assert.Equal (code, actual.Value); + } + + [Theory] + [InlineData (0x0338)] // Combining Long Solidus Overlay (U+0338) (e.g. ≠) + [InlineData (0x0300)] // Combining Grave Accent + [InlineData (0x0301)] // Combining acute accent (é) + [InlineData (0x0302)] // Combining Circumflex Accent + [InlineData (0x0061)] // Combining ogonek (a small hook or comma shape) + public void MakePrintable_Combining_Character_Is_Not_Printable (int code) + { + var rune = new Rune (code); + var actual = rune.MakePrintable (); + Assert.Equal (code, actual.Value); + } + + [Theory] + [InlineData ('a', "a", 1, 1, 1)] + [InlineData ('b', "b", 1, 1, 1)] + [InlineData (123, "{", 1, 1, 1)] // { Left Curly Bracket + [InlineData ('\u1150', "ᅐ", 2, 1, 3)] // ᅐ Hangul Choseong Ceongchieumcieuc + [InlineData ('\u1161', "ᅡ", 0, 1, 3)] // ᅡ Hangul Jungseong A - Unicode Hangul Jamo for join with column width equal to 0 alone. + [InlineData (31, "\u001f", -1, 1, 1)] // non printable character - Information Separator One + [InlineData (127, "\u007f", -1, 1, 1)] // non printable character - Delete + [InlineData ('\u20D0', "⃐", 0, 1, 3)] // ◌⃐ Combining Left Harpoon Above + [InlineData ('\u25a0', "■", 1, 1, 3)] // ■ Black Square + [InlineData ('\u25a1', "□", 1, 1, 3)] // □ White Square + [InlineData ('\uf61e', "", 1, 1, 3)] // Private Use Area + [InlineData ('\u2103', "℃", 1, 1, 3)] // ℃ Degree Celsius + [InlineData ('\u1100', "ᄀ", 2, 1, 3)] // ᄀ Hangul Choseong Kiyeok + [InlineData ('\u2501', "━", 1, 1, 3)] // ━ Box Drawings Heavy Horizontal + [InlineData ('\u2615', "☕", 2, 1, 3)] // ☕ Hot Beverage + [InlineData ('\u231a', "⌚", 2, 1, 3)] // ⌚ Watch + [InlineData ('\u231b', "⌛", 2, 1, 3)] // ⌛ Hourglass + [InlineData ('\u231c', "⌜", 1, 1, 3)] // ⌜ Top Left Corner + [InlineData ('\u1dc0', "᷀", 0, 1, 3)] // ◌᷀ Combining Dotted Grave Accent + public void GetColumns_With_Single_Code (int code, string str, int runeLength, int stringLength, int utf8Length) + { + var rune = new Rune (code); + Assert.Equal (str, rune.ToString ()); + Assert.Equal (runeLength, rune.GetColumns ()); + Assert.Equal (stringLength, rune.ToString ().Length); + Assert.Equal (utf8Length, rune.Utf8SequenceLength); + Assert.True (Rune.IsValid (rune.Value)); + } + + [Theory] + [InlineData (new byte [] { 0xf0, 0x9f, 0xa8, 0x81 }, "🨁", 1, 2)] // Neutral Chess Queen + [InlineData (new byte [] { 0xf3, 0xa0, 0xbf, 0xa1 }, "󠿡", 1, 2)] // Undefined Character + [InlineData (new byte [] { 0xf0, 0x9f, 0x8d, 0x95 }, "🍕", 2, 2)] // 🍕 Slice of Pizza + [InlineData (new byte [] { 0xf0, 0x9f, 0xa4, 0x96 }, "🤖", 2, 2)] // 🤖 Robot Face + [InlineData (new byte [] { 0xf0, 0x90, 0x90, 0xa1 }, "𐐡", 1, 2)] // 𐐡 Deseret Capital Letter Er + [InlineData (new byte [] { 0xf0, 0x9f, 0x8c, 0xb9 }, "🌹", 2, 2)] // 🌹 Rose + public void GetColumns_Utf8_Encode (byte [] code, string str, int runeLength, int stringLength) + { + var operationStatus = Rune.DecodeFromUtf8 (code, out Rune rune, out int bytesConsumed); + Assert.Equal (OperationStatus.Done, operationStatus); + Assert.Equal (str, rune.ToString ()); + Assert.Equal (runeLength, rune.GetColumns ()); + Assert.Equal (stringLength, rune.ToString ().Length); + Assert.Equal (bytesConsumed, rune.Utf8SequenceLength); + Assert.True (Rune.IsValid (rune.Value)); + } + + [Theory] + [InlineData (new char [] { '\ud83e', '\ude01' }, "🨁", 1, 2, 4)] // Neutral Chess Queen + [InlineData (new char [] { '\udb43', '\udfe1' }, "󠿡", 1, 2, 4)] // Undefined Character + [InlineData (new char [] { '\ud83c', '\udf55' }, "🍕", 2, 2, 4)] // 🍕 Slice of Pizza + [InlineData (new char [] { '\ud83e', '\udd16' }, "🤖", 2, 2, 4)] // 🤖 Robot Face + [InlineData (new char [] { '\ud83e', '\udde0' }, "🧠", 2, 2, 4)] // 🧠 Brain + [InlineData (new char [] { '\ud801', '\udc21' }, "𐐡", 1, 2, 4)] // 𐐡 Deseret Capital Letter Er + [InlineData (new char [] { '\ud83c', '\udf39' }, "🌹", 2, 2, 4)] // 🌹 Rose + public void GetColumns_Utf16_Encode (char [] code, string str, int runeLength, int stringLength, int utf8Length) + { + var rune = new Rune (code [0], code [1]); + Assert.Equal (str, rune.ToString ()); + Assert.Equal (runeLength, rune.GetColumns ()); + Assert.Equal (stringLength, rune.ToString ().Length); + Assert.Equal (utf8Length, rune.Utf8SequenceLength); + Assert.True (Rune.IsValid (rune.Value)); + } + + [Theory] + [InlineData ("\U0001fa01", "🨁", 1, 2)] // Neutral Chess Queen + [InlineData ("\U000e0fe1", "󠿡", 1, 2)] // Undefined Character + [InlineData ("\U0001F355", "🍕", 2, 2)] // 🍕 Slice of Pizza + [InlineData ("\U0001F916", "🤖", 2, 2)] // 🤖 Robot Face + [InlineData ("\U0001f9e0", "🧠", 2, 2)] // 🧠 Brain + [InlineData ("\U00010421", "𐐡", 1, 2)] // 𐐡 Deseret Capital Letter Er + [InlineData ("\U0001f339", "🌹", 2, 2)] // 🌹 Rose + public void GetColumns_Utf32_Encode (string code, string str, int runeLength, int stringLength) + { + var operationStatus = Rune.DecodeFromUtf16 (code, out Rune rune, out int charsConsumed); + Assert.Equal (OperationStatus.Done, operationStatus); + Assert.Equal (str, rune.ToString ()); + Assert.Equal (runeLength, rune.GetColumns ()); + Assert.Equal (stringLength, rune.ToString ().Length); + Assert.Equal (charsConsumed, rune.Utf16SequenceLength); + Assert.True (Rune.IsValid (rune.Value)); + + // with DecodeRune + (var nrune, var size) = code.DecodeRune (); + Assert.Equal (str, nrune.ToString ()); + Assert.Equal (runeLength, nrune.GetColumns ()); + Assert.Equal (stringLength, nrune.ToString ().Length); + Assert.Equal (size, nrune.Utf8SequenceLength); + for (int x = 0; x < code.Length - 1; x++) { + Assert.Equal (nrune.Value, char.ConvertToUtf32 (code [x], code [x + 1])); + Assert.True (RuneExtensions.EncodeSurrogatePair (code [x], code [x + 1], out Rune result)); + Assert.Equal (rune, result); + } + Assert.True (Rune.IsValid (nrune.Value)); + } + + [Theory] + [InlineData ("\u2615\ufe0f", "☕️", 2, 2, 2)] // \ufe0f forces it to be rendered as a colorful image as compared to a monochrome text variant. + [InlineData ("\u1107\u1165\u11b8", "법", 3, 2, 1)] // the letters 법 join to form the Korean word for "rice:" U+BC95 법 (read from top left to bottom right) + [InlineData ("\U0001F468\u200D\U0001F469\u200D\U0001F467", "👨‍👩‍👧", 8, 6, 8)] // Man, Woman and Girl emoji. + [InlineData ("\u0915\u093f", "कि", 2, 2, 2)] // Hindi कि with DEVANAGARI LETTER KA and DEVANAGARI VOWEL SIGN I + [InlineData ("\u0e4d\u0e32", "ํา", 2, 1, 2)] // Decomposition: ํ (U+0E4D) - า (U+0E32) = U+0E33 ำ Thai Character Sara Am + [InlineData ("\u0e33", "ำ", 1, 1, 1)] // Decomposition: ํ (U+0E4D) - า (U+0E32) = U+0E33 ำ Thai Character Sara Am + public void GetColumns_String_Without_SurrogatePair (string code, string str, int codeLength, int runesLength, int stringLength) + { + Assert.Equal (str, code.Normalize ()); + Assert.Equal (codeLength, code.Length); + Assert.Equal (runesLength, code.EnumerateRunes ().Sum (x => x.GetColumns ())); + Assert.Equal (runesLength, str.GetColumns ()); + Assert.Equal (stringLength, str.Length); + } + + [Theory] + [InlineData (new char [] { '\ud799', '\udc21' })] + public void Rune_Exceptions_Utf16_Encode (char [] code) + { + Assert.False (RuneExtensions.EncodeSurrogatePair (code [0], code [1], out Rune rune)); + Assert.Throws (() => new Rune (code [0], code [1])); + } + + [Theory] + [InlineData (0x12345678)] + [InlineData ('\ud801')] + public void Rune_Exceptions_Integers (int code) + { + Assert.Throws (() => new Rune (code)); + } + + [Fact] + public void GetColumns_GetRuneCount () + { + PrintTextElementCount ('\u00e1'.ToString (), "á", 1, 1, 1, 1); + PrintTextElementCount ("\u0061\u0301", "á", 1, 2, 2, 1); + PrintTextElementCount ("\u0061\u0301", "á", 1, 2, 2, 1); + PrintTextElementCount ("\u0065\u0301", "é", 1, 2, 2, 1); + PrintTextElementCount ("\U0001f469\U0001f3fd\u200d\U0001f692", "👩🏽‍🚒", 6, 4, 7, 1); + PrintTextElementCount ("\ud801\udccf", "𐓏", 1, 1, 2, 1); + } + + private void PrintTextElementCount (string us, string s, int consoleWidth, int runeCount, int stringCount, int txtElementCount) + { + Assert.Equal (us.Length, s.Length); + Assert.Equal (us, s); + Assert.Equal (consoleWidth, us.GetColumns ()); + Assert.Equal (runeCount, us.GetRuneCount ()); + Assert.Equal (stringCount, s.Length); + + TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator (s); + + int textElementCount = 0; + while (enumerator.MoveNext ()) { + textElementCount++; // For versions prior to Net5.0 the StringInfo class might handle some grapheme clusters incorrectly. + } + + Assert.Equal (txtElementCount, textElementCount); + } + + [Fact] + public void TestRuneIsLetter () + { + Assert.Equal (5, CountLettersInString ("Hello")); + Assert.Equal (8, CountLettersInString ("𐓏𐓘𐓻𐓘𐓻𐓟 𐒻𐓟")); + } + + private int CountLettersInString (string s) + { + int letterCount = 0; + foreach (Rune rune in s.EnumerateRunes ()) { + if (Rune.IsLetter (rune)) { letterCount++; } + } + + return letterCount; + } + + [Fact] + public void Test_SurrogatePair_From_String () + { + Assert.True (ProcessTestStringUseChar ("𐓏𐓘𐓻𐓘𐓻𐓟 𐒻𐓟")); + Assert.Throws (() => ProcessTestStringUseChar ("\ud801")); + + Assert.True (ProcessStringUseRune ("𐓏𐓘𐓻𐓘𐓻𐓟 𐒻𐓟")); + Assert.Throws (() => ProcessStringUseRune ("\ud801")); + } + + private bool ProcessTestStringUseChar (string s) + { + char surrogateChar = default; + for (int i = 0; i < s.Length; i++) { + Rune r; + if (char.IsSurrogate (s [i])) { + if (surrogateChar != default && char.IsSurrogate (surrogateChar)) { + r = new Rune (surrogateChar, s [i]); + Assert.True (r.IsSurrogatePair ()); + int codePoint = char.ConvertToUtf32 (surrogateChar, s [i]); + RuneExtensions.EncodeSurrogatePair (surrogateChar, s [i], out Rune rune); + Assert.Equal (codePoint, rune.Value); + string sp = new string (new char [] { surrogateChar, s [i] }); + r = (Rune)codePoint; + Assert.Equal (sp, r.ToString ()); + Assert.True (r.IsSurrogatePair ()); + + surrogateChar = default; + } else if (i < s.Length - 1) { + surrogateChar = s [i]; + continue; + } else { + Assert.Throws (() => new Rune (s [i])); + throw new Exception ("String was not well-formed UTF-16."); + } + } else { + r = new Rune (s [i]); + var buff = new byte [4]; + ((Rune)s [i]).Encode (buff); + Assert.Equal ((int)s [i], buff [0]); + Assert.Equal (s [i], r.Value); + Assert.True (Rune.IsValid (r.Value)); + Assert.False (r.IsSurrogatePair ()); + } + } + return true; + } + + private bool ProcessStringUseRune (string s) + { + var us = s; + string rs = ""; + Rune codePoint; + List runes = new List (); + int colWidth = 0; + + for (int i = 0; i < s.Length; i++) { + Rune rune = default; + if (Rune.IsValid (s [i])) { + rune = new Rune (s [i]); + Assert.True (Rune.IsValid (rune.Value)); + runes.Add (rune); + Assert.Equal (s [i], rune.Value); + Assert.False (rune.IsSurrogatePair ()); + } else if (i + 1 < s.Length && (RuneExtensions.EncodeSurrogatePair (s [i], s [i + 1], out codePoint))) { + Assert.Equal (0, rune.Value); + Assert.False (Rune.IsValid (s [i])); + rune = codePoint; + runes.Add (rune); + string sp = new string (new char [] { s [i], s [i + 1] }); + Assert.Equal (sp, codePoint.ToString ()); + Assert.True (codePoint.IsSurrogatePair ()); + i++; // Increment the iterator by the number of surrogate pair + } else { + Assert.Throws (() => new Rune (s [i])); + throw new Exception ("String was not well-formed UTF-16."); + } + colWidth += rune.GetColumns (); // Increment the column width of this Rune + rs += rune.ToString (); + } + Assert.Equal (us.GetColumns (), colWidth); + Assert.Equal (s, rs); + Assert.Equal (s, StringExtensions.ToString (runes)); + return true; + } + + [Fact] + public void TestSplit () + { + string inputString = "🐂, 🐄, 🐆"; + string [] splitOnSpace = inputString.Split (' '); + string [] splitOnComma = inputString.Split (','); + Assert.Equal (3, splitOnSpace.Length); + Assert.Equal (3, splitOnComma.Length); + } + + [Theory] + [InlineData (true, '\u1100')] + [InlineData (true, '\ud83c', '\udf39')] + [InlineData (true, '\udbff', '\udfff')] + [InlineData (false, '\ud801')] + [InlineData (false, '\ud83e')] + public void Rune_IsValid (bool valid, params char [] chars) + { + Rune rune = default; + bool isValid = true; + if (chars.Length == 1) { + try { + rune = new Rune (chars [0]); + } catch (Exception) { + + isValid = false; + } + } else { + rune = new Rune (chars [0], chars [1]); + } + if (valid) { + Assert.NotEqual (default, rune); + Assert.True (Rune.IsValid (rune.Value)); + Assert.True (valid); + } else { + Assert.False (valid); + Assert.False (isValid); + } + } + + [Theory] + [InlineData ('\u006f', '\u0302', "\u006f\u0302", 1, 0, 2, "o", "̂", "ô", 1, 2)] + [InlineData ('\u0065', '\u0301', "\u0065\u0301", 1, 0, 2, "e", "́", "é", 1, 2)] + public void Test_NonSpacingChar (int code1, int code2, string code, int rune1Length, int rune2Length, int codeLength, string code1String, string code2String, string joinString, int joinLength, int bytesLength) + { + var rune = new Rune (code1); + var nsRune = new Rune (code2); + Assert.Equal (rune1Length, rune.GetColumns ()); + Assert.Equal (rune2Length, nsRune.GetColumns ()); + var ul = rune.ToString (); + Assert.Equal (code1String, ul); + var uns = nsRune.ToString (); + Assert.Equal (code2String, uns); + var f = $"{rune}{nsRune}".Normalize (); + Assert.Equal (f, joinString); + Assert.Equal (f, code.Normalize ()); + Assert.Equal (joinLength, f.GetColumns ()); + Assert.Equal (joinLength, code.EnumerateRunes ().Sum (c => c.GetColumns ())); + Assert.Equal (codeLength, code.Length); + (var nrune, var size) = f.DecodeRune (); + Assert.Equal (f.ToRunes () [0], nrune); + Assert.Equal (bytesLength, size); + } + + [Theory] + [InlineData (500000000)] + [InlineData (0xf801, 0xdfff)] + public void Test_MaxRune (params int [] codes) + { + if (codes.Length == 1) { + Assert.Throws (() => new Rune (codes [0])); + } else { + Assert.Throws (() => new Rune ((char)codes [0], (char)codes [1])); + } + } + + [Fact] + public void Sum_Of_Rune_GetColumns_Is_Not_Always_Equal_To_String_GetColumns () + { + const int start = 0x000000; + const int end = 0x10ffff; + + for (int i = start; i <= end; i++) { + if (char.IsSurrogate ((char)i)) { + continue; + } + Rune r = new Rune ((uint)i); + string us = r.ToString (); + string hex = i.ToString ("x6"); + int v = int.Parse (hex, System.Globalization.NumberStyles.HexNumber); + string s = char.ConvertFromUtf32 (v); + + if (!r.IsSurrogatePair ()) { + Assert.Equal (r.ToString (), us); + Assert.Equal (us, s); + if (r.GetColumns () < 0) { + Assert.NotEqual (r.GetColumns (), us.GetColumns ()); + Assert.NotEqual (s.EnumerateRunes ().Sum (c => c.GetColumns ()), us.GetColumns ()); + } else { + Assert.Equal (r.GetColumns (), us.GetColumns ()); + Assert.Equal (s.EnumerateRunes ().Sum (c => c.GetColumns ()), us.GetColumns ()); + } + Assert.Equal (us.GetRuneCount (), s.Length); + } else { + Assert.Equal (r.ToString (), us); + Assert.Equal (us, s); + Assert.Equal (r.GetColumns (), us.GetColumns ()); + Assert.Equal (s.GetColumns (), us.GetColumns ()); + Assert.Equal (1, us.GetRuneCount ()); // Here returns 1 because is a valid surrogate pair resulting in only rune >=U+10000..U+10FFFF + Assert.Equal (2, s.Length); // String always preserves the originals values of each surrogate pair + } + } + } + + [Theory] + [InlineData (0x20D0, 0x20EF)] + [InlineData (0x2310, 0x231F)] + [InlineData (0x1D800, 0x1D80F)] + public void Test_Range (int start, int end) + { + for (int i = start; i <= end; i++) { + Rune r = new Rune ((uint)i); + string us = r.ToString (); + string hex = i.ToString ("x6"); + int v = int.Parse (hex, System.Globalization.NumberStyles.HexNumber); + string s = char.ConvertFromUtf32 (v); + + if (!r.IsSurrogatePair ()) { + Assert.Equal (r.ToString (), us); + Assert.Equal (us, s); + Assert.Equal (r.GetColumns (), us.GetColumns ()); + Assert.Equal (us.GetRuneCount (), s.Length); // For not surrogate pairs string.RuneCount is always equal to String.Length + } else { + Assert.Equal (r.ToString (), us); + Assert.Equal (us, s); + Assert.Equal (r.GetColumns (), us.GetColumns ()); + Assert.Equal (1, us.GetRuneCount ()); // Here returns 1 because is a valid surrogate pair resulting in only rune >=U+10000..U+10FFFF + Assert.Equal (2, s.Length); // String always preserves the originals values of each surrogate pair + } + Assert.Equal (s.GetColumns (), us.GetColumns ()); + } + } + + [Theory] + [InlineData ('\ue0fd', false)] + [InlineData ('\ud800', true)] + [InlineData ('\udfff', true)] + public void Test_IsSurrogate (char code, bool isSurrogate) + { + if (isSurrogate) { + Assert.True (char.IsSurrogate (code.ToString (), 0)); + } else { + Assert.False (char.IsSurrogate (code.ToString (), 0)); + } + } + + [Theory] + [InlineData (unchecked((char)0x40D7C0), (char)0xDC20, 0, "\0", false)] + [InlineData ((char)0x0065, (char)0x0301, 0, "\0", false)] + [InlineData ('\ud83c', '\udf56', 0x1F356, "🍖", true)] // 🍖 Meat On Bone + public void Test_EncodeSurrogatePair (char highSurrogate, char lowSurrogate, int runeValue, string runeString, bool isSurrogatePair) + { + Rune rune; + if (isSurrogatePair) { + Assert.True (RuneExtensions.EncodeSurrogatePair ('\ud83c', '\udf56', out rune)); + } else { + Assert.False (RuneExtensions.EncodeSurrogatePair (highSurrogate, lowSurrogate, out rune)); + } + Assert.Equal (runeValue, rune.Value); + Assert.Equal (runeString, rune.ToString ()); + } + + [Theory] + [InlineData ('\uea85', null, "", false)] // Private Use Area + [InlineData (0x1F356, new char [] { '\ud83c', '\udf56' }, "🍖", true)] // 🍖 Meat On Bone + public void Test_DecodeSurrogatePair (int code, char [] charsValue, string runeString, bool isSurrogatePair) + { + Rune rune = new Rune (code); + char [] chars; + if (isSurrogatePair) { + Assert.True (rune.DecodeSurrogatePair (out chars)); + Assert.Equal (2, chars.Length); + Assert.Equal (charsValue [0], chars [0]); + Assert.Equal (charsValue [1], chars [1]); + Assert.Equal (runeString, new Rune (chars [0], chars [1]).ToString ()); + } else { + Assert.False (rune.DecodeSurrogatePair (out chars)); + Assert.Null (chars); + Assert.Equal (runeString, rune.ToString ()); + } + Assert.Equal (chars, charsValue); + } + + [Fact] + public void Test_All_Surrogate_Pairs_Range () + { + for (uint h = 0xd800; h <= 0xdbff; h++) { + for (uint l = 0xdc00; l <= 0xdfff; l++) { + Rune r = new Rune ((char)h, (char)l); + string us = r.ToString (); + string hex = r.Value.ToString ("x6"); + int v = int.Parse (hex, System.Globalization.NumberStyles.HexNumber); + string s = char.ConvertFromUtf32 (v); + + Assert.True (v >= 0x10000 && v <= RuneExtensions.MaxUnicodeCodePoint); + Assert.Equal (r.ToString (), us); + Assert.Equal (us, s); + Assert.Equal (r.GetColumns (), us.GetColumns ()); + Assert.Equal (s.GetColumns (), us.GetColumns ()); + Assert.Equal (1, us.GetRuneCount ()); // Here returns 1 because is a valid surrogate pair resulting in only rune >=U+10000..U+10FFFF + Assert.Equal (2, s.Length); // String always preserves the originals values of each surrogate pair + } + } + } + + [Theory] + [InlineData ("Hello, 世界", 13, 11, 9)] // Without Surrogate Pairs + [InlineData ("Hello, 𝔹𝕆𝔹", 19, 13, 13)] // With Surrogate Pairs + public void Test_DecodeRune_Extension (string text, int bytesLength, int colsLength, int textLength) + { + List runes = new List (); + int tSize = 0; + for (int i = 0; i < text.GetRuneCount (); i++) { + (Rune rune, int size) = text.DecodeRune (i); + runes.Add (rune); + tSize += size; + } + string result = StringExtensions.ToString (runes); + Assert.Equal (text, result); + Assert.Equal (bytesLength, tSize); + Assert.Equal (colsLength, result.GetColumns ()); + Assert.Equal (textLength, result.Length); + } + + [Theory] + [InlineData ("Hello, 世界", 13, 11, 9, "界世 ,olleH")] // Without Surrogate Pairs + [InlineData ("Hello, 𝔹𝕆𝔹", 19, 13, 13, "𝔹𝕆𝔹 ,olleH")] // With Surrogate Pairs + public void Test_DecodeLastRune_Extension (string text, int bytesLength, int colsLength, int textLength, string encoded) + { + List runes = new List (); + int tSize = 0; + for (int i = text.GetRuneCount () - 1; i >= 0; i--) { + (Rune rune, int size) = text.DecodeLastRune (i); + runes.Add (rune); + tSize += size; + } + string result = StringExtensions.ToString (runes); + Assert.Equal (encoded, result); + Assert.Equal (bytesLength, tSize); + Assert.Equal (colsLength, result.GetColumns ()); + Assert.Equal (textLength, result.Length); + } + + [Theory] + [InlineData ("���", false)] + [InlineData ("Hello, 世界", true)] + [InlineData (new byte [] { 0xff, 0xfe, 0xfd }, false)] + [InlineData (new byte [] { 0xf0, 0x9f, 0x8d, 0x95 }, true)] + public void Test_CanBeEncodedAsRune_Extension (object text, bool canBeEncodedAsRune) + { + string str; + if (text is string) { + str = (string)text; + if (canBeEncodedAsRune) { + Assert.True (RuneExtensions.CanBeEncodedAsRune (Encoding.Unicode.GetBytes (str.ToCharArray ()))); + } else { + Assert.False (RuneExtensions.CanBeEncodedAsRune (Encoding.Unicode.GetBytes (str.ToCharArray ()))); + } + } else if (text is byte []) { + str = StringExtensions.ToString ((byte [])text); + if (canBeEncodedAsRune) { + Assert.True (RuneExtensions.CanBeEncodedAsRune (Encoding.Unicode.GetBytes (str.ToCharArray ()))); + } else { + Assert.False (RuneExtensions.CanBeEncodedAsRune (Encoding.Unicode.GetBytes (str.ToCharArray ()))); + } + } + } + + [Fact] + public void Equals_ToRuneList () + { + var a = new List> () { "First line.".ToRuneList () }; + var b = new List> () { "First line.".ToRuneList (), "Second line.".ToRuneList () }; + var c = new List (a [0]); + var d = a [0]; + + Assert.Equal (a [0], b [0]); + // Not the same reference + Assert.False (a [0] == b [0]); + Assert.NotEqual (a [0], b [1]); + Assert.False (a [0] == b [1]); + + Assert.Equal (c, a [0]); + Assert.False (c == a [0]); + Assert.Equal (c, b [0]); + Assert.False (c == b [0]); + Assert.NotEqual (c, b [1]); + Assert.False (c == b [1]); + + Assert.Equal (d, a [0]); + // Is the same reference + Assert.True (d == a [0]); + Assert.Equal (d, b [0]); + Assert.False (d == b [0]); + Assert.NotEqual (d, b [1]); + Assert.False (d == b [1]); + + Assert.True (a [0].SequenceEqual (b [0])); + Assert.False (a [0].SequenceEqual (b [1])); + + Assert.True (c.SequenceEqual (a [0])); + Assert.True (c.SequenceEqual (b [0])); + Assert.False (c.SequenceEqual (b [1])); + + Assert.True (d.SequenceEqual (a [0])); + Assert.True (d.SequenceEqual (b [0])); + Assert.False (d.SequenceEqual (b [1])); + } + + [Fact] + public void Rune_GetColumns_Versus_String_GetColumns_With_Non_Printable_Characters () + { + int sumRuneWidth = 0; + int sumConsoleWidth = 0; + for (uint i = 0; i < 32; i++) { + sumRuneWidth += ((Rune)i).GetColumns (); + sumConsoleWidth += ((Rune)i).ToString ().GetColumns (); + } + + Assert.Equal (-32, sumRuneWidth); + Assert.Equal (0, sumConsoleWidth); + } + + [Theory] + [InlineData ("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 200, 200, 200)] + [InlineData ("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n", 201, 200, 199)] // has a '\n' newline + [InlineData ("\t01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n", 202, 200, 198)] // has a '\t' and a '\n' newline + public void Rune_ColumnWidth_Versus_String_ConsoleWidth (string text, int stringLength, int strCols, int runeCols) + { + Assert.Equal (stringLength, text.Length); + Assert.Equal (stringLength, text.GetRuneCount ()); + Assert.Equal (strCols, text.GetColumns ()); + int sumRuneWidth = text.EnumerateRunes ().Sum (x => x.GetColumns ()); + Assert.Equal (runeCols, sumRuneWidth); + } + + [Theory] + [InlineData ('\ud800', true)] + [InlineData ('\udbff', true)] + [InlineData ('\udc00', false)] + [InlineData ('\udfff', false)] + [InlineData ('\uefff', null)] + public void Rune_IsHighSurrogate_IsLowSurrogate (char code, bool? isHighSurrogate) + { + if (isHighSurrogate == true) { + Assert.True (char.IsHighSurrogate (code)); + } else if (isHighSurrogate == false) { + Assert.True (char.IsLowSurrogate (code)); + } else { + Assert.False (char.IsHighSurrogate (code)); + Assert.False (char.IsLowSurrogate (code)); + } + } + + [Theory] + [InlineData ("First line.")] + [InlineData ("Hello, 𝔹𝕆𝔹")] + public void Rune_ToRunes (string text) + { + var runes = text.ToRunes (); + for (int i = 0; i < runes.Length; i++) { + Assert.Equal (text.EnumerateRunes ().ToArray () [i].Value, runes [i].Value); + } + } + + [Theory] + [InlineData ('a', 1, 1)] + [InlineData (31, 1, 1)] + [InlineData (123, 1, 1)] + [InlineData (127, 1, 1)] + [InlineData ('\u1150', 1, 3)] + [InlineData ('\u1161', 1, 3)] + [InlineData (0x16fe0, 2, 4)] + public void System_Text_Rune_SequenceLength (int code, int utf16Length, int utf8Length) + { + var r = new System.Text.Rune (code); + Assert.Equal (utf16Length, r.Utf16SequenceLength); + Assert.Equal (utf8Length, r.Utf8SequenceLength); + } +} diff --git a/UnitTests/Text/StringTests.cs b/UnitTests/Text/StringTests.cs new file mode 100644 index 000000000..4b708034e --- /dev/null +++ b/UnitTests/Text/StringTests.cs @@ -0,0 +1,70 @@ +using Xunit; + +namespace Terminal.Gui.TextTests; + +#nullable enable + +public class StringTests { + [Fact] + public void TestGetColumns_Empty () + { + var str = string.Empty; + Assert.Equal (0, str.GetColumns ()); + } + + [Fact] + public void TestGetColumns_Null () + { + string? str = null; + Assert.Equal (0, str.GetColumns ()); + } + + [Fact] + public void TestGetColumns_SingleRune () + { + var str = "a"; + Assert.Equal (1, str.GetColumns ()); + } + + [Theory] + [InlineData ("a", 1)] + [InlineData ("á", 1)] + [InlineData ("ab", 2)] + [InlineData ("áé", 2)] + [InlineData ("abc", 3)] + [InlineData ("áéí", 3)] + [InlineData ("abcd", 4)] + public void TestGetColumns_MultiRune (string str, int expected) + { + Assert.Equal (expected, str.GetColumns ()); + } + + // Test known wide codepoints + [Theory] + [InlineData ("🙂", 2)] + [InlineData ("a🙂", 3)] + [InlineData ("🙂a", 3)] + [InlineData ("👨‍👩‍👦‍👦", 8)] + [InlineData ("👨‍👩‍👦‍👦🙂", 10)] + [InlineData ("👨‍👩‍👦‍👦🙂a", 11)] + [InlineData ("👨‍👩‍👦‍👦a🙂", 11)] + [InlineData ("👨‍👩‍👦‍👦👨‍👩‍👦‍👦", 16)] + [InlineData ("山", 2)] // The character for "mountain" in Chinese/Japanese/Korean (山), Unicode U+5C71 + [InlineData ("山🙂", 4)] // The character for "mountain" in Chinese/Japanese/Korean (山), Unicode U+5C71 + public void TestGetColumns_MultiRune_WideBMP (string str, int expected) + { + Assert.Equal (expected, str.GetColumns ()); + } + + // Test non-BMP codepoints + // Face with Tears of Joy Emoji (😂), Unicode U+1F602 is 2 columns wide + [Theory] + [InlineData ("😂", 2)] + [InlineData ("😂😂", 4)] + public void TestGetColumns_MultiRune_NonBMP (string str, int expected) + { + Assert.Equal (expected, str.GetColumns ()); + } + +} + diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs index d95cb2ca5..858a660a1 100644 --- a/UnitTests/Text/TextFormatterTests.cs +++ b/UnitTests/Text/TextFormatterTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Linq; @@ -21,7 +21,7 @@ namespace Terminal.Gui.TextTests { [Fact] public void Basic_Usage () { - var testText = ustring.Make ("test"); + var testText = "test"; var expectedSize = new Size (); var testBounds = new Rect (0, 0, 100, 1); var tf = new TextFormatter (); @@ -77,7 +77,7 @@ namespace Terminal.Gui.TextTests { [Fact] public void NeedsFormat_Sets () { - var testText = ustring.Make ("test"); + var testText = "test"; var testBounds = new Rect (0, 0, 100, 1); var tf = new TextFormatter (); @@ -100,1438 +100,492 @@ namespace Terminal.Gui.TextTests { Assert.False (tf.NeedsFormat); // get_Lines causes a Format } - [Fact] - public void FindHotKey_Invalid_ReturnsFalse () + [Theory] + [InlineData (null)] + [InlineData ("")] + [InlineData ("no hotkey")] + [InlineData ("No hotkey, Upper Case")] + [InlineData ("Non-english: Сохранить")] + public void FindHotKey_Invalid_ReturnsFalse (string text) { - var text = ustring.Empty; - Rune hotKeySpecifier = '_'; + Rune hotKeySpecifier = (Rune)'_'; bool supportFirstUpperCase = false; int hotPos = 0; Key hotKey = Key.Unknown; bool result = false; - text = null; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = ""; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "no hotkey"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "No hotkey, Upper Case"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Non-english: Сохранить"; result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); Assert.False (result); Assert.Equal (-1, hotPos); Assert.Equal (Key.Unknown, hotKey); } - [Fact] - public void FindHotKey_AlphaUpperCase_Succeeds () + [Theory] + [InlineData ("_K Before", true, 0, (Key)'K')] + [InlineData ("a_K Second", true, 1, (Key)'K')] + [InlineData ("Last _K", true, 5, (Key)'K')] + [InlineData ("After K_", false, -1, Key.Unknown)] + [InlineData ("Multiple _K and _R", true, 9, (Key)'K')] + [InlineData ("Non-english: _Кдать", true, 13, (Key)'К')] // Cryllic K (К) + [InlineData ("_K Before", true, 0, (Key)'K', true)] // Turn on FirstUpperCase and verify same results + [InlineData ("a_K Second", true, 1, (Key)'K', true)] + [InlineData ("Last _K", true, 5, (Key)'K', true)] + [InlineData ("After K_", false, -1, Key.Unknown, true)] + [InlineData ("Multiple _K and _R", true, 9, (Key)'K', true)] + [InlineData ("Non-english: _Кдать", true, 13, (Key)'К', true)] // Cryllic K (К) + public void FindHotKey_AlphaUpperCase_Succeeds (string text, bool expectedResult, int expectedHotPos, Key expectedKey, bool supportFirstUpperCase = false) { - var text = ustring.Empty; - Rune hotKeySpecifier = '_'; - bool supportFirstUpperCase = false; - int hotPos = 0; - Key hotKey = Key.Unknown; - bool result = false; + Rune hotKeySpecifier = (Rune)'_'; - text = "_K Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "a_K Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "Last _K"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "After K_"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Multiple _K and _R"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'K', hotKey); - - // Cryllic K (К) - text = "Non-english: _Кдать"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (13, hotPos); - Assert.Equal ((Key)'К', hotKey); - - // Turn on FirstUpperCase and verify same results - supportFirstUpperCase = true; - text = "_K Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "a_K Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "Last _K"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "After K_"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Multiple _K and _R"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'K', hotKey); - - // Cryllic K (К) - text = "Non-english: _Кдать"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (13, hotPos); - Assert.Equal ((Key)'К', hotKey); - } - [Fact] - public void FindHotKey_AlphaLowerCase_Succeeds () - { - var text = ustring.Empty; - Rune hotKeySpecifier = '_'; - bool supportFirstUpperCase = false; - int hotPos = 0; - Key hotKey = Key.Unknown; - bool result = false; - - // lower case should return uppercase Hotkey - text = "_k Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "a_k Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "Last _k"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "After k_"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Multiple _k and _R"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'K', hotKey); - - // Lower case Cryllic K (к) - text = "Non-english: _кдать"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (13, hotPos); - Assert.Equal ((Key)'К', hotKey); - - // Turn on FirstUpperCase and verify same results - supportFirstUpperCase = true; - text = "_k Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "a_k Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "Last _k"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "After k_"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Multiple _k and _R"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'K', hotKey); - - // Lower case Cryllic K (к) - text = "Non-english: _кдать"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (13, hotPos); - Assert.Equal ((Key)'К', hotKey); + var result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out int hotPos, out Key hotKey); + if (expectedResult) { + Assert.True (result); + } else { + Assert.False (result); + } + Assert.Equal (expectedResult, result); + Assert.Equal (expectedHotPos, hotPos); + Assert.Equal (expectedKey, hotKey); } - [Fact] - public void FindHotKey_Numeric_Succeeds () + [Theory] + [InlineData ("_k Before", true, 0, (Key)'K')] // lower case should return uppercase Hotkey + [InlineData ("a_k Second", true, 1, (Key)'K')] + [InlineData ("Last _k", true, 5, (Key)'K')] + [InlineData ("After k_", false, -1, Key.Unknown)] + [InlineData ("Multiple _k and _R", true, 9, (Key)'K')] + [InlineData ("Non-english: _кдать", true, 13, (Key)'К')] // Lower case Cryllic K (к) + [InlineData ("_k Before", true, 0, (Key)'K', true)] // Turn on FirstUpperCase and verify same results + [InlineData ("a_k Second", true, 1, (Key)'K', true)] + [InlineData ("Last _k", true, 5, (Key)'K', true)] + [InlineData ("After k_", false, -1, Key.Unknown, true)] + [InlineData ("Multiple _k and _r", true, 9, (Key)'K', true)] + [InlineData ("Non-english: _кдать", true, 13, (Key)'К', true)] // Cryllic K (К) + public void FindHotKey_AlphaLowerCase_Succeeds (string text, bool expectedResult, int expectedHotPos, Key expectedKey, bool supportFirstUpperCase = false) { - var text = ustring.Empty; - Rune hotKeySpecifier = '_'; - bool supportFirstUpperCase = false; - int hotPos = 0; - Key hotKey = Key.Unknown; - bool result = false; - // Digits - text = "_1 Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'1', hotKey); + Rune hotKeySpecifier = (Rune)'_'; - text = "a_1 Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'1', hotKey); - - text = "Last _1"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'1', hotKey); - - text = "After 1_"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Multiple _1 and _2"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'1', hotKey); - - // Turn on FirstUpperCase and verify same results - supportFirstUpperCase = true; - text = "_1 Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'1', hotKey); - - text = "a_1 Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'1', hotKey); - - text = "Last _1"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'1', hotKey); - - text = "After 1_"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "Multiple _1 and _2"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'1', hotKey); + var result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out int hotPos, out Key hotKey); + if (expectedResult) { + Assert.True (result); + } else { + Assert.False (result); + } + Assert.Equal (expectedResult, result); + Assert.Equal (expectedHotPos, hotPos); + Assert.Equal (expectedKey, hotKey); } - [Fact] - public void FindHotKey_Legacy_FirstUpperCase_Succeeds () + [Theory] + [InlineData ("_1 Before", true, 0, (Key)'1')] // Digits + [InlineData ("a_1 Second", true, 1, (Key)'1')] + [InlineData ("Last _1", true, 5, (Key)'1')] + [InlineData ("After 1_", false, -1, Key.Unknown)] + [InlineData ("Multiple _1 and _2", true, 9, (Key)'1')] + [InlineData ("_1 Before", true, 0, (Key)'1', true)] // Turn on FirstUpperCase and verify same results + [InlineData ("a_1 Second", true, 1, (Key)'1', true)] + [InlineData ("Last _1", true, 5, (Key)'1', true)] + [InlineData ("After 1_", false, -1, Key.Unknown, true)] + [InlineData ("Multiple _1 and _2", true, 9, (Key)'1', true)] + public void FindHotKey_Numeric_Succeeds (string text, bool expectedResult, int expectedHotPos, Key expectedKey, bool supportFirstUpperCase = false) + { + Rune hotKeySpecifier = (Rune)'_'; + + var result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out int hotPos, out Key hotKey); + if (expectedResult) { + Assert.True (result); + } else { + Assert.False (result); + } + Assert.Equal (expectedResult, result); + Assert.Equal (expectedHotPos, hotPos); + Assert.Equal (expectedKey, hotKey); + } + + [Theory] + [InlineData ("K Before", true, 0, (Key)'K')] + [InlineData ("aK Second", true, 1, (Key)'K')] + [InlineData ("last K", true, 5, (Key)'K')] + [InlineData ("multiple K and R", true, 9, (Key)'K')] + [InlineData ("non-english: Кдать", true, 13, (Key)'К')] // Cryllic K (К) + public void FindHotKey_Legacy_FirstUpperCase_Succeeds (string text, bool expectedResult, int expectedHotPos, Key expectedKey) + { + var supportFirstUpperCase = true; + + Rune hotKeySpecifier = (Rune)0; + + var result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out int hotPos, out Key hotKey); + if (expectedResult) { + Assert.True (result); + } else { + Assert.False (result); + } + Assert.Equal (expectedResult, result); + Assert.Equal (expectedHotPos, hotPos); + Assert.Equal (expectedKey, hotKey); + } + + [Theory] + [InlineData ("\"k before")] + [InlineData ("ak second")] + [InlineData ("last k")] + [InlineData ("multiple k and r")] + [InlineData ("12345")] + [InlineData ("`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?")] // punctuation + [InlineData (" ~  s  gui.cs   master ↑10")] // ~IsLetterOrDigit + Unicode + [InlineData ("non-english: кдать")] // Lower case Cryllic K (к) + public void FindHotKey_Legacy_FirstUpperCase_NotFound_Returns_False (string text) { bool supportFirstUpperCase = true; - var text = ustring.Empty; var hotKeySpecifier = (Rune)0; - int hotPos = 0; - Key hotKey = Key.Unknown; - bool result = false; - text = "K Before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (0, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "aK Second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (1, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "last K"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (5, hotPos); - Assert.Equal ((Key)'K', hotKey); - - text = "multiple K and R"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (9, hotPos); - Assert.Equal ((Key)'K', hotKey); - - // Cryllic K (К) - text = "non-english: Кдать"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.True (result); - Assert.Equal (13, hotPos); - Assert.Equal ((Key)'К', hotKey); - } - - [Fact] - public void FindHotKey_Legacy_FirstUpperCase_NotFound_Returns_False () - { - bool supportFirstUpperCase = true; - - var text = ustring.Empty; - var hotKeySpecifier = (Rune)0; - int hotPos = 0; - Key hotKey = Key.Unknown; - bool result = false; - - text = "k before"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "ak second"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "last k"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "multiple k and r"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - text = "12345"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - // punctuation - text = "`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - // ~IsLetterOrDigit + Unicode - text = " ~  s  gui.cs   master ↑10"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); - Assert.False (result); - Assert.Equal (-1, hotPos); - Assert.Equal (Key.Unknown, hotKey); - - // Lower case Cryllic K (к) - text = "non-english: кдать"; - result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out hotPos, out hotKey); + var result = TextFormatter.FindHotKey (text, hotKeySpecifier, supportFirstUpperCase, out int hotPos, out Key hotKey); Assert.False (result); Assert.Equal (-1, hotPos); Assert.Equal (Key.Unknown, hotKey); } - static ustring testHotKeyAtStart = "_K Before"; - static ustring testHotKeyAtSecondPos = "a_K Second"; - static ustring testHotKeyAtLastPos = "Last _K"; - static ustring testHotKeyAfterLastChar = "After K_"; - static ustring testMultiHotKeys = "Multiple _K and _R"; - static ustring testNonEnglish = "Non-english: _Кдать"; + static string testHotKeyAtStart = "_K Before"; + static string testHotKeyAtSecondPos = "a_K Second"; + static string testHotKeyAtLastPos = "Last _K"; + static string testHotKeyAfterLastChar = "After K_"; + static string testMultiHotKeys = "Multiple _K and _R"; + static string testNonEnglish = "Non-english: _Кдать"; - [Fact] - public void RemoveHotKeySpecifier_InValid_ReturnsOriginal () + [Theory] + [InlineData (null)] + [InlineData ("")] + [InlineData ("a")] + public void RemoveHotKeySpecifier_InValid_ReturnsOriginal (string text) { - Rune hotKeySpecifier = '_'; + Rune hotKeySpecifier = (Rune)'_'; - Assert.Null (TextFormatter.RemoveHotKeySpecifier (null, 0, hotKeySpecifier)); - Assert.Equal ("", TextFormatter.RemoveHotKeySpecifier ("", 0, hotKeySpecifier)); - Assert.Equal ("", TextFormatter.RemoveHotKeySpecifier ("", -1, hotKeySpecifier)); - Assert.Equal ("", TextFormatter.RemoveHotKeySpecifier ("", 100, hotKeySpecifier)); - - Assert.Equal ("a", TextFormatter.RemoveHotKeySpecifier ("a", -1, hotKeySpecifier)); - Assert.Equal ("a", TextFormatter.RemoveHotKeySpecifier ("a", 100, hotKeySpecifier)); + if (text == null) { + Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier)); + Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier)); + Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier)); + } else { + Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier)); + Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier)); + Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier)); + } } - [Fact] - public void RemoveHotKeySpecifier_Valid_ReturnsStripped () + [Theory] + [InlineData ("_K Before", 0, "K Before")] + [InlineData ("a_K Second", 1, "aK Second")] + [InlineData ("Last _K", 5, "Last K")] + [InlineData ("After K_", 7, "After K")] + [InlineData ("Multiple _K and _R", 9, "Multiple K and _R")] + [InlineData ("Non-english: _Кдать", 13, "Non-english: Кдать")] + public void RemoveHotKeySpecifier_Valid_ReturnsStripped (string text, int hotPos, string expectedText) { - Rune hotKeySpecifier = '_'; + Rune hotKeySpecifier = (Rune)'_'; - Assert.Equal ("K Before", TextFormatter.RemoveHotKeySpecifier ("_K Before", 0, hotKeySpecifier)); - Assert.Equal ("aK Second", TextFormatter.RemoveHotKeySpecifier ("a_K Second", 1, hotKeySpecifier)); - Assert.Equal ("Last K", TextFormatter.RemoveHotKeySpecifier ("Last _K", 5, hotKeySpecifier)); - Assert.Equal ("After K", TextFormatter.RemoveHotKeySpecifier ("After K_", 7, hotKeySpecifier)); - Assert.Equal ("Multiple K and _R", TextFormatter.RemoveHotKeySpecifier ("Multiple _K and _R", 9, hotKeySpecifier)); - Assert.Equal ("Non-english: Кдать", TextFormatter.RemoveHotKeySpecifier ("Non-english: _Кдать", 13, hotKeySpecifier)); + Assert.Equal (expectedText, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier)); } - [Fact] - public void RemoveHotKeySpecifier_Valid_Legacy_ReturnsOriginal () + [Theory] + [InlineData ("all lower case", 0)] + [InlineData ("K Before", 0)] + [InlineData ("aK Second", 1)] + [InlineData ("Last K", 5)] + [InlineData ("fter K", 7)] + [InlineData ("Multiple K and R", 9)] + [InlineData ("Non-english: Кдать", 13)] + public void RemoveHotKeySpecifier_Valid_Legacy_ReturnsOriginal (string text, int hotPos) { - Rune hotKeySpecifier = '_'; + Rune hotKeySpecifier = (Rune)'_'; - Assert.Equal ("all lower case", TextFormatter.RemoveHotKeySpecifier ("all lower case", 0, hotKeySpecifier)); - Assert.Equal ("K Before", TextFormatter.RemoveHotKeySpecifier ("K Before", 0, hotKeySpecifier)); - Assert.Equal ("aK Second", TextFormatter.RemoveHotKeySpecifier ("aK Second", 1, hotKeySpecifier)); - Assert.Equal ("Last K", TextFormatter.RemoveHotKeySpecifier ("Last K", 5, hotKeySpecifier)); - Assert.Equal ("After K", TextFormatter.RemoveHotKeySpecifier ("After K", 7, hotKeySpecifier)); - Assert.Equal ("Multiple K and R", TextFormatter.RemoveHotKeySpecifier ("Multiple K and R", 9, hotKeySpecifier)); - Assert.Equal ("Non-english: Кдать", TextFormatter.RemoveHotKeySpecifier ("Non-english: Кдать", 13, hotKeySpecifier)); + Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier)); } - [Fact] - public void CalcRect_Invalid_Returns_Empty () + [Theory] + [InlineData (null)] + [InlineData ("")] + public void CalcRect_Invalid_Returns_Empty (string text) { - Assert.Equal (Rect.Empty, TextFormatter.CalcRect (0, 0, null)); - Assert.Equal (Rect.Empty, TextFormatter.CalcRect (0, 0, "")); - Assert.Equal (new Rect (new Point (1, 2), Size.Empty), TextFormatter.CalcRect (1, 2, "")); - Assert.Equal (new Rect (new Point (-1, -2), Size.Empty), TextFormatter.CalcRect (-1, -2, "")); + Assert.Equal (Rect.Empty, TextFormatter.CalcRect (0, 0, text)); + Assert.Equal (new Rect (new Point (1, 2), Size.Empty), TextFormatter.CalcRect (1, 2, text)); + Assert.Equal (new Rect (new Point (-1, -2), Size.Empty), TextFormatter.CalcRect (-1, -2, text)); } - [Fact] - public void CalcRect_SingleLine_Returns_1High () + [Theory] + [InlineData ("test")] + [InlineData (" ~  s  gui.cs   master ↑10")] + public void CalcRect_SingleLine_Returns_1High (string text) { - var text = ustring.Empty; - - text = "test"; - Assert.Equal (new Rect (0, 0, text.RuneCount, 1), TextFormatter.CalcRect (0, 0, text)); - Assert.Equal (new Rect (0, 0, text.ConsoleWidth, 1), TextFormatter.CalcRect (0, 0, text)); - - text = " ~  s  gui.cs   master ↑10"; - Assert.Equal (new Rect (0, 0, text.RuneCount, 1), TextFormatter.CalcRect (0, 0, text)); - Assert.Equal (new Rect (0, 0, text.ConsoleWidth, 1), TextFormatter.CalcRect (0, 0, text)); + Assert.Equal (new Rect (0, 0, text.GetRuneCount (), 1), TextFormatter.CalcRect (0, 0, text)); + Assert.Equal (new Rect (0, 0, text.GetColumns (), 1), TextFormatter.CalcRect (0, 0, text)); } - [Fact] - public void CalcRect_MultiLine_Returns_nHigh () + [Theory] + [InlineData ("line1\nline2", 5, 2)] + [InlineData ("\nline2", 5, 2)] + [InlineData ("\n\n", 0, 3)] + [InlineData ("\n\n\n", 0, 4)] + [InlineData ("line1\nline2\nline3long!", 10, 3)] + [InlineData ("line1\nline2\n\n", 5, 4)] + [InlineData ("line1\r\nline2", 5, 2)] + [InlineData (" ~  s  gui.cs   master ↑10\n", 31, 2)] + [InlineData ("\n ~  s  gui.cs   master ↑10", 31, 2)] + [InlineData (" ~  s  gui.cs   master\n↑10", 27, 2)] + public void CalcRect_MultiLine_Returns_nHigh (string text, int expectedWidth, int expectedLines) { - var text = ustring.Empty; - var lines = 0; - - text = "line1\nline2"; - lines = 2; - Assert.Equal (new Rect (0, 0, 5, lines), TextFormatter.CalcRect (0, 0, text)); - - text = "\nline2"; - lines = 2; - Assert.Equal (new Rect (0, 0, 5, lines), TextFormatter.CalcRect (0, 0, text)); - - text = "\n\n"; - lines = 3; - Assert.Equal (new Rect (0, 0, 0, lines), TextFormatter.CalcRect (0, 0, text)); - - text = "\n\n\n"; - lines = 4; - Assert.Equal (new Rect (0, 0, 0, lines), TextFormatter.CalcRect (0, 0, text)); - - text = "line1\nline2\nline3long!"; - lines = 3; - Assert.Equal (new Rect (0, 0, 10, lines), TextFormatter.CalcRect (0, 0, text)); - - text = "line1\nline2\n\n"; - lines = 4; - Assert.Equal (new Rect (0, 0, 5, lines), TextFormatter.CalcRect (0, 0, text)); - - text = "line1\r\nline2"; - lines = 2; - Assert.Equal (new Rect (0, 0, 5, lines), TextFormatter.CalcRect (0, 0, text)); - - text = " ~  s  gui.cs   master ↑10\n"; - lines = 2; - Assert.Equal (new Rect (0, 0, text.RuneCount - 1, lines), TextFormatter.CalcRect (0, 0, text)); - Assert.Equal (new Rect (0, 0, text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 0)), lines), TextFormatter.CalcRect (0, 0, text)); - - text = "\n ~  s  gui.cs   master ↑10"; - lines = 2; - Assert.Equal (new Rect (0, 0, text.RuneCount - 1, lines), TextFormatter.CalcRect (0, 0, text)); - Assert.Equal (new Rect (0, 0, text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 0)), lines), TextFormatter.CalcRect (0, 0, text)); - - text = " ~  s  gui.cs   master\n↑10"; - lines = 2; - Assert.Equal (new Rect (0, 0, ustring.Make (" ~  s  gui.cs   master\n").RuneCount - 1, lines), TextFormatter.CalcRect (0, 0, text)); - Assert.Equal (new Rect (0, 0, ustring.Make (" ~  s  gui.cs   master\n").ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 0)), lines), TextFormatter.CalcRect (0, 0, text)); + Assert.Equal (new Rect (0, 0, expectedWidth, expectedLines), TextFormatter.CalcRect (0, 0, text)); + var lines = text.Split (text.Contains (Environment.NewLine) ? Environment.NewLine : "\n"); + var maxWidth = lines.Max (s => s.GetColumns ()); + var lineWider = 0; + for (int i = 0; i < lines.Length; i++) { + var w = lines [i].GetColumns (); + if (w == maxWidth) { + lineWider = i; + } + } + Assert.Equal (new Rect (0, 0, maxWidth, expectedLines), TextFormatter.CalcRect (0, 0, text)); + Assert.Equal (new Rect (0, 0, lines [lineWider].ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 0)), expectedLines), TextFormatter.CalcRect (0, 0, text)); } - [Fact] - public void ClipAndJustify_Invalid_Returns_Original () + [Theory] + [InlineData ("")] + [InlineData (null)] + [InlineData ("test")] + public void ClipAndJustify_Invalid_Returns_Original (string text) { - var text = ustring.Empty; - - Assert.Equal (text, TextFormatter.ClipAndJustify (text, 0, TextAlignment.Left)); - - text = null; - Assert.Equal (text, TextFormatter.ClipAndJustify (text, 0, TextAlignment.Left)); - - text = "test"; + var expected = string.IsNullOrEmpty (text) ? text : ""; + Assert.Equal (expected, TextFormatter.ClipAndJustify (text, 0, TextAlignment.Left)); + Assert.Equal (expected, TextFormatter.ClipAndJustify (text, 0, TextAlignment.Left)); Assert.Throws (() => TextFormatter.ClipAndJustify (text, -1, TextAlignment.Left)); } - [Fact] - public void ClipAndJustify_Valid_Left () + [Theory] + [InlineData ("test", "", 0)] + [InlineData ("test", "te", 2)] + [InlineData ("test", "test", int.MaxValue)] + [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", int.MaxValue)] // should fit + [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit + [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit + [InlineData ("A\tsentence\thas\twords.", "A\tsentence\thas\twords.", int.MaxValue)] + [InlineData ("A\tsentence\thas\twords.", "A\tsentence", 10)] + [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)] + [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)] + [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit + [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit + public void ClipAndJustify_Valid_Left (string text, string justifiedText, int maxWidth) { var align = TextAlignment.Left; - var text = ustring.Empty; - var justifiedText = ustring.Empty; - int maxWidth = 0; - int expectedClippedWidth = 0; - - text = "test"; - maxWidth = 0; - Assert.Equal (ustring.Empty, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = 2; - Assert.Equal (text.ToRunes () [0..maxWidth], justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = int.MaxValue; - Assert.Equal (text, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - Assert.True (justifiedText.RuneCount <= maxWidth); - Assert.True (justifiedText.ConsoleWidth <= maxWidth); - - text = "A sentence has words."; - // should fit - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + var expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + Assert.True (justifiedText.GetRuneCount () <= maxWidth); + Assert.True (justifiedText.GetColumns () <= maxWidth); + Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ()); + Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))); Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Unicode - text = " ~  s  gui.cs   master ↑10"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // should fit - text = "Ð ÑÐ"; - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); + Assert.Equal (StringExtensions.ToString (justifiedText.ToRunes () [0..expectedClippedWidth]), justifiedText); } - [Fact] - public void ClipAndJustify_Valid_Right () + [Theory] + [InlineData ("test", "", 0)] + [InlineData ("test", "te", 2)] + [InlineData ("test", "test", int.MaxValue)] + [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", int.MaxValue)] // should fit + [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit + [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit + [InlineData ("A\tsentence\thas\twords.", "A\tsentence\thas\twords.", int.MaxValue)] + [InlineData ("A\tsentence\thas\twords.", "A\tsentence", 10)] + [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)] + [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)] + [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit + [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit + public void ClipAndJustify_Valid_Right (string text, string justifiedText, int maxWidth) { var align = TextAlignment.Right; - var text = ustring.Empty; - var justifiedText = ustring.Empty; - int maxWidth = 0; - int expectedClippedWidth = 0; - - text = "test"; - maxWidth = 0; - Assert.Equal (ustring.Empty, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = 2; - Assert.Equal (text.ToRunes () [0..maxWidth], justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = int.MaxValue; - Assert.Equal (text, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - Assert.True (justifiedText.RuneCount <= maxWidth); - Assert.True (justifiedText.ConsoleWidth <= maxWidth); - - text = "A sentence has words."; - // should fit - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + var expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + Assert.True (justifiedText.GetRuneCount () <= maxWidth); + Assert.True (justifiedText.GetColumns () <= maxWidth); + Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ()); + Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))); Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Unicode - text = " ~  s  gui.cs   master ↑10"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // should fit - text = "Ð ÑÐ"; - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); + Assert.Equal (StringExtensions.ToString (justifiedText.ToRunes () [0..expectedClippedWidth]), justifiedText); } - [Fact] - public void ClipAndJustify_Valid_Centered () + [Theory] + [InlineData ("test", "", 0)] + [InlineData ("test", "te", 2)] + [InlineData ("test", "test", int.MaxValue)] + [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", int.MaxValue)] // should fit + [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit + [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit + [InlineData ("A\tsentence\thas\twords.", "A\tsentence\thas\twords.", int.MaxValue)] + [InlineData ("A\tsentence\thas\twords.", "A\tsentence", 10)] + [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)] + [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)] + [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit + [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit + public void ClipAndJustify_Valid_Centered (string text, string justifiedText, int maxWidth) { var align = TextAlignment.Centered; - var text = ustring.Empty; - var justifiedText = ustring.Empty; - int maxWidth = 0; - int expectedClippedWidth = 0; - - text = "test"; - maxWidth = 0; - Assert.Equal (ustring.Empty, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = 2; - Assert.Equal (text.ToRunes () [0..maxWidth], justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = int.MaxValue; - Assert.Equal (text, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - Assert.True (justifiedText.RuneCount <= maxWidth); - Assert.True (justifiedText.ConsoleWidth <= maxWidth); - - text = "A sentence has words."; - // should fit - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + var expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + Assert.True (justifiedText.GetRuneCount () <= maxWidth); + Assert.True (justifiedText.GetColumns () <= maxWidth); + Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ()); + Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))); Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Unicode - text = " ~  s  gui.cs   master ↑10"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // should fit - text = "Ð ÑÐ"; - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); + Assert.Equal (StringExtensions.ToString (justifiedText.ToRunes () [0..expectedClippedWidth]), justifiedText); } - [Fact] - public void ClipAndJustify_Valid_Justified () + [Theory] + [InlineData ("test", "", 0)] + [InlineData ("test", "te", 2)] + [InlineData ("test", "test", int.MaxValue)] + [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit + [InlineData ("A sentence has words.", "A sentence has words.", 500)] // should fit + [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit + [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit + [InlineData ("A\tsentence\thas\twords.", "A\tsentence\thas\twords.", int.MaxValue)] + [InlineData ("A\tsentence\thas\twords.", "A\tsentence", 10)] + [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)] + [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)] + [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit + [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit + [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit + public void ClipAndJustify_Valid_Justified (string text, string justifiedText, int maxWidth) { var align = TextAlignment.Justified; - var text = ustring.Empty; - var justifiedText = ustring.Empty; - int maxWidth = 0; - int expectedClippedWidth = 0; - - text = "test"; - maxWidth = 0; - Assert.Equal (ustring.Empty, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = 2; - Assert.Equal (text.ToRunes () [0..maxWidth], justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - - text = "test"; - maxWidth = int.MaxValue; - Assert.Equal (text, justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align)); - Assert.True (justifiedText.RuneCount <= maxWidth); - - text = "A sentence has words."; - // should fit - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Max (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + var expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth); + Assert.Equal (justifiedText, TextFormatter.ClipAndJustify (text, maxWidth, align)); + Assert.True (justifiedText.GetRuneCount () <= maxWidth); + Assert.True (justifiedText.GetColumns () <= maxWidth); + Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ()); + Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))); Assert.True (expectedClippedWidth <= maxWidth); - Assert.Throws (() => ustring.Make (text.ToRunes () [0..expectedClippedWidth])); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - //Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = 500; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - //Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.True (expectedClippedWidth <= maxWidth); - //Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - //Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - //Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - //Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "A\tsentence\thas\twords."; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = int.MaxValue; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - text = "line1\nline2\nline3long!"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1))); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Unicode - text = " ~  s  gui.cs   master ↑10"; - maxWidth = 10; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // should fit - text = "Ð ÑÐ"; - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - //Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.True (expectedClippedWidth <= maxWidth); - //Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should fit. - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); - - // Should not fit - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - justifiedText = TextFormatter.ClipAndJustify (text, maxWidth, align); - Assert.Equal (expectedClippedWidth, justifiedText.RuneCount); - Assert.Equal (expectedClippedWidth, justifiedText.ConsoleWidth); - Assert.True (expectedClippedWidth <= maxWidth); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), justifiedText); + Assert.Equal (StringExtensions.ToString (justifiedText.ToRunes () [0..expectedClippedWidth]), justifiedText); // see Justify_ tests below } - [Fact] - public void Justify_Invalid () + [Theory] + [InlineData ("")] + [InlineData (null)] + [InlineData ("test")] + public void Justify_Invalid (string text) { - var text = ustring.Empty; Assert.Equal (text, TextFormatter.Justify (text, 0)); - - text = null; Assert.Equal (text, TextFormatter.Justify (text, 0)); - - text = "test"; Assert.Throws (() => TextFormatter.Justify (text, -1)); } - [Fact] - public void Justify_SingleWord () + [Theory] + [InlineData ("word")] // Even # of chars + [InlineData ("word.")] // Odd # of chars + [InlineData ("пÑивеÑ")] // Unicode (even #) + [InlineData ("пÑивеÑ.")] // Unicode (odd # of chars) + public void Justify_SingleWord (string text) { - var text = ustring.Empty; - var justifiedText = ustring.Empty; - int width = 0; + var justifiedText = text; char fillChar = '+'; - // Even # of chars - text = "word"; - justifiedText = text; - - width = text.RuneCount; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 10; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 11; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - - // Odd # of chars - text = "word."; - justifiedText = text; - - width = text.RuneCount; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 10; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 11; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - - // Unicode (even #) - text = "пÑивеÑ"; - justifiedText = text; - - width = text.RuneCount; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 10; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 11; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - - // Unicode (odd # of chars) - text = "пÑивеÑ."; - justifiedText = text; - - width = text.RuneCount; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 10; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); - width = text.RuneCount + 11; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, width, fillChar).ToString ()); + int width = text.GetRuneCount (); + Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar)); + width = text.GetRuneCount () + 1; + Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar)); + width = text.GetRuneCount () + 2; + Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar)); + width = text.GetRuneCount () + 10; + Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar)); + width = text.GetRuneCount () + 11; + Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar)); } - [Fact] - public void Justify_Sentence () + [Theory] + // Even # of spaces + // 0123456789 + [InlineData ("012 456 89", "012 456 89", 10, 0, "+", true)] + [InlineData ("012 456 89", "012++456+89", 11, 1)] + [InlineData ("012 456 89", "012 456 89", 12, 2, "++", true)] + [InlineData ("012 456 89", "012+++456++89", 13, 3)] + [InlineData ("012 456 89", "012 456 89", 14, 4, "+++", true)] + [InlineData ("012 456 89", "012++++456+++89", 15, 5)] + [InlineData ("012 456 89", "012 456 89", 16, 6, "++++", true)] + [InlineData ("012 456 89", "012 456 89", 30, 20, "+++++++++++", true)] + [InlineData ("012 456 89", "012+++++++++++++456++++++++++++89", 33, 23)] + // Odd # of spaces + // 01234567890123 + [InlineData ("012 456 89 end", "012 456 89 end", 14, 0, "+", true)] + [InlineData ("012 456 89 end", "012++456+89+end", 15, 1)] + [InlineData ("012 456 89 end", "012++456++89+end", 16, 2)] + [InlineData ("012 456 89 end", "012 456 89 end", 17, 3, "++", true)] + [InlineData ("012 456 89 end", "012+++456++89++end", 18, 4)] + [InlineData ("012 456 89 end", "012+++456+++89++end", 19, 5)] + [InlineData ("012 456 89 end", "012 456 89 end", 20, 6, "+++", true)] + [InlineData ("012 456 89 end", "012++++++++456++++++++89+++++++end", 34, 20)] + [InlineData ("012 456 89 end", "012+++++++++456+++++++++89++++++++end", 37, 23)] + // Unicode + // Even # of chars + // 0123456789 + [InlineData ("пÑРвРÑ", "пÑРвРÑ", 10, 0, "+", true)] + [InlineData ("пÑРвРÑ", "пÑÐ++вÐ+Ñ", 11, 1)] + [InlineData ("пÑРвРÑ", "пÑРвРÑ", 12, 2, "++", true)] + [InlineData ("пÑРвРÑ", "пÑÐ+++вÐ++Ñ", 13, 3)] + [InlineData ("пÑРвРÑ", "пÑРвРÑ", 14, 4, "+++", true)] + [InlineData ("пÑРвРÑ", "пÑÐ++++вÐ+++Ñ", 15, 5)] + [InlineData ("пÑРвРÑ", "пÑРвРÑ", 16, 6, "++++", true)] + [InlineData ("пÑРвРÑ", "пÑРвРÑ", 30, 20, "+++++++++++", true)] + [InlineData ("пÑРвРÑ", "пÑÐ+++++++++++++вÐ++++++++++++Ñ", 33, 23)] + // Unicode + // Odd # of chars + // 0123456789 + [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 10, 0, "+", true)] + [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ+вÐ+Ñ", 11, 1)] + [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ++вÐ+Ñ", 12, 2)] + [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 13, 3, "++", true)] + [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ++вÐ++Ñ", 14, 4)] + [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ+++вÐ++Ñ", 15, 5)] + [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 16, 6, "+++", true)] + [InlineData ("Ð ÑРвРÑ", "Ð++++++++ÑÐ++++++++вÐ+++++++Ñ", 30, 20)] + [InlineData ("Ð ÑРвРÑ", "Ð+++++++++ÑÐ+++++++++вÐ++++++++Ñ", 33, 23)] + public void Justify_Sentence (string text, string justifiedText, int forceToWidth, int widthOffset, string replaceWith = null, bool replace = false) { - var text = ustring.Empty; - var justifiedText = ustring.Empty; - int forceToWidth = 0; char fillChar = '+'; - // Even # of spaces - // 0123456789 - text = "012 456 89"; - - forceToWidth = text.RuneCount; - justifiedText = text.Replace (" ", "+"); - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012++456+89"; - forceToWidth = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "++"); - forceToWidth = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012+++456++89"; - forceToWidth = text.RuneCount + 3; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "+++"); - forceToWidth = text.RuneCount + 4; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012++++456+++89"; - forceToWidth = text.RuneCount + 5; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "++++"); - forceToWidth = text.RuneCount + 6; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "+++++++++++"); - forceToWidth = text.RuneCount + 20; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012+++++++++++++456++++++++++++89"; - forceToWidth = text.RuneCount + 23; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - // Odd # of spaces - // 0123456789 - text = "012 456 89 end"; - - forceToWidth = text.RuneCount; - justifiedText = text.Replace (" ", "+"); - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012++456+89+end"; - forceToWidth = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012++456++89+end"; - forceToWidth = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "++"); - forceToWidth = text.RuneCount + 3; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012+++456++89++end"; - forceToWidth = text.RuneCount + 4; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012+++456+++89++end"; - forceToWidth = text.RuneCount + 5; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "+++"); - forceToWidth = text.RuneCount + 6; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012++++++++456++++++++89+++++++end"; - forceToWidth = text.RuneCount + 20; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "012+++++++++456+++++++++89++++++++end"; - forceToWidth = text.RuneCount + 23; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - // Unicode - // Even # of chars - // 0123456789 - text = "пÑРвРÑ"; - - forceToWidth = text.RuneCount; - justifiedText = text.Replace (" ", "+"); - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "пÑÐ++вÐ+Ñ"; - forceToWidth = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "++"); - forceToWidth = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "пÑÐ+++вÐ++Ñ"; - forceToWidth = text.RuneCount + 3; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "+++"); - forceToWidth = text.RuneCount + 4; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "пÑÐ++++вÐ+++Ñ"; - forceToWidth = text.RuneCount + 5; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "++++"); - forceToWidth = text.RuneCount + 6; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "+++++++++++"); - forceToWidth = text.RuneCount + 20; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "пÑÐ+++++++++++++вÐ++++++++++++Ñ"; - forceToWidth = text.RuneCount + 23; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - // Unicode - // Odd # of chars - // 0123456789 - text = "Ð ÑРвРÑ"; - - forceToWidth = text.RuneCount; - justifiedText = text.Replace (" ", "+"); - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "Ð++ÑÐ+вÐ+Ñ"; - forceToWidth = text.RuneCount + 1; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "Ð++ÑÐ++вÐ+Ñ"; - forceToWidth = text.RuneCount + 2; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "++"); - forceToWidth = text.RuneCount + 3; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "Ð+++ÑÐ++вÐ++Ñ"; - forceToWidth = text.RuneCount + 4; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "Ð+++ÑÐ+++вÐ++Ñ"; - forceToWidth = text.RuneCount + 5; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = text.Replace (" ", "+++"); - forceToWidth = text.RuneCount + 6; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "Ð++++++++ÑÐ++++++++вÐ+++++++Ñ"; - forceToWidth = text.RuneCount + 20; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); - - justifiedText = "Ð+++++++++ÑÐ+++++++++вÐ++++++++Ñ"; - forceToWidth = text.RuneCount + 23; - Assert.Equal (justifiedText.ToString (), TextFormatter.Justify (text, forceToWidth, fillChar).ToString ()); - Assert.True (Math.Abs (forceToWidth - justifiedText.RuneCount) < text.Count (" ")); - Assert.True (Math.Abs (forceToWidth - justifiedText.ConsoleWidth) < text.Count (" ")); + Assert.Equal (forceToWidth, text.GetRuneCount () + widthOffset); + if (replace) { + justifiedText = text.Replace (" ", replaceWith); + } + Assert.Equal (justifiedText, TextFormatter.Justify (text, forceToWidth, fillChar)); + Assert.True (Math.Abs (forceToWidth - justifiedText.GetRuneCount ()) < text.Count (s => s == ' ')); + Assert.True (Math.Abs (forceToWidth - justifiedText.GetColumns ()) < text.Count (s => s == ' ')); } [Fact] public void WordWrap_Invalid () { - var text = ustring.Empty; + var text = string.Empty; int width = 0; Assert.Empty (TextFormatter.WordWrapText (null, width)); @@ -1542,769 +596,240 @@ namespace Terminal.Gui.TextTests { [Fact] public void WordWrap_BigWidth () { - List wrappedLines; + List wrappedLines; var text = "Constantinople"; wrappedLines = TextFormatter.WordWrapText (text, 100); Assert.True (wrappedLines.Count == 1); - Assert.Equal ("Constantinople", wrappedLines [0].ToString ()); + Assert.Equal ("Constantinople", wrappedLines [0]); } - [Fact] - public void WordWrap_SingleWordLine () + [Theory] + [InlineData ("Constantinople", 14, 0, new string [] { "Constantinople" })] + [InlineData ("Constantinople", 12, -2, new string [] { "Constantinop", "le" })] + [InlineData ("Constantinople", 9, -5, new string [] { "Constanti", "nople" })] + [InlineData ("Constantinople", 7, -7, new string [] { "Constan", "tinople" })] + [InlineData ("Constantinople", 5, -9, new string [] { "Const", "antin", "ople" })] + [InlineData ("Constantinople", 4, -10, new string [] { "Cons", "tant", "inop", "le" })] + [InlineData ("Constantinople", 1, -13, new string [] { "C", "o", "n", "s", "t", "a", "n", "t", "i", "n", "o", "p", "l", "e" })] + public void WordWrap_SingleWordLine (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { - var text = ustring.Empty; - int width = 0; - List wrappedLines; + List wrappedLines; - text = "Constantinople"; - width = text.RuneCount; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.True (wrappedLines.Count == 1); - - width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal (text [0, text.RuneCount - 1].ToString (), wrappedLines [0].ToString ()); - Assert.Equal ("e", wrappedLines [1].ToString ()); - - width = text.RuneCount - 2; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal (text [0, text.RuneCount - 2].ToString (), wrappedLines [0].ToString ()); - - width = text.RuneCount - 5; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 2F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal ("Constan", wrappedLines [0].ToString ()); - Assert.Equal ("tinople", wrappedLines [1].ToString ()); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 3F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (3, wrappedLines.Count); - Assert.Equal ("Const", wrappedLines [0].ToString ()); - Assert.Equal ("antin", wrappedLines [1].ToString ()); - Assert.Equal ("ople", wrappedLines [2].ToString ()); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 4F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (4, wrappedLines.Count); - - width = (int)Math.Ceiling ((double)text.RuneCount / text.RuneCount); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (text.RuneCount, wrappedLines.Count); - Assert.Equal (text.ConsoleWidth, wrappedLines.Count); - Assert.Equal ("C", wrappedLines [0].ToString ()); - Assert.Equal ("o", wrappedLines [1].ToString ()); - Assert.Equal ("n", wrappedLines [2].ToString ()); - Assert.Equal ("s", wrappedLines [3].ToString ()); - Assert.Equal ("t", wrappedLines [4].ToString ()); - Assert.Equal ("a", wrappedLines [5].ToString ()); - Assert.Equal ("n", wrappedLines [6].ToString ()); - Assert.Equal ("t", wrappedLines [7].ToString ()); - Assert.Equal ("i", wrappedLines [8].ToString ()); - Assert.Equal ("n", wrappedLines [9].ToString ()); - Assert.Equal ("o", wrappedLines [10].ToString ()); - Assert.Equal ("p", wrappedLines [11].ToString ()); - Assert.Equal ("l", wrappedLines [12].ToString ()); - Assert.Equal ("e", wrappedLines [13].ToString ()); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void WordWrap_Unicode_SingleWordLine () + [Theory] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 51, 0, new string [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" })] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 50, -1, new string [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัา", "ำ" })] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 46, -5, new string [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ", "ฯะัาำ" })] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 26, -25, new string [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" })] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 17, -34, new string [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑ", "ฒณดตถทธนบปผฝพฟภมย", "รฤลฦวศษสหฬอฮฯะัาำ" })] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 13, -38, new string [] { "กขฃคฅฆงจฉชซฌญ", "ฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦว", "ศษสหฬอฮฯะัาำ" })] + [InlineData ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", 1, -50, new string [] { "ก", "ข", "ฃ", "ค", "ฅ", "ฆ", "ง", "จ", "ฉ", "ช", "ซ", "ฌ", "ญ", "ฎ", "ฏ", "ฐ", "ฑ", "ฒ", "ณ", "ด", "ต", "ถ", "ท", "ธ", "น", "บ", "ป", "ผ", "ฝ", "พ", "ฟ", "ภ", "ม", "ย", "ร", "ฤ", "ล", "ฦ", "ว", "ศ", "ษ", "ส", "ห", "ฬ", "อ", "ฮ", "ฯ", "ะ", "ั", "า", "ำ" })] + public void WordWrap_Unicode_SingleWordLine (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { - var text = ustring.Empty; - int width = 0; - List wrappedLines; + List wrappedLines; - text = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ"; - width = text.RuneCount; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.True (wrappedLines.Count == 1); - - width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.RuneCount - 1)]).ToString (), wrappedLines [0].ToString ()); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)) - 1)]).ToString (), wrappedLines [0].ToString ()); - Assert.Equal ("ำ", wrappedLines [1].ToString ()); - - width = text.RuneCount - 2; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.RuneCount - 2)]).ToString (), wrappedLines [0].ToString ()); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)) - 2)]).ToString (), wrappedLines [0].ToString ()); - - width = text.RuneCount - 5; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 2F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal ("กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบ", wrappedLines [0].ToString ()); - Assert.Equal ("ปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ", wrappedLines [1].ToString ()); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 3F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (3, wrappedLines.Count); - Assert.Equal ("กขฃคฅฆงจฉชซฌญฎฏฐฑ", wrappedLines [0].ToString ()); - Assert.Equal ("ฒณดตถทธนบปผฝพฟภมย", wrappedLines [1].ToString ()); - Assert.Equal ("รฤลฦวศษสหฬอฮฯะัาำ", wrappedLines [2].ToString ()); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 4F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (4, wrappedLines.Count); - - width = (int)Math.Ceiling ((double)text.RuneCount / text.RuneCount); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (text.RuneCount, wrappedLines.Count); - Assert.Equal (text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)), wrappedLines.Count); - Assert.Equal ("ก", wrappedLines [0].ToString ()); - Assert.Equal ("ข", wrappedLines [1].ToString ()); - Assert.Equal ("ฃ", wrappedLines [2].ToString ()); - Assert.Equal ("ำ", wrappedLines [^1].ToString ()); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void WordWrap_Unicode_LineWithNonBreakingSpace () + [Theory] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 19, 0, new string [] { "This\u00A0is\u00A0a\u00A0sentence." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 18, -1, new string [] { "This\u00A0is\u00A0a\u00A0sentence", "." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 17, -2, new string [] { "This\u00A0is\u00A0a\u00A0sentenc", "e." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 14, -5, new string [] { "This\u00A0is\u00A0a\u00A0sent", "ence." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 10, -9, new string [] { "This\u00A0is\u00A0a\u00A0", "sentence." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 7, -12, new string [] { "This\u00A0is", "\u00A0a\u00A0sent", "ence." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 5, -14, new string [] { "This\u00A0", "is\u00A0a\u00A0", "sente", "nce." })] + [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 1, -18, new string [] { "T", "h", "i", "s", "\u00A0", "i", "s", "\u00A0", "a", "\u00A0", "s", "e", "n", "t", "e", "n", "c", "e", "." })] + public void WordWrap_Unicode_LineWithNonBreakingSpace (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { - var text = ustring.Empty; - int width = 0; - List wrappedLines; + List wrappedLines; - text = "This\u00A0is\u00A0a\u00A0sentence."; - width = text.RuneCount; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.True (wrappedLines.Count == 1); - - width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.RuneCount - 1)]).ToString (), wrappedLines [0].ToString ()); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)) - 1)]).ToString (), wrappedLines [0].ToString ()); - Assert.Equal (".", wrappedLines [1].ToString ()); - - width = text.RuneCount - 2; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.RuneCount - 2)]).ToString (), wrappedLines [0].ToString ()); - Assert.Equal (ustring.Make (text.ToRunes () [0..(text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)) - 2)]).ToString (), wrappedLines [0].ToString ()); - - width = text.RuneCount - 5; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 2F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (2, wrappedLines.Count); - Assert.Equal ("This\u00A0is\u00A0a\u00A0", wrappedLines [0].ToString ()); - Assert.Equal ("sentence.", wrappedLines [1].ToString ()); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 3F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (3, wrappedLines.Count); - Assert.Equal ("This\u00A0is", wrappedLines [0].ToString ()); - Assert.Equal ("\u00a0a\u00a0sent", wrappedLines [1].ToString ()); - Assert.Equal ("ence.", wrappedLines [2].ToString ()); - - width = (int)Math.Ceiling ((double)(text.RuneCount / 4F)); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (4, wrappedLines.Count); - - width = (int)Math.Ceiling ((double)text.RuneCount / text.RuneCount); - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (text.RuneCount, wrappedLines.Count); - Assert.Equal (text.ToRuneList ().Sum (r => Math.Max (Rune.ColumnWidth (r), 1)), wrappedLines.Count); - Assert.Equal ("T", wrappedLines [0].ToString ()); - Assert.Equal ("h", wrappedLines [1].ToString ()); - Assert.Equal ("i", wrappedLines [2].ToString ()); - Assert.Equal (".", wrappedLines [^1].ToString ()); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void WordWrap_Unicode_2LinesWithNonBreakingSpace () + [Theory] + [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 20, 0, new string [] { "This\u00A0is\u00A0a\u00A0sentence." })] + [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 19, -1, new string [] { "This\u00A0is\u00A0a\u00A0sentence." })] + [InlineData ("\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence.", 19, 0, new string [] { "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence." })] + public void WordWrap_Unicode_2LinesWithNonBreakingSpace (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { - var text = ustring.Empty; - int width = 0; - List wrappedLines; + List wrappedLines; - text = "This\u00A0is\n\u00A0a\u00A0sentence."; - width = text.RuneCount; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.True (wrappedLines.Count == 1); - - width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrapText (text, width); -#pragma warning disable xUnit2013 // Do not use equality check to check for collection size. - Assert.Equal (1, wrappedLines.Count); -#pragma warning restore xUnit2013 // Do not use equality check to check for collection size. - Assert.Equal ("This\u00A0is\u00A0a\u00A0sentence.", wrappedLines [0].ToString ()); - - text = "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence."; - width = text.RuneCount; - wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.True (wrappedLines.Count == 1); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void WordWrap_NoNewLines_Default () + [Theory] + [InlineData ("A sentence has words.", 21, 0, new string [] { "A sentence has words." })] + [InlineData ("A sentence has words.", 20, -1, new string [] { "A sentence has", "words." })] + [InlineData ("A sentence has words.", 15, -6, new string [] { "A sentence has", "words." })] + [InlineData ("A sentence has words.", 14, -7, new string [] { "A sentence has", "words." })] + [InlineData ("A sentence has words.", 13, -8, new string [] { "A sentence", "has words." })] + // Unicode + [InlineData ("A Unicode sentence (пÑивеÑ) has words.", 42, 0, new string [] { "A Unicode sentence (пÑивеÑ) has words." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.", 41, -1, new string [] { "A Unicode sentence (пÑивеÑ) has", "words." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.", 36, -6, new string [] { "A Unicode sentence (пÑивеÑ) has", "words." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.", 35, -7, new string [] { "A Unicode sentence (пÑивеÑ) has", "words." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.", 34, -8, new string [] { "A Unicode sentence (пÑивеÑ)", "has words." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.", 25, -17, new string [] { "A Unicode sentence", "(пÑивеÑ) has words." })] + public void WordWrap_NoNewLines_Default (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false - var text = ustring.Empty; - int maxWidth = 0; - int expectedClippedWidth = 0; + List wrappedLines; - List wrappedLines; - - text = "A sentence has words."; - maxWidth = text.RuneCount; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.True (wrappedLines.Count == 1); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence has words.", wrappedLines [0].ToString ()); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence has", wrappedLines [0].ToString ()); - Assert.Equal ("words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence has", wrappedLines [0].ToString ()); - Assert.Equal ("words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - " words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence has", wrappedLines [0].ToString ()); - Assert.Equal ("words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "s words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence", wrappedLines [0].ToString ()); - Assert.Equal ("has words.", wrappedLines [1].ToString ()); - - // Unicode - text = "A Unicode sentence (пÑивеÑ) has words."; - maxWidth = text.RuneCount; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.True (wrappedLines.Count == 1); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has words.", wrappedLines [0].ToString ()); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has", wrappedLines [0].ToString ()); - Assert.Equal ("words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has", wrappedLines [0].ToString ()); - Assert.Equal ("words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - " words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has", wrappedLines [0].ToString ()); - Assert.Equal ("words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "s words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ)", wrappedLines [0].ToString ()); - Assert.Equal ("has words.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "веÑ) has words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence", wrappedLines [0].ToString ()); - Assert.Equal ("(пÑивеÑ) has words.", wrappedLines [1].ToString ()); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } /// /// WordWrap strips CRLF /// - [Fact] - public void WordWrap_WithNewLines () + [Theory] + [InlineData ("A sentence has words.\nA paragraph has lines.", 44, 0, new string [] { "A sentence has words.A paragraph has lines." })] + [InlineData ("A sentence has words.\nA paragraph has lines.", 43, -1, new string [] { "A sentence has words.A paragraph has lines." })] + [InlineData ("A sentence has words.\nA paragraph has lines.", 38, -6, new string [] { "A sentence has words.A paragraph has", "lines." })] + [InlineData ("A sentence has words.\nA paragraph has lines.", 34, -10, new string [] { "A sentence has words.A paragraph", "has lines." })] + [InlineData ("A sentence has words.\nA paragraph has lines.", 27, -17, new string [] { "A sentence has words.A", "paragraph has lines." })] + // Unicode + [InlineData ("A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.", 69, 0, new string [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.", 68, -1, new string [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.", 63, -6, new string [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has", "Линии." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.", 59, -10, new string [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт", "has Линии." })] + [InlineData ("A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.", 52, -17, new string [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode", "Пункт has Линии." })] + public void WordWrap_WithNewLines (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { - var text = ustring.Empty; - int maxWidth = 0; - int expectedClippedWidth = 0; + List wrappedLines; - List wrappedLines; - - text = "A sentence has words.\nA paragraph has lines."; - maxWidth = text.RuneCount; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); wrappedLines = TextFormatter.WordWrapText (text, maxWidth); -#pragma warning disable xUnit2013 // Do not use equality check to check for collection size. - Assert.Equal (1, wrappedLines.Count); -#pragma warning restore xUnit2013 // Do not use equality check to check for collection size. - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.Equal ("A sentence has words.A paragraph has lines.", wrappedLines [0].ToString ()); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); -#pragma warning disable xUnit2013 // Do not use equality check to check for collection size. - Assert.Equal (1, wrappedLines.Count); -#pragma warning restore xUnit2013 // Do not use equality check to check for collection size. - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence has words.A paragraph has lines.", wrappedLines [0].ToString ()); - - maxWidth = text.RuneCount - "words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence has words.A paragraph has", wrappedLines [0].ToString ()); - Assert.Equal ("lines.", wrappedLines [1].ToString ()); - - // Unicode - text = "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии."; - maxWidth = text.RuneCount; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.True (wrappedLines.Count == 1); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии.", wrappedLines [0].ToString ()); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has", wrappedLines [0].ToString ()); - Assert.Equal ("Линии.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has", wrappedLines [0].ToString ()); - Assert.Equal ("Линии.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "s words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт", wrappedLines [0].ToString ()); - Assert.Equal ("has Линии.", wrappedLines [1].ToString ()); - - maxWidth = text.RuneCount - "веÑ) has words.".Length; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.Equal (2, wrappedLines.Count); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A Unicode sentence (пÑивеÑ) has words.A Unicode", wrappedLines [0].ToString ()); - Assert.Equal ("Пункт has Линии.", wrappedLines [1].ToString ()); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void WordWrap_Narrow_Default () + [Theory] + [InlineData ("A sentence has words.", 3, -18, new string [] { "A", "sen", "ten", "ce", "has", "wor", "ds." })] + [InlineData ("A sentence has words.", 2, -19, new string [] { "A", "se", "nt", "en", "ce", "ha", "s", "wo", "rd", "s." })] + [InlineData ("A sentence has words.", 1, -20, new string [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." })] + public void WordWrap_Narrow_Default (string text, int maxWidth, int widthOffset, IEnumerable resultLines) { // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false - var text = ustring.Empty; - int maxWidth = 1; - int expectedClippedWidth = 1; + List wrappedLines; - List wrappedLines; - - text = "A sentence has words."; - maxWidth = 3; - expectedClippedWidth = 3; + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A", wrappedLines [0].ToString ()); - Assert.Equal ("sen", wrappedLines [1].ToString ()); - Assert.Equal ("ten", wrappedLines [2].ToString ()); - Assert.Equal ("ce", wrappedLines [3].ToString ()); - Assert.Equal ("has", wrappedLines [4].ToString ()); - Assert.Equal ("wor", wrappedLines [5].ToString ()); - Assert.Equal ("ds.", wrappedLines [6].ToString ()); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); + } - maxWidth = 2; - expectedClippedWidth = 2; + [Theory] + [InlineData ("A sentence has words.", 14, -7, new string [] { "A sentence ", "has words." })] + [InlineData ("A sentence has words.", 8, -13, new string [] { "A ", "sentence", " has ", "words." })] + [InlineData ("A sentence has words.", 6, -15, new string [] { "A ", "senten", "ce ", "has ", "words." })] + [InlineData ("A sentence has words.", 3, -18, new string [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds." })] + [InlineData ("A sentence has words.", 2, -19, new string [] { "A ", "se", "nt", "en", "ce", " ", "ha", "s ", "wo", "rd", "s." })] + [InlineData ("A sentence has words.", 1, -20, new string [] { "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", " ", "w", "o", "r", "d", "s", "." })] + public void WordWrap_PreserveTrailingSpaces_True (string text, int maxWidth, int widthOffset, IEnumerable resultLines) + { + List wrappedLines; + + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth, preserveTrailingSpaces: true); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); + } + + [Theory] + [InlineData ("文に は言葉 があり ます。", 14, 0, new string [] { "文に は言葉 ", "があり ます。" })] + [InlineData ("文に は言葉 があり ます。", 3, -11, new string [] { "文", "に ", "は", "言", "葉 ", "が", "あ", "り ", "ま", "す", "。" })] + [InlineData ("文に は言葉 があり ます。", 2, -12, new string [] { "文", "に", " ", "は", "言", "葉", " ", "が", "あ", "り", " ", "ま", "す", "。" })] + [InlineData ("文に は言葉 があり ます。", 1, -13, new string [] { })] + public void WordWrap_PreserveTrailingSpaces_True_Wide_Runes (string text, int maxWidth, int widthOffset, IEnumerable resultLines) + { + List wrappedLines; + + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth, preserveTrailingSpaces: true); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); + } + + [Theory] + [InlineData ("文に は言葉 があり ます。", 14, 0, new string [] { "文に は言葉", "があり ます。" })] + [InlineData ("文に は言葉 があり ます。", 3, -11, new string [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })] + [InlineData ("文に は言葉 があり ます。", 2, -12, new string [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })] + [InlineData ("文に は言葉 があり ます。", 1, -13, new string [] { })] + public void WordWrap_PreserveTrailingSpaces_False_Wide_Runes (string text, int maxWidth, int widthOffset, IEnumerable resultLines) + { + List wrappedLines; + + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A", wrappedLines [0].ToString ()); - Assert.Equal ("se", wrappedLines [1].ToString ()); - Assert.Equal ("nt", wrappedLines [2].ToString ()); - Assert.Equal ("en", wrappedLines [3].ToString ()); - Assert.Equal ("s.", wrappedLines [^1].ToString ()); - - maxWidth = 1; - expectedClippedWidth = 1; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A", wrappedLines [0].ToString ()); - Assert.Equal ("s", wrappedLines [1].ToString ()); - Assert.Equal ("e", wrappedLines [2].ToString ()); - Assert.Equal ("n", wrappedLines [3].ToString ()); - Assert.Equal (".", wrappedLines [^1].ToString ()); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void WordWrap_PreserveTrailingSpaces_True () + [Theory] + [InlineData ("A sentence has words. ", 3, new string [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds.", " " })] + [InlineData ("A sentence has words. ", 3, new string [] { "A ", " ", "sen", "ten", "ce ", " ", " ", " ", "has", " ", "wor", "ds.", " " })] + public void WordWrap_PreserveTrailingSpaces_True_With_Simple_Runes_Width_3 (string text, int width, IEnumerable resultLines) { - var text = ustring.Empty; - int maxWidth = 1; - int expectedClippedWidth = 1; - - List wrappedLines; - - text = "A sentence has words."; - maxWidth = 14; - expectedClippedWidth = 14; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A sentence ", wrappedLines [0].ToString ()); - Assert.Equal ("has words.", wrappedLines [1].ToString ()); - Assert.True (wrappedLines.Count == 2); - - maxWidth = 8; - expectedClippedWidth = 8; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("sentence", wrappedLines [1].ToString ()); - Assert.Equal (" has ", wrappedLines [2].ToString ()); - Assert.Equal ("words.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 4); - - maxWidth = 6; - expectedClippedWidth = 6; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("senten", wrappedLines [1].ToString ()); - Assert.Equal ("ce ", wrappedLines [2].ToString ()); - Assert.Equal ("has ", wrappedLines [3].ToString ()); - Assert.Equal ("words.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 5); - - maxWidth = 3; - expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("sen", wrappedLines [1].ToString ()); - Assert.Equal ("ten", wrappedLines [2].ToString ()); - Assert.Equal ("ce ", wrappedLines [3].ToString ()); - Assert.Equal ("has", wrappedLines [4].ToString ()); - Assert.Equal (" ", wrappedLines [5].ToString ()); - Assert.Equal ("wor", wrappedLines [6].ToString ()); - Assert.Equal ("ds.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 8); - - maxWidth = 2; - expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("se", wrappedLines [1].ToString ()); - Assert.Equal ("nt", wrappedLines [2].ToString ()); - Assert.Equal ("en", wrappedLines [3].ToString ()); - Assert.Equal ("ce", wrappedLines [4].ToString ()); - Assert.Equal (" ", wrappedLines [5].ToString ()); - Assert.Equal ("ha", wrappedLines [6].ToString ()); - Assert.Equal ("s ", wrappedLines [7].ToString ()); - Assert.Equal ("wo", wrappedLines [8].ToString ()); - Assert.Equal ("rd", wrappedLines [9].ToString ()); - Assert.Equal ("s.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 11); - - maxWidth = 1; - expectedClippedWidth = 1; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("A", wrappedLines [0].ToString ()); - Assert.Equal (" ", wrappedLines [1].ToString ()); - Assert.Equal ("s", wrappedLines [2].ToString ()); - Assert.Equal ("e", wrappedLines [3].ToString ()); - Assert.Equal ("n", wrappedLines [4].ToString ()); - Assert.Equal ("t", wrappedLines [5].ToString ()); - Assert.Equal ("e", wrappedLines [6].ToString ()); - Assert.Equal ("n", wrappedLines [7].ToString ()); - Assert.Equal ("c", wrappedLines [8].ToString ()); - Assert.Equal ("e", wrappedLines [9].ToString ()); - Assert.Equal (" ", wrappedLines [10].ToString ()); - Assert.Equal (".", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == text.Length); - } - - [Fact] - public void WordWrap_PreserveTrailingSpaces_True_Wide_Runes () - { - var text = ustring.Empty; - int maxWidth = 1; - int expectedClippedWidth = 1; - - List wrappedLines; - - text = "文に は言葉 があり ます。"; - maxWidth = 14; - expectedClippedWidth = 14; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("文に は言葉 ", wrappedLines [0].ToString ()); - Assert.Equal ("があり ます。", wrappedLines [1].ToString ()); - Assert.True (wrappedLines.Count == 2); - - maxWidth = 3; - expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("文", wrappedLines [0].ToString ()); - Assert.Equal ("に ", wrappedLines [1].ToString ()); - Assert.Equal ("は", wrappedLines [2].ToString ()); - Assert.Equal ("言", wrappedLines [3].ToString ()); - Assert.Equal ("葉 ", wrappedLines [4].ToString ()); - Assert.Equal ("が", wrappedLines [5].ToString ()); - Assert.Equal ("あ", wrappedLines [6].ToString ()); - Assert.Equal ("り ", wrappedLines [7].ToString ()); - Assert.Equal ("ま", wrappedLines [8].ToString ()); - Assert.Equal ("す", wrappedLines [9].ToString ()); - Assert.Equal ("。", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 11); - - maxWidth = 2; - expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("文", wrappedLines [0].ToString ()); - Assert.Equal ("に", wrappedLines [1].ToString ()); - Assert.Equal (" ", wrappedLines [2].ToString ()); - Assert.Equal ("は", wrappedLines [3].ToString ()); - Assert.Equal ("言", wrappedLines [4].ToString ()); - Assert.Equal ("葉", wrappedLines [5].ToString ()); - Assert.Equal (" ", wrappedLines [6].ToString ()); - Assert.Equal ("が", wrappedLines [7].ToString ()); - Assert.Equal ("あ", wrappedLines [8].ToString ()); - Assert.Equal ("り", wrappedLines [9].ToString ()); - Assert.Equal (" ", wrappedLines [10].ToString ()); - Assert.Equal ("ま", wrappedLines [11].ToString ()); - Assert.Equal ("す", wrappedLines [12].ToString ()); - Assert.Equal ("。", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 14); - - maxWidth = 1; - expectedClippedWidth = 0; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.Empty (wrappedLines); - Assert.False (wrappedLines.Count == text.Length); - Assert.False (wrappedLines.Count == text.RuneCount); - Assert.False (wrappedLines.Count == text.ConsoleWidth); - Assert.Equal (25, text.ConsoleWidth); - Assert.Equal (25, TextFormatter.GetTextWidth (text)); - } - - [Fact] - public void WordWrap_PreserveTrailingSpaces_False_Wide_Runes () - { - var text = ustring.Empty; - int maxWidth = 1; - int expectedClippedWidth = 1; - - List wrappedLines; - - text = "文に は言葉 があり ます。"; - maxWidth = 14; - expectedClippedWidth = 14; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("文に は言葉 ", wrappedLines [0].ToString ()); - Assert.Equal ("があり ます。", wrappedLines [1].ToString ()); - Assert.True (wrappedLines.Count == 2); - - maxWidth = 3; - expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("文", wrappedLines [0].ToString ()); - Assert.Equal ("に ", wrappedLines [1].ToString ()); - Assert.Equal ("は", wrappedLines [2].ToString ()); - Assert.Equal ("言", wrappedLines [3].ToString ()); - Assert.Equal ("葉 ", wrappedLines [4].ToString ()); - Assert.Equal ("が", wrappedLines [5].ToString ()); - Assert.Equal ("あ", wrappedLines [6].ToString ()); - Assert.Equal ("り ", wrappedLines [7].ToString ()); - Assert.Equal ("ま", wrappedLines [8].ToString ()); - Assert.Equal ("す", wrappedLines [9].ToString ()); - Assert.Equal ("。", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 11); - - maxWidth = 2; - expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - Assert.Equal ("文", wrappedLines [0].ToString ()); - Assert.Equal ("に", wrappedLines [1].ToString ()); - Assert.Equal (" ", wrappedLines [2].ToString ()); - Assert.Equal ("は", wrappedLines [3].ToString ()); - Assert.Equal ("言", wrappedLines [4].ToString ()); - Assert.Equal ("葉", wrappedLines [5].ToString ()); - Assert.Equal (" ", wrappedLines [6].ToString ()); - Assert.Equal ("が", wrappedLines [7].ToString ()); - Assert.Equal ("あ", wrappedLines [8].ToString ()); - Assert.Equal ("り", wrappedLines [9].ToString ()); - Assert.Equal (" ", wrappedLines [10].ToString ()); - Assert.Equal ("ま", wrappedLines [11].ToString ()); - Assert.Equal ("す", wrappedLines [12].ToString ()); - Assert.Equal ("。", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 14); - - maxWidth = 1; - expectedClippedWidth = 0; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); - Assert.Empty (wrappedLines); - Assert.False (wrappedLines.Count == text.Length); - Assert.False (wrappedLines.Count == text.RuneCount); - Assert.False (wrappedLines.Count == text.ConsoleWidth); - Assert.Equal (25, text.ConsoleWidth); - Assert.Equal (25, TextFormatter.GetTextWidth (text)); - //var text = ustring.Empty; - //int maxWidth = 1; - //int expectedClippedWidth = 1; - - //List wrappedLines; - - //text = "文に は言葉 があり ます。"; - //maxWidth = 14; - //expectedClippedWidth = 14; - //wrappedLines = TextFormatter.WordWrapText (text, maxWidth, false); - //Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - //Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - //Assert.Equal ("文に は言葉", wrappedLines [0].ToString ()); - //Assert.Equal ("があり ます。", wrappedLines [1].ToString ()); - //Assert.True (wrappedLines.Count == 2); - - //maxWidth = 3; - //expectedClippedWidth = 3; - //wrappedLines = TextFormatter.WordWrapText (text, maxWidth, false); - //Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - //Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - //Assert.Equal ("文 ", wrappedLines [0]); - //Assert.Equal ("に ", wrappedLines [1]); - //Assert.Equal ("は ", wrappedLines [2]); - //Assert.Equal ("言 ", wrappedLines [3]); - //Assert.Equal ("葉 ", wrappedLines [4]); - //Assert.Equal ("が ", wrappedLines [5]); - //Assert.Equal ("あ ", wrappedLines [6]); - //Assert.Equal ("り ", wrappedLines [7]); - //Assert.Equal ("ま ", wrappedLines [8]); - //Assert.Equal ("す ", wrappedLines [9]); - //Assert.Equal ("。", wrappedLines [^1]); - //Assert.Equal (11, wrappedLines.Count); - - //maxWidth = 2; - //expectedClippedWidth = 2; - //wrappedLines = TextFormatter.WordWrapText (text, maxWidth, false); - //Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - //Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.ConsoleWidth)); - //Assert.Equal ("文", wrappedLines [0].ToString ()); - //Assert.Equal ("に", wrappedLines [1].ToString ()); - //Assert.Equal ("は", wrappedLines [2].ToString ()); - //Assert.Equal ("言", wrappedLines [3].ToString ()); - //Assert.Equal ("葉", wrappedLines [4].ToString ()); - //Assert.Equal ("が", wrappedLines [5].ToString ()); - //Assert.Equal ("あ", wrappedLines [6].ToString ()); - //Assert.Equal ("り", wrappedLines [7].ToString ()); - //Assert.Equal ("ま", wrappedLines [8].ToString ()); - //Assert.Equal ("す", wrappedLines [9].ToString ()); - //Assert.Equal ("。", wrappedLines [^1].ToString ()); - //Assert.Equal (11, wrappedLines.Count); - - //maxWidth = 1; - //expectedClippedWidth = 0; - //wrappedLines = TextFormatter.WordWrapText (text, maxWidth, false); - //Assert.Empty (wrappedLines); - } - - [Fact] - public void WordWrap_PreserveTrailingSpaces_True_With_Simple_Runes_Width_3 () - { - var text = "A sentence has words. "; - var width = 3; var wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: true); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.Equal (resultLines, wrappedLines); var breakLines = ""; foreach (var line in wrappedLines) { breakLines += $"{line}{Environment.NewLine}"; } - var expected = "A " + Environment.NewLine + - "sen" + Environment.NewLine + - "ten" + Environment.NewLine + - "ce " + Environment.NewLine + - "has" + Environment.NewLine + - " " + Environment.NewLine + - "wor" + Environment.NewLine + - "ds." + Environment.NewLine + - " " + Environment.NewLine; + var expected = string.Empty; + foreach (var line in resultLines) { + expected += $"{line}{Environment.NewLine}"; + } Assert.Equal (expected, breakLines); // Double space Complex example - this is how VS 2022 does it @@ -2330,1309 +855,347 @@ namespace Terminal.Gui.TextTests { //Assert.Equal (expected, breakLines); } - [Fact] - public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_1 () + [Theory] + [InlineData (null, 1, new string [] { })] // null input + [InlineData ("", 1, new string [] { })] // Empty input + [InlineData ("1 34", 1, new string [] { "1", "3", "4" })] // Single Spaces + [InlineData ("1", 1, new string [] { "1" })] // Short input + [InlineData ("12", 1, new string [] { "1", "2" })] + [InlineData ("123", 1, new string [] { "1", "2", "3" })] + [InlineData ("123456", 1, new string [] { "1", "2", "3", "4", "5", "6" })] // No spaces + [InlineData (" ", 1, new string [] { " " })] // Just Spaces; should result in a single space + [InlineData (" ", 1, new string [] { " " })] + [InlineData (" ", 1, new string [] { " ", " " })] + [InlineData (" ", 1, new string [] { " ", " " })] + [InlineData ("12 456", 1, new string [] { "1", "2", "4", "5", "6" })] // Single Spaces + [InlineData (" 2 456", 1, new string [] { " ", "2", "4", "5", "6" })] // Leading spaces should be preserved. + [InlineData (" 2 456 8", 1, new string [] { " ", "2", "4", "5", "6", "8" })] + [InlineData ("A sentence has words. ", 1, new string [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." })] // Complex example + [InlineData ("12 567", 1, new string [] { "1", "2", " ", "5", "6", "7" })] // Double Spaces + [InlineData (" 3 567", 1, new string [] { " ", "3", "5", "6", "7" })] // Double Leading spaces should be preserved. + [InlineData (" 3 678 1", 1, new string [] { " ", "3", " ", "6", "7", "8", " ", "1" })] + [InlineData ("1 456", 1, new string [] { "1", " ", "4", "5", "6" })] + [InlineData ("A sentence has words. ", 1, new string [] { "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", "w", "o", "r", "d", "s", ".", " " })] // Double space Complex example + public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_1 (string text, int width, IEnumerable resultLines) { - // Empty input - string text = null; - var width = 1; - var breakLines = ""; - //var wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - //foreach (var line in wrappedLines) { - // breakLines += $"{line}{Environment.NewLine}"; - //} - var expected = string.Empty; - //Assert.Equal (expected, breakLines); - - // Single Spaces - text = "1 34"; - breakLines = ""; var wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - "3" + Environment.NewLine + - "4" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = string.Empty; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = string.Empty; - Assert.Equal (expected, breakLines); - - // Short input - text = "1"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "12"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - "2" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "123"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - "2" + Environment.NewLine + - "3" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // No spaces - text = "123456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - "2" + Environment.NewLine + - "3" + Environment.NewLine + - "4" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Just Spaces; should result in a single space - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine + - " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine + - " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Single Spaces - text = "12 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - "2" + Environment.NewLine + - "4" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Leading spaces should be preserved. - text = " 2 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine + - "2" + Environment.NewLine + - "4" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " 2 456 8"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine + - "2" + Environment.NewLine + - "4" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine + - "8" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Complex example - text = "A sentence has words. "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "A" + Environment.NewLine + - "s" + Environment.NewLine + - "e" + Environment.NewLine + - "n" + Environment.NewLine + - "t" + Environment.NewLine + - "e" + Environment.NewLine + - "n" + Environment.NewLine + - "c" + Environment.NewLine + - "e" + Environment.NewLine + - "h" + Environment.NewLine + - "a" + Environment.NewLine + - "s" + Environment.NewLine + - "w" + Environment.NewLine + - "o" + Environment.NewLine + - "r" + Environment.NewLine + - "d" + Environment.NewLine + - "s" + Environment.NewLine + - "." + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double Spaces - text = "12 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - "2" + Environment.NewLine + - "4" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double Leading spaces should be preserved. - text = " 3 567"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine + - "3" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine + - "7" + Environment.NewLine; Assert.Equal (expected, breakLines); - Assert.Equal (expected, breakLines); - - text = " 3 678 1"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine + - "3" + Environment.NewLine + - " " + Environment.NewLine + - "6" + Environment.NewLine + - "7" + Environment.NewLine + - "8" + Environment.NewLine + - " " + Environment.NewLine + - "1" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "1 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine + - " " + Environment.NewLine + - "4" + Environment.NewLine + - "5" + Environment.NewLine + - "6" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double space Complex example - text = "A sentence has words. "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "A" + Environment.NewLine + - " " + Environment.NewLine + - "s" + Environment.NewLine + - "e" + Environment.NewLine + - "n" + Environment.NewLine + - "t" + Environment.NewLine + - "e" + Environment.NewLine + - "n" + Environment.NewLine + - "c" + Environment.NewLine + - "e" + Environment.NewLine + - " " + Environment.NewLine + - "h" + Environment.NewLine + - "a" + Environment.NewLine + - "s" + Environment.NewLine + - "w" + Environment.NewLine + - "o" + Environment.NewLine + - "r" + Environment.NewLine + - "d" + Environment.NewLine + - "s" + Environment.NewLine + - "." + Environment.NewLine + - " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - } - - [Fact] - public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_3 () - { - // Empty input - string text = null; - var width = 3; + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.Equal (resultLines, wrappedLines); var breakLines = ""; - var wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); foreach (var line in wrappedLines) { breakLines += $"{line}{Environment.NewLine}"; } var expected = string.Empty; - Assert.Equal (expected, breakLines); - - text = string.Empty; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; + foreach (var line in resultLines) { + expected += $"{line}{Environment.NewLine}"; } - expected = string.Empty; - Assert.Equal (expected, breakLines); - - // Short input - text = "1"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "12"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "12" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "123"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "123" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // No spaces - text = "123456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "123" + Environment.NewLine + - "456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // No spaces - text = "1234567"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "123" + Environment.NewLine + - "456" + Environment.NewLine + - "7" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Just Spaces; should result in a single space - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - //" " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Single Spaces - text = "12 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "12" + Environment.NewLine + - "456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Leading spaces should be preserved. - text = " 2 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 2" + Environment.NewLine + - "456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " 2 456 8"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 2" + Environment.NewLine + - "456" + Environment.NewLine + - "8" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Complex example - text = "A sentence has words. "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "A" + Environment.NewLine + - "sen" + Environment.NewLine + - "ten" + Environment.NewLine + - "ce" + Environment.NewLine + - "has" + Environment.NewLine + - "wor" + Environment.NewLine + - "ds." + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double Spaces - text = "12 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "12" + Environment.NewLine + - "456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double Leading spaces should be preserved. - text = " 3 567"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 3" + Environment.NewLine + - "567" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " 3 678 1"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 3" + Environment.NewLine + - " 67" + Environment.NewLine + - "8 " + Environment.NewLine + // BUGBUG: looks like a trailing space to me! - "1" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "1 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1 " + Environment.NewLine + // BUGBUG: looks like a trailing space to me! - "456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double space Complex example - text = "A sentence has words. "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "A " + Environment.NewLine + - "sen" + Environment.NewLine + - "ten" + Environment.NewLine + - "ce " + Environment.NewLine + - " " + Environment.NewLine + - "has" + Environment.NewLine + - "wor" + Environment.NewLine + - "ds." + Environment.NewLine + - " " + Environment.NewLine; Assert.Equal (expected, breakLines); } - [Fact] - public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_50 () + [Theory] + [InlineData (null, 3, new string [] { })] // null input + [InlineData ("", 3, new string [] { })] // Empty input + [InlineData ("1", 3, new string [] { "1" })] // Short input + [InlineData ("12", 3, new string [] { "12" })] + [InlineData ("123", 3, new string [] { "123" })] + [InlineData ("123456", 3, new string [] { "123", "456" })] // No spaces + [InlineData ("1234567", 3, new string [] { "123", "456", "7" })] // No spaces + [InlineData (" ", 3, new string [] { " " })] // Just Spaces; should result in a single space + [InlineData (" ", 3, new string [] { " " })] + [InlineData (" ", 3, new string [] { " " })] + [InlineData (" ", 3, new string [] { " " })] + [InlineData ("12 456", 3, new string [] { "12", "456" })] // Single Spaces + [InlineData (" 2 456", 3, new string [] { " 2", "456" })] // Leading spaces should be preserved. + [InlineData (" 2 456 8", 3, new string [] { " 2", "456", "8" })] + [InlineData ("A sentence has words. ", 3, new string [] { "A", "sen", "ten", "ce", "has", "wor", "ds." })] // Complex example + [InlineData ("12 567", 3, new string [] { "12 ", "567" })] // Double Spaces + [InlineData (" 3 567", 3, new string [] { " 3", "567" })] // Double Leading spaces should be preserved. + [InlineData (" 3 678 1", 3, new string [] { " 3", " 67", "8 ", "1" })] + [InlineData ("1 456", 3, new string [] { "1 ", "456" })] + [InlineData ("A sentence has words. ", 3, new string [] { "A ", "sen", "ten", "ce ", " ", "has", "wor", "ds.", " " })] // Double space Complex example + public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_3 (string text, int width, IEnumerable resultLines) { - // Empty input - string text = null; - var width = 50; - var breakLines = ""; var wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.Equal (resultLines, wrappedLines); + var breakLines = ""; foreach (var line in wrappedLines) { breakLines += $"{line}{Environment.NewLine}"; } var expected = string.Empty; - Assert.Equal (expected, breakLines); - - text = string.Empty; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; + foreach (var line in resultLines) { + expected += $"{line}{Environment.NewLine}"; } - expected = string.Empty; - Assert.Equal (expected, breakLines); - - // Short input - text = "1"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "12"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "12" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "123"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "123" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // No spaces - text = "123456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "123456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // No spaces - text = "1234567"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1234567" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Just Spaces; should result in a single space - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Single Spaces - text = "12 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "12 456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Leading spaces should be preserved. - text = " 2 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 2 456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " 2 456 8"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 2 456 8" + Environment.NewLine ; - Assert.Equal (expected, breakLines); - - // Complex example - text = "A sentence has words. "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "A sentence has words. " + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double Spaces - text = "12 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "12 456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double Leading spaces should be preserved. - text = " 3 567"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 3 567" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = " 3 678 1"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = " 3 678 1" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - text = "1 456"; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "1 456" + Environment.NewLine; - Assert.Equal (expected, breakLines); - - // Double space Complex example - text = "A sentence has words. "; - breakLines = ""; - wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); - foreach (var line in wrappedLines) { - breakLines += $"{line}{Environment.NewLine}"; - } - expected = "A sentence has words. " + Environment.NewLine; Assert.Equal (expected, breakLines); } - [Fact] - public void WordWrap_PreserveTrailingSpaces_True_With_Tab () + [Theory] + [InlineData (null, 50, new string [] { })] // null input + [InlineData ("", 50, new string [] { })] // Empty input + [InlineData ("1", 50, new string [] { "1" })] // Short input + [InlineData ("12", 50, new string [] { "12" })] + [InlineData ("123", 50, new string [] { "123" })] + [InlineData ("123456", 50, new string [] { "123456" })] // No spaces + [InlineData ("1234567", 50, new string [] { "1234567" })] // No spaces + [InlineData (" ", 50, new string [] { " " })] // Just Spaces; should result in a single space + [InlineData (" ", 50, new string [] { " " })] + [InlineData (" ", 50, new string [] { " " })] + [InlineData ("12 456", 50, new string [] { "12 456" })] // Single Spaces + [InlineData (" 2 456", 50, new string [] { " 2 456" })] // Leading spaces should be preserved. + [InlineData (" 2 456 8", 50, new string [] { " 2 456 8" })] + [InlineData ("A sentence has words. ", 50, new string [] { "A sentence has words. " })] // Complex example + [InlineData ("12 567", 50, new string [] { "12 567" })] // Double Spaces + [InlineData (" 3 567", 50, new string [] { " 3 567" })] // Double Leading spaces should be preserved. + [InlineData (" 3 678 1", 50, new string [] { " 3 678 1" })] + [InlineData ("1 456", 50, new string [] { "1 456" })] + [InlineData ("A sentence has words. ", 50, new string [] { "A sentence has words. " })] // Double space Complex example + public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_50 (string text, int width, IEnumerable resultLines) { - var text = ustring.Empty; - int maxWidth = 1; - int expectedClippedWidth = 1; - - List wrappedLines; - - text = "A sentence\t\t\t has words."; - var tabWidth = 4; - maxWidth = 14; - expectedClippedWidth = 11; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.Equal ("A sentence\t", wrappedLines [0].ToString ()); - Assert.Equal ("\t\t has ", wrappedLines [1].ToString ()); - Assert.Equal ("words.", wrappedLines [2].ToString ()); - Assert.True (wrappedLines.Count == 3); - - maxWidth = 8; - expectedClippedWidth = 8; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("sentence", wrappedLines [1].ToString ()); - Assert.Equal ("\t\t", wrappedLines [2].ToString ()); - Assert.Equal ("\t ", wrappedLines [3].ToString ()); - Assert.Equal ("has ", wrappedLines [4].ToString ()); - Assert.Equal ("words.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 6); - - maxWidth = 3; - expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("sen", wrappedLines [1].ToString ()); - Assert.Equal ("ten", wrappedLines [2].ToString ()); - Assert.Equal ("ce", wrappedLines [3].ToString ()); - Assert.Equal ("\t", wrappedLines [4].ToString ()); - Assert.Equal ("\t", wrappedLines [5].ToString ()); - Assert.Equal ("\t", wrappedLines [6].ToString ()); - Assert.Equal (" ", wrappedLines [7].ToString ()); - Assert.Equal ("has", wrappedLines [8].ToString ()); - Assert.Equal (" ", wrappedLines [9].ToString ()); - Assert.Equal ("wor", wrappedLines [10].ToString ()); - Assert.Equal ("ds.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 12); - - maxWidth = 2; - expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.Equal ("A ", wrappedLines [0].ToString ()); - Assert.Equal ("se", wrappedLines [1].ToString ()); - Assert.Equal ("nt", wrappedLines [2].ToString ()); - Assert.Equal ("en", wrappedLines [3].ToString ()); - Assert.Equal ("ce", wrappedLines [4].ToString ()); - Assert.Equal ("\t", wrappedLines [5].ToString ()); - Assert.Equal ("\t", wrappedLines [6].ToString ()); - Assert.Equal ("\t", wrappedLines [7].ToString ()); - Assert.Equal (" ", wrappedLines [8].ToString ()); - Assert.Equal ("ha", wrappedLines [9].ToString ()); - Assert.Equal ("s ", wrappedLines [10].ToString ()); - Assert.Equal ("wo", wrappedLines [11].ToString ()); - Assert.Equal ("rd", wrappedLines [12].ToString ()); - Assert.Equal ("s.", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == 14); - - maxWidth = 1; - expectedClippedWidth = 1; - wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth); - Assert.True (expectedClippedWidth >= wrappedLines.Max (l => l.RuneCount)); - Assert.Equal ("A", wrappedLines [0].ToString ()); - Assert.Equal (" ", wrappedLines [1].ToString ()); - Assert.Equal ("s", wrappedLines [2].ToString ()); - Assert.Equal ("e", wrappedLines [3].ToString ()); - Assert.Equal ("n", wrappedLines [4].ToString ()); - Assert.Equal ("t", wrappedLines [5].ToString ()); - Assert.Equal ("e", wrappedLines [6].ToString ()); - Assert.Equal ("n", wrappedLines [7].ToString ()); - Assert.Equal ("c", wrappedLines [8].ToString ()); - Assert.Equal ("e", wrappedLines [9].ToString ()); - Assert.Equal ("\t", wrappedLines [10].ToString ()); - Assert.Equal ("\t", wrappedLines [11].ToString ()); - Assert.Equal ("\t", wrappedLines [12].ToString ()); - Assert.Equal (" ", wrappedLines [13].ToString ()); - Assert.Equal (".", wrappedLines [^1].ToString ()); - Assert.True (wrappedLines.Count == text.Length); + var wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: false); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.Equal (resultLines, wrappedLines); + var breakLines = ""; + foreach (var line in wrappedLines) { + breakLines += $"{line}{Environment.NewLine}"; + } + var expected = string.Empty; + foreach (var line in resultLines) { + expected += $"{line}{Environment.NewLine}"; + } + Assert.Equal (expected, breakLines); } - [Fact] - public void WordWrap_Unicode_Wide_Runes () + [Theory] + [InlineData ("A sentence\t\t\t has words.", 14, -10, new string [] { "A sentence\t", "\t\t has ", "words." })] + [InlineData ("A sentence\t\t\t has words.", 8, -16, new string [] { "A ", "sentence", "\t\t", "\t ", "has ", "words." })] + [InlineData ("A sentence\t\t\t has words.", 3, -21, new string [] { "A ", "sen", "ten", "ce", "\t", "\t", "\t", " ", "has", " ", "wor", "ds." })] + [InlineData ("A sentence\t\t\t has words.", 2, -22, new string [] { "A ", "se", "nt", "en", "ce", "\t", "\t", "\t", " ", "ha", "s ", "wo", "rd", "s." })] + [InlineData ("A sentence\t\t\t has words.", 1, -23, new string [] { "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", "\t", "\t", "\t", " ", "h", "a", "s", " ", "w", "o", "r", "d", "s", "." })] + public void WordWrap_PreserveTrailingSpaces_True_With_Tab (string text, int maxWidth, int widthOffset, IEnumerable resultLines, int tabWidth = 4) { - ustring text = "これが最初の行です。 こんにちは世界。 これが2行目です。"; - var width = text.RuneCount; - var wrappedLines = TextFormatter.WordWrapText (text, width); - Assert.Equal (3, wrappedLines.Count); - Assert.Equal ("これが最初の行です。", wrappedLines [0].ToString ()); - Assert.Equal ("こんにちは世界。", wrappedLines [1].ToString ()); - Assert.Equal ("これが2行目です。", wrappedLines [^1].ToString ()); + List wrappedLines; + + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth, preserveTrailingSpaces: true, tabWidth: tabWidth); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); } - [Fact] - public void ReplaceHotKeyWithTag () + [Theory] + [InlineData ("これが最初の行です。 こんにちは世界。 これが2行目です。", 29, 0, new string [] { "これが最初の行です。", "こんにちは世界。", "これが2行目です。" })] + public void WordWrap_PreserveTrailingSpaces_False_Unicode_Wide_Runes (string text, int maxWidth, int widthOffset, IEnumerable resultLines) + { + List wrappedLines; + + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth, preserveTrailingSpaces: false); + Assert.Equal (wrappedLines.Count, resultLines.Count ()); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)); + Assert.True (expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)); + Assert.Equal (resultLines, wrappedLines); + } + + [Theory] + [InlineData ("test", 0, 't', "test")] + [InlineData ("test", 1, 'e', "test")] + [InlineData ("Ok", 0, 'O', "Ok")] + [InlineData ("[◦ Ok ◦]", 3, 'O', "[◦ Ok ◦]")] + [InlineData ("^k", 0, '^', "^k")] + public void ReplaceHotKeyWithTag (string text, int hotPos, uint tag, string expected) { var tf = new TextFormatter (); - ustring text = "test"; - int hotPos = 0; - uint tag = 't'; - - Assert.Equal (ustring.Make (new Rune [] { tag, 'e', 's', 't' }), tf.ReplaceHotKeyWithTag (text, hotPos)); - - tag = 'e'; - hotPos = 1; - Assert.Equal (ustring.Make (new Rune [] { 't', tag, 's', 't' }), tf.ReplaceHotKeyWithTag (text, hotPos)); - - var result = tf.ReplaceHotKeyWithTag (text, hotPos); - Assert.Equal ('e', result.ToRunes () [1]); - - text = "Ok"; - tag = 'O'; - hotPos = 0; - Assert.Equal (ustring.Make (new Rune [] { tag, 'k' }), result = tf.ReplaceHotKeyWithTag (text, hotPos)); - Assert.Equal ('O', result.ToRunes () [0]); - - text = "[◦ Ok ◦]"; - text = ustring.Make (new Rune [] { '[', '◦', ' ', 'O', 'k', ' ', '◦', ']' }); var runes = text.ToRuneList (); - Assert.Equal (text.RuneCount, runes.Count); - Assert.Equal (text, ustring.Make (runes)); - tag = 'O'; - hotPos = 3; - Assert.Equal (ustring.Make (new Rune [] { '[', '◦', ' ', tag, 'k', ' ', '◦', ']' }), result = tf.ReplaceHotKeyWithTag (text, hotPos)); - Assert.Equal ('O', result.ToRunes () [3]); + Rune rune; + if (Rune.TryGetRuneAt (text, hotPos, out rune)) { + Assert.Equal (rune, (Rune)tag); - text = "^k"; - tag = '^'; - hotPos = 0; - Assert.Equal (ustring.Make (new Rune [] { tag, 'k' }), result = tf.ReplaceHotKeyWithTag (text, hotPos)); - Assert.Equal ('^', result.ToRunes () [0]); + } + var result = tf.ReplaceHotKeyWithTag (text, hotPos); + Assert.Equal (result, expected); + Assert.Equal ((Rune)tag, result.ToRunes () [hotPos]); + Assert.Equal (text.GetRuneCount (), runes.Count); + Assert.Equal (text, StringExtensions.ToString (runes)); } - [Fact] - public void Reformat_Invalid () + [Theory] + [InlineData ("", -1, TextAlignment.Left, false, 0)] + [InlineData (null, 0, TextAlignment.Left, false, 1)] + [InlineData (null, 0, TextAlignment.Left, true, 1)] + [InlineData ("", 0, TextAlignment.Left, false, 1)] + [InlineData ("", 0, TextAlignment.Left, true, 1)] + public void Reformat_Invalid (string text, int maxWidth, TextAlignment textAlignment, bool wrap, int linesCount) { - var text = ustring.Empty; - var list = new List (); + if (maxWidth < 0) { + Assert.Throws (() => TextFormatter.Format (text, maxWidth, textAlignment, wrap)); + } else { + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap); + Assert.NotEmpty (list); + Assert.True (list.Count == linesCount); + Assert.Equal (string.Empty, list [0]); + } + } - Assert.Throws (() => TextFormatter.Format (text, -1, TextAlignment.Left, false)); - - list = TextFormatter.Format (text, 0, TextAlignment.Left, false); + [Theory] + [InlineData ("", 0, 0, TextAlignment.Left, false, 1, true)] + [InlineData ("", 1, 1, TextAlignment.Left, false, 1, true)] + [InlineData ("A sentence has words.", 0, -21, TextAlignment.Left, false, 1, true)] + [InlineData ("A sentence has words.", 1, -20, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.", 5, -16, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.", 20, -1, TextAlignment.Left, false, 1, false)] + // no clip + [InlineData ("A sentence has words.", 21, 0, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.", 22, 1, TextAlignment.Left, false, 1, false)] + public void Reformat_NoWordrap_SingleLine (string text, int maxWidth, int widthOffset, TextAlignment textAlignment, bool wrap, int linesCount, bool stringEmpty) + { + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap); Assert.NotEmpty (list); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); + Assert.True (list.Count == linesCount); + if (stringEmpty) { + Assert.Equal (string.Empty, list [0]); + } else { + Assert.NotEqual (string.Empty, list [0]); + } + Assert.Equal (StringExtensions.ToString (text.ToRunes () [0..expectedClippedWidth]), list [0]); + } - text = null; - list = TextFormatter.Format (text, 0, TextAlignment.Left, false); + [Theory] + [InlineData ("A sentence has words.\nLine 2.", 0, -29, TextAlignment.Left, false, 1, true)] + [InlineData ("A sentence has words.\nLine 2.", 1, -28, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\nLine 2.", 5, -24, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\nLine 2.", 28, -1, TextAlignment.Left, false, 1, false)] + // no clip + [InlineData ("A sentence has words.\nLine 2.", 29, 0, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\nLine 2.", 30, 1, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, TextAlignment.Left, false, 1, true)] + [InlineData ("A sentence has words.\r\nLine 2.", 1, -29, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\r\nLine 2.", 5, -25, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\r\nLine 2.", 29, -1, TextAlignment.Left, false, 1, false, 1)] + [InlineData ("A sentence has words.\r\nLine 2.", 30, 0, TextAlignment.Left, false, 1, false)] + [InlineData ("A sentence has words.\r\nLine 2.", 31, 1, TextAlignment.Left, false, 1, false)] + public void Reformat_NoWordrap_NewLines (string text, int maxWidth, int widthOffset, TextAlignment textAlignment, bool wrap, int linesCount, bool stringEmpty, int clipWidthOffset = 0) + { + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth) + clipWidthOffset; + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap); Assert.NotEmpty (list); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); + Assert.True (list.Count == linesCount); + if (stringEmpty) { + Assert.Equal (string.Empty, list [0]); + } else { + Assert.NotEqual (string.Empty, list [0]); + } + if (text.Contains ("\r\n") && maxWidth > 0) { + Assert.Equal (StringExtensions.ToString (text.ToRunes () [0..expectedClippedWidth]).Replace ("\r\n", " "), list [0]); + } else if (text.Contains ('\n') && maxWidth > 0) { + Assert.Equal (StringExtensions.ToString (text.ToRunes () [0..expectedClippedWidth]).Replace ("\n", " "), list [0]); + } else { + Assert.Equal (StringExtensions.ToString (text.ToRunes () [0..expectedClippedWidth]), list [0]); + } + } - list = TextFormatter.Format (text, 0, TextAlignment.Left, true); + [Theory] + // Even # of spaces + // 0123456789 + [InlineData ("012 456 89", 0, -10, TextAlignment.Left, true, true, true, new string [] { "" })] + [InlineData ("012 456 89", 1, -9, TextAlignment.Left, true, true, false, new string [] { "0", "1", "2", " ", "4", "5", "6", " ", "8", "9" }, "01245689")] + [InlineData ("012 456 89", 5, -5, TextAlignment.Left, true, true, false, new string [] { "012 ", "456 ", "89" })] + [InlineData ("012 456 89", 9, -1, TextAlignment.Left, true, true, false, new string [] { "012 456 ", "89" })] + // no clip + [InlineData ("012 456 89", 10, 0, TextAlignment.Left, true, true, false, new string [] { "012 456 89" })] + [InlineData ("012 456 89", 11, 1, TextAlignment.Left, true, true, false, new string [] { "012 456 89" })] + // Odd # of spaces + // 01234567890123 + [InlineData ("012 456 89 end", 13, -1, TextAlignment.Left, true, true, false, new string [] { "012 456 89 ", "end" })] + // no clip + [InlineData ("012 456 89 end", 14, 0, TextAlignment.Left, true, true, false, new string [] { "012 456 89 end" })] + [InlineData ("012 456 89 end", 15, 1, TextAlignment.Left, true, true, false, new string [] { "012 456 89 end" })] + public void Reformat_Wrap_Spaces_No_NewLines (string text, int maxWidth, int widthOffset, TextAlignment textAlignment, bool wrap, bool preserveTrailingSpaces, bool stringEmpty, IEnumerable resultLines, string noSpaceText = "") + { + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth); + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap, preserveTrailingSpaces); Assert.NotEmpty (list); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); + Assert.True (list.Count == resultLines.Count ()); + if (stringEmpty) { + Assert.Equal (string.Empty, list [0]); + } else { + Assert.NotEqual (string.Empty, list [0]); + } + Assert.Equal (resultLines, list); + + if (maxWidth > 0) { + // remove whitespace chars + if (maxWidth < 5) { + expectedClippedWidth = text.GetRuneCount () - text.Sum (r => r == ' ' ? 1 : 0); + } else { + expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth - text.Sum (r => r == ' ' ? 1 : 0)); + } + list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap, preserveTrailingSpaces: false); + if (maxWidth == 1) { + Assert.Equal (expectedClippedWidth, list.Count); + Assert.Equal (noSpaceText, string.Concat (list.ToArray ())); + } + if (maxWidth > 1 && maxWidth < 10) { + Assert.Equal (StringExtensions.ToString (text.ToRunes () [0..expectedClippedWidth]), list [0]); + } + } } - [Fact] - public void Reformat_NoWordrap_SingleLine () + [Theory] + // Unicode + // Even # of chars + // 0123456789 + [InlineData ("\u2660пÑРвРÑ", 10, -1, TextAlignment.Left, true, false, new string [] { "\u2660пÑРвÐ", "Ñ" })] + // no clip + [InlineData ("\u2660пÑРвРÑ", 11, 0, TextAlignment.Left, true, false, new string [] { "\u2660пÑРвРÑ" })] + [InlineData ("\u2660пÑРвРÑ", 12, 1, TextAlignment.Left, true, false, new string [] { "\u2660пÑРвРÑ" })] + // Unicode + // Odd # of chars + // 0123456789 + [InlineData ("\u2660 ÑРвРÑ", 9, -1, TextAlignment.Left, true, false, new string [] { "\u2660 ÑРвÐ", "Ñ" })] + // no clip + [InlineData ("\u2660 ÑРвРÑ", 10, 0, TextAlignment.Left, true, false, new string [] { "\u2660 ÑРвРÑ" })] + [InlineData ("\u2660 ÑРвРÑ", 11, 1, TextAlignment.Left, true, false, new string [] { "\u2660 ÑРвРÑ" })] + public void Reformat_Unicode_Wrap_Spaces_No_NewLines (string text, int maxWidth, int widthOffset, TextAlignment textAlignment, bool wrap, bool preserveTrailingSpaces, IEnumerable resultLines) { - var text = ustring.Empty; - var list = new List (); - var maxWidth = 0; - var expectedClippedWidth = 0; - var wrap = false; - - maxWidth = 0; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - - maxWidth = 1; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - - text = "A sentence has words."; - maxWidth = 0; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); - - maxWidth = 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = 5; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap, preserveTrailingSpaces); + Assert.Equal (list.Count, resultLines.Count ()); + Assert.Equal (resultLines, list); } - [Fact] - public void Reformat_NoWordrap_NewLines () + [Theory] + // Unicode + [InlineData ("\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464", 8, -1, TextAlignment.Left, true, false, new string [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" })] + // no clip + [InlineData ("\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464", 9, 0, TextAlignment.Left, true, false, new string [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" })] + [InlineData ("\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464", 10, 1, TextAlignment.Left, true, false, new string [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" })] + public void Reformat_Unicode_Wrap_Spaces_NewLines (string text, int maxWidth, int widthOffset, TextAlignment textAlignment, bool wrap, bool preserveTrailingSpaces, IEnumerable resultLines) { - var text = ustring.Empty; - var list = new List (); - var maxWidth = 0; - var expectedClippedWidth = 0; - var wrap = false; - - text = "A sentence has words.\nLine 2."; - maxWidth = 0; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); - - maxWidth = 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = 5; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]).Replace ("\n", " "), list [0]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]).Replace ("\n", " "), list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]).Replace ("\n", " "), list [0]); - - text = "A sentence has words.\r\nLine 2."; - maxWidth = 0; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); - - maxWidth = 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = 5; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth) + 1; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]).Replace ("\r\n", " ").ToString (), list [0].ToString ()); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]).Replace ("\r\n", " "), list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]).Replace ("\r\n", " "), list [0]); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap, preserveTrailingSpaces); + Assert.Equal (list.Count, resultLines.Count ()); + Assert.Equal (resultLines, list); } - [Fact] - public void Reformat_Wrap_Spaces_No_NewLines () + [Theory] + [InlineData (" A sentence has words. \n This is the second Line - 2. ", 4, -50, TextAlignment.Left, true, false, new string [] { " A", "sent", "ence", "has", "word", "s. ", " Thi", "s is", "the", "seco", "nd", "Line", "- 2." }, " Asentencehaswords. This isthesecondLine- 2.")] + [InlineData (" A sentence has words. \n This is the second Line - 2. ", 4, -50, TextAlignment.Left, true, true, new string [] { " A ", "sent", "ence", " ", "has ", "word", "s. ", " ", "This", " is ", "the ", "seco", "nd ", "Line", " - ", "2. " }, " A sentence has words. This is the second Line - 2. ")] + public void Format_WordWrap_PreserveTrailingSpaces (string text, int maxWidth, int widthOffset, TextAlignment textAlignment, bool wrap, bool preserveTrailingSpaces, IEnumerable resultLines, string expectedWrappedText) { - var text = ustring.Empty; - var list = new List (); - var maxWidth = 0; - var expectedClippedWidth = 0; - var wrap = true; - var preserveTrailingSpaces = true; - - // Even # of spaces - // 0123456789 - text = "012 456 89"; - - // See WordWrap BUGBUGs above. - maxWidth = 0; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal (ustring.Empty, list [0]); - - maxWidth = 1; - // remove 3 whitespace chars - expectedClippedWidth = text.RuneCount - text.Sum (r => r == ' ' ? 1 : 0); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.Equal (expectedClippedWidth, list.Count); - Assert.Equal ("01245689", ustring.Join ("", list.ToArray ())); - - maxWidth = 1; - // keep 3 whitespace chars - expectedClippedWidth = text.RuneCount; - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap, preserveTrailingSpaces); - Assert.Equal (expectedClippedWidth, list.Count); - Assert.Equal (text, ustring.Join ("", list.ToArray ())); - - maxWidth = 5; - // remove 3 whitespace chars - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth - text.Sum (r => r == ' ' ? 1 : 0)); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.Equal (expectedClippedWidth, list.Count); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - Assert.Equal ("01245689", ustring.Join ("", list.ToArray ())); - - maxWidth = 5; - // keep 3 whitespace chars - expectedClippedWidth = Math.Min (text.RuneCount, (int)Math.Ceiling ((double)(text.RuneCount / 3F))); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap, preserveTrailingSpaces); - Assert.Equal (expectedClippedWidth - (maxWidth - expectedClippedWidth), list.Count); - Assert.Equal (ustring.Make (text.ToRunes () [0..expectedClippedWidth]), list [0]); - Assert.Equal ("012 456 89", ustring.Join ("", list.ToArray ())); - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 2); - Assert.Equal ("012 456", list [0]); - Assert.Equal ("89", list [1]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("012 456 89", list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("012 456 89", list [0]); - - // Odd # of spaces - // 0123456789 - text = "012 456 89 end"; - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 2); - Assert.Equal ("012 456 89", list [0]); - Assert.Equal ("end", list [1]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("012 456 89 end", list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("012 456 89 end", list [0]); - } - - [Fact] - public void Reformat_Unicode_Wrap_Spaces_No_NewLines () - { - var text = ustring.Empty; - var list = new List (); - var maxWidth = 0; - var expectedClippedWidth = 0; - var wrap = true; - - // Unicode - // Even # of chars - // 0123456789 - text = "\u2660пÑРвРÑ"; - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 2); - Assert.Equal ("\u2660пÑРвÐ", list [0]); - Assert.Equal ("Ñ", list [1]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("\u2660пÑРвРÑ", list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("\u2660пÑРвРÑ", list [0]); - - // Unicode - // Odd # of chars - // 0123456789 - text = "\u2660 ÑРвРÑ"; - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 2); - Assert.Equal ("\u2660 ÑРвÐ", list [0]); - Assert.Equal ("Ñ", list [1]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("\u2660 ÑРвРÑ", list [0]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.True (list.Count == 1); - Assert.Equal ("\u2660 ÑРвРÑ", list [0]); - } - - [Fact] - public void Reformat_Unicode_Wrap_Spaces_NewLines () - { - var text = ustring.Empty; - var list = new List (); - var maxWidth = 0; - var expectedClippedWidth = 0; - var wrap = true; - - // Unicode - text = "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464"; - - maxWidth = text.RuneCount - 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.Equal (2, list.Count); - Assert.Equal ("\u2460\u2461\u2462", list [0]); - Assert.Equal ("\u2460\u2461\u2462\u2463\u2464", list [1]); - - // no clip - maxWidth = text.RuneCount + 0; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.Equal (2, list.Count); - Assert.Equal ("\u2460\u2461\u2462", list [0]); - Assert.Equal ("\u2460\u2461\u2462\u2463\u2464", list [1]); - - maxWidth = text.RuneCount + 1; - expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - list = TextFormatter.Format (text, maxWidth, TextAlignment.Left, wrap); - Assert.Equal (2, list.Count); - Assert.Equal ("\u2460\u2461\u2462", list [0]); - Assert.Equal ("\u2460\u2461\u2462\u2463\u2464", list [1]); - } - - [Fact] - public void System_Rune_ColumnWidth () - { - var c = new Rune ('a'); - Assert.Equal (1, Rune.ColumnWidth (c)); - Assert.Equal (1, ustring.Make (c).ConsoleWidth); - Assert.Equal (1, ustring.Make (c).Length); - - c = new Rune ('b'); - Assert.Equal (1, Rune.ColumnWidth (c)); - Assert.Equal (1, ustring.Make (c).ConsoleWidth); - Assert.Equal (1, ustring.Make (c).Length); - - c = new Rune (123); - Assert.Equal (1, Rune.ColumnWidth (c)); - Assert.Equal (1, ustring.Make (c).ConsoleWidth); - Assert.Equal (1, ustring.Make (c).Length); - - c = new Rune ('\u1150'); - Assert.Equal (2, Rune.ColumnWidth (c)); // 0x1150 ᅐ Unicode Technical Report #11 - Assert.Equal (2, ustring.Make (c).ConsoleWidth); - Assert.Equal (3, ustring.Make (c).Length); - - c = new Rune ('\u1161'); - Assert.Equal (0, Rune.ColumnWidth (c)); // 0x1161 ᅡ column width of 0 - Assert.Equal (0, ustring.Make (c).ConsoleWidth); - Assert.Equal (3, ustring.Make (c).Length); - - c = new Rune (31); - Assert.Equal (-1, Rune.ColumnWidth (c)); // non printable character - Assert.Equal (0, ustring.Make (c).ConsoleWidth);// ConsoleWidth only returns zero or greater than zero - Assert.Equal (1, ustring.Make (c).Length); - - c = new Rune (127); - Assert.Equal (-1, Rune.ColumnWidth (c)); // non printable character - Assert.Equal (0, ustring.Make (c).ConsoleWidth); - Assert.Equal (1, ustring.Make (c).Length); - } - - [Fact] - public void System_Text_Rune () - { - var c = new System.Text.Rune ('a'); - Assert.Equal (1, c.Utf8SequenceLength); - - c = new System.Text.Rune ('b'); - Assert.Equal (1, c.Utf8SequenceLength); - - c = new System.Text.Rune (123); - Assert.Equal (1, c.Utf8SequenceLength); - - c = new System.Text.Rune ('\u1150'); - Assert.Equal (3, c.Utf8SequenceLength); // 0x1150 ᅐ Unicode Technical Report #11 - - c = new System.Text.Rune ('\u1161'); - Assert.Equal (3, c.Utf8SequenceLength); // 0x1161 ᅡ column width of 0 - - c = new System.Text.Rune (31); - Assert.Equal (1, c.Utf8SequenceLength); // non printable character - - c = new System.Text.Rune (127); - Assert.Equal (1, c.Utf8SequenceLength); // non printable character - } - - [Fact] - public void Format_WordWrap_PreserveTrailingSpaces () - { - ustring text = " A sentence has words. \n This is the second Line - 2. "; - - // With preserveTrailingSpaces = false by default. - var list1 = TextFormatter.Format (text, 4, TextAlignment.Left, true); - ustring wrappedText1 = ustring.Empty; - Assert.Equal (" A", list1 [0].ToString ()); - Assert.Equal ("sent", list1 [1].ToString ()); - Assert.Equal ("ence", list1 [2].ToString ()); - Assert.Equal ("has", list1 [3].ToString ()); - Assert.Equal ("word", list1 [4].ToString ()); - Assert.Equal ("s. ", list1 [5].ToString ()); - Assert.Equal (" Thi", list1 [6].ToString ()); - Assert.Equal ("s is", list1 [7].ToString ()); - Assert.Equal ("the", list1 [8].ToString ()); - Assert.Equal ("seco", list1 [9].ToString ()); - Assert.Equal ("nd", list1 [10].ToString ()); - Assert.Equal ("Line", list1 [11].ToString ()); - Assert.Equal ("- 2.", list1 [^1].ToString ()); - foreach (var txt in list1) wrappedText1 += txt; - Assert.Equal (" Asentencehaswords. This isthesecondLine- 2.", wrappedText1.ToString ()); - - // With preserveTrailingSpaces = true. - var list2 = TextFormatter.Format (text, 4, TextAlignment.Left, true, true); - ustring wrappedText2 = ustring.Empty; - Assert.Equal (" A ", list2 [0].ToString ()); - Assert.Equal ("sent", list2 [1].ToString ()); - Assert.Equal ("ence", list2 [2].ToString ()); - Assert.Equal (" ", list2 [3].ToString ()); - Assert.Equal ("has ", list2 [4].ToString ()); - Assert.Equal ("word", list2 [5].ToString ()); - Assert.Equal ("s. ", list2 [6].ToString ()); - Assert.Equal (" ", list2 [7].ToString ()); - Assert.Equal ("This", list2 [8].ToString ()); - Assert.Equal (" is ", list2 [9].ToString ()); - Assert.Equal ("the ", list2 [10].ToString ()); - Assert.Equal ("seco", list2 [11].ToString ()); - Assert.Equal ("nd ", list2 [12].ToString ()); - Assert.Equal ("Line", list2 [13].ToString ()); - Assert.Equal (" - ", list2 [14].ToString ()); - Assert.Equal ("2. ", list2 [^1].ToString ()); - foreach (var txt in list2) wrappedText2 += txt; - Assert.Equal (" A sentence has words. This is the second Line - 2. ", wrappedText2.ToString ()); + Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset); + var list = TextFormatter.Format (text, maxWidth, textAlignment, wrap, preserveTrailingSpaces); + Assert.Equal (list.Count, resultLines.Count ()); + Assert.Equal (resultLines, list); + string wrappedText = string.Empty; + foreach (var txt in list) wrappedText += txt; + Assert.Equal (expectedWrappedText, wrappedText); } [Fact] @@ -3642,49 +1205,54 @@ namespace Terminal.Gui.TextTests { Assert.Null (exception); } - - [Fact] - public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Horizontal () + [Theory] + [InlineData ("Hello world, how are you today? Pretty neat!", 44, 80, "Hello world, how are you today? Pretty neat!")] + public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Horizontal (string text, int runeCount, int maxWidth, string justifiedText) { - ustring text = "Hello world, how are you today? Pretty neat!"; + Assert.Equal (runeCount, text.GetRuneCount ()); - Assert.Equal (44, text.RuneCount); - - for (int i = 44; i < 80; i++) { - var fmtText = TextFormatter.Format (text, i, TextAlignment.Justified, false, true) [0]; - Assert.Equal (i, fmtText.RuneCount); - var c = (char)fmtText [^1]; - Assert.Equal ('!', c); + var fmtText = string.Empty; + for (int i = text.GetRuneCount (); i < maxWidth; i++) { + fmtText = TextFormatter.Format (text, i, TextAlignment.Justified, false, true) [0]; + Assert.Equal (i, fmtText.GetRuneCount ()); + var c = fmtText [^1]; + Assert.True (text.EndsWith (c)); } + Assert.Equal (justifiedText, fmtText); } - [Fact] - public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Vertical () + [Theory] + [InlineData ("Hello world, how are you today? Pretty neat!", 44, 80, "Hello world, how are you today? Pretty neat!")] + public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Vertical (string text, int runeCount, int maxWidth, string justifiedText) { - ustring text = "Hello world, how are you today? Pretty neat!"; + Assert.Equal (runeCount, text.GetRuneCount ()); - Assert.Equal (44, text.RuneCount); - - for (int i = 44; i < 80; i++) { - var fmtText = TextFormatter.Format (text, i, TextAlignment.Justified, false, true, 0, TextDirection.TopBottom_LeftRight) [0]; - Assert.Equal (i, fmtText.RuneCount); - var c = (char)fmtText [^1]; - Assert.Equal ('!', c); + var fmtText = string.Empty; + for (int i = text.GetRuneCount (); i < maxWidth; i++) { + fmtText = TextFormatter.Format (text, i, TextAlignment.Justified, false, true, 0, TextDirection.TopBottom_LeftRight) [0]; + Assert.Equal (i, fmtText.GetRuneCount ()); + var c = fmtText [^1]; + Assert.True (text.EndsWith (c)); } + Assert.Equal (justifiedText, fmtText); } - [Fact] - public void TestClipOrPad_ShortWord () + [Theory] + [InlineData ("fff", 6, "fff ")] + [InlineData ("Hello World", 16, "Hello World ")] + public void TestClipOrPad_ShortWord (string text, int fillPad, string expectedText) { - // word is short but we want it to fill 6 so it should be padded - Assert.Equal ("fff ", TextFormatter.ClipOrPad ("fff", 6)); + // word is short but we want it to fill # so it should be padded + Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad)); } - [Fact] - public void TestClipOrPad_LongWord () + [Theory] + [InlineData ("123456789", 3, "123")] + [InlineData ("Hello World", 8, "Hello Wo")] + public void TestClipOrPad_LongWord (string text, int fillPad, string expectedText) { - // word is long but we want it to fill 3 space only - Assert.Equal ("123", TextFormatter.ClipOrPad ("123456789", 3)); + // word is long but we want it to fill # space only + Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad)); } [Fact] @@ -3696,210 +1264,166 @@ namespace Terminal.Gui.TextTests { Assert.Equal (Key.CtrlMask | Key.Q, tf.HotKey); } - [Fact] - public void GetTextWidth_Simple_And_Wide_Runes () + [Theory] + [InlineData ("Hello World", 11)] + [InlineData ("こんにちは世界", 14)] + public void GetColumns_Simple_And_Wide_Runes (string text, int width) { - ustring text = "Hello World"; - Assert.Equal (11, TextFormatter.GetTextWidth (text)); - text = "こんにちは世界"; - Assert.Equal (14, TextFormatter.GetTextWidth (text)); + Assert.Equal (width, text.GetColumns ()); } - [Fact] - public void GetSumMaxCharWidth_Simple_And_Wide_Runes () + [Theory] + [InlineData ("Hello World", 11, 6, 1, 1)] + [InlineData ("こんにちは 世界", 15, 6, 1, 2)] + public void GetSumMaxCharWidth_Simple_And_Wide_Runes (string text, int width, int index, int length, int indexWidth) { - ustring text = "Hello World"; - Assert.Equal (11, TextFormatter.GetSumMaxCharWidth (text)); - Assert.Equal (1, TextFormatter.GetSumMaxCharWidth (text, 6, 1)); - text = "こんにちは 世界"; - Assert.Equal (15, TextFormatter.GetSumMaxCharWidth (text)); - Assert.Equal (2, TextFormatter.GetSumMaxCharWidth (text, 6, 1)); + Assert.Equal (width, TextFormatter.GetSumMaxCharWidth (text)); + Assert.Equal (indexWidth, TextFormatter.GetSumMaxCharWidth (text, index, length)); } - [Fact] - public void GetSumMaxCharWidth_List_Simple_And_Wide_Runes () + [Theory] + [InlineData (new string [] { "Hello", "World" }, 2, 1, 1, 1)] + [InlineData (new string [] { "こんにちは", "世界" }, 4, 1, 1, 2)] + public void GetSumMaxCharWidth_List_Simple_And_Wide_Runes (IEnumerable text, int width, int index, int length, int indexWidth) { - var text = new List () { "Hello", "World" }; - Assert.Equal (2, TextFormatter.GetSumMaxCharWidth (text)); - Assert.Equal (1, TextFormatter.GetSumMaxCharWidth (text, 1, 1)); - text = new List () { "こんにちは", "世界" }; - Assert.Equal (4, TextFormatter.GetSumMaxCharWidth (text)); - Assert.Equal (2, TextFormatter.GetSumMaxCharWidth (text, 1, 1)); + Assert.Equal (width, TextFormatter.GetSumMaxCharWidth (text.ToList ())); + Assert.Equal (indexWidth, TextFormatter.GetSumMaxCharWidth (text.ToList (), index, length)); } - [Fact] - public void GetLengthThatFits_runelist () + [Theory] + [InlineData ("test", 3, 3)] + [InlineData ("test", 4, 4)] + [InlineData ("test", 10, 4)] + public void GetLengthThatFits_Runelist (string text, int columns, int expectedLength) { - int columns = 3; - ustring text = "test"; var runes = text.ToRuneList (); - Assert.Equal (3, TextFormatter.GetLengthThatFits (runes, columns)); - - columns = 4; - Assert.Equal (4, TextFormatter.GetLengthThatFits (runes, columns)); - - columns = 10; - Assert.Equal (4, TextFormatter.GetLengthThatFits (runes, columns)); + Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns)); } - [Fact] - public void GetLengthThatFits_ustring () + [Theory] + [InlineData ("test", 3, 3)] + [InlineData ("test", 4, 4)] + [InlineData ("test", 10, 4)] + [InlineData ("test", 1, 1)] + [InlineData ("test", 0, 0)] + [InlineData ("test", -1, 0)] + [InlineData (null, -1, 0)] + [InlineData ("", -1, 0)] + public void GetLengthThatFits_String (string text, int columns, int expectedLength) { - int columns = 3; - ustring text = "test"; - - Assert.Equal (3, TextFormatter.GetLengthThatFits (text, columns)); - - columns = 4; - Assert.Equal (4, TextFormatter.GetLengthThatFits (text, columns)); - - columns = 10; - Assert.Equal (4, TextFormatter.GetLengthThatFits (text, columns)); - - columns = 1; - Assert.Equal (1, TextFormatter.GetLengthThatFits (text, columns)); - - columns = 0; - Assert.Equal (0, TextFormatter.GetLengthThatFits (text, columns)); - - columns = -1; - Assert.Equal (0, TextFormatter.GetLengthThatFits (text, columns)); - - text = null; - Assert.Equal (0, TextFormatter.GetLengthThatFits (text, columns)); - - text = string.Empty; - Assert.Equal (0, TextFormatter.GetLengthThatFits (text, columns)); + Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns)); } - [Fact] - public void GetLengthThatFits_Simple_And_Wide_Runes () + [Theory] + [InlineData ("Hello World", 6, 6)] + [InlineData ("こんにちは 世界", 6, 3)] + public void GetLengthThatFits_Simple_And_Wide_Runes (string text, int columns, int expectedLength) { - ustring text = "Hello World"; - Assert.Equal (6, TextFormatter.GetLengthThatFits (text, 6)); - text = "こんにちは 世界"; - Assert.Equal (3, TextFormatter.GetLengthThatFits (text, 6)); + Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns)); } - [Fact] - public void GetLengthThatFits_List_Simple_And_Wide_Runes () + [Theory] + [InlineData ("Hello World", 6, 6)] + [InlineData ("こんにちは 世界", 6, 3)] + [MemberData (nameof (CMGlyphs))] + public void GetLengthThatFits_List_Simple_And_Wide_Runes (string text, int columns, int expectedLength) { - var runes = ustring.Make ("Hello World").ToRuneList (); - Assert.Equal (6, TextFormatter.GetLengthThatFits (runes, 6)); - runes = ustring.Make ("こんにちは 世界").ToRuneList (); - Assert.Equal (3, TextFormatter.GetLengthThatFits (runes, 6)); - runes = ustring.Make ($"{CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}").ToRuneList (); - Assert.Equal (15, TextFormatter.GetLengthThatFits (runes, 16)); + var runes = text.ToRuneList (); + Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns)); } - [Fact] - public void Format_Truncate_Simple_And_Wide_Runes () - { - var text = "Truncate"; - var list = TextFormatter.Format (text, 3, false, false); - Assert.Equal ("Tru", list [^1].ToString ()); + public static IEnumerable CMGlyphs => + new List + { + new object[] { $"{CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}", 16, 15 } + }; - text = "デモエムポンズ"; - list = TextFormatter.Format (text, 3, false, false); - Assert.Equal ("デ", list [^1].ToString ()); + [Theory] + [InlineData ("Truncate", 3, "Tru")] + [InlineData ("デモエムポンズ", 3, "デ")] + public void Format_Truncate_Simple_And_Wide_Runes (string text, int width, string expected) + { + var list = TextFormatter.Format (text, width, false, false); + Assert.Equal (expected, list [^1]); } - - [Fact] - public void Format_With_PreserveTrailingSpaces_And_Without_PreserveTrailingSpaces () + [Theory] + [MemberData (nameof (FormatEnvironmentNewLine))] + public void Format_With_PreserveTrailingSpaces_And_Without_PreserveTrailingSpaces (string text, int width, IEnumerable expected) { - var text = $"Line1{Environment.NewLine}Line2{Environment.NewLine}Line3{Environment.NewLine}"; - var width = 60; var preserveTrailingSpaces = false; var formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces); - Assert.Equal ("Line1", formated [0].ToString ()); - Assert.Equal ("Line2", formated [1].ToString ()); - Assert.Equal ("Line3", formated [^1].ToString ()); + Assert.Equal (expected, formated); preserveTrailingSpaces = true; formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces); - Assert.Equal ("Line1", formated [0].ToString ()); - Assert.Equal ("Line2", formated [1].ToString ()); - Assert.Equal ("Line3", formated [^1].ToString ()); + Assert.Equal (expected, formated); } - [Fact] - public void SplitNewLine_Ending_Without_NewLine_Probably_CRLF () + public static IEnumerable FormatEnvironmentNewLine => + new List + { + new object[] { $"Line1{Environment.NewLine}Line2{Environment.NewLine}Line3{Environment.NewLine}", 60, new string [] { "Line1", "Line2", "Line3" } } + }; + + [Theory] + [MemberData (nameof (SplitEnvironmentNewLine))] + public void SplitNewLine_Ending__With_Or_Without_NewLine_Probably_CRLF (string text, IEnumerable expected) { - var text = $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界"; var splited = TextFormatter.SplitNewLine (text); - Assert.Equal ("First Line 界", splited [0]); - Assert.Equal ("Second Line 界", splited [1]); - Assert.Equal ("Third Line 界", splited [^1]); + Assert.Equal (expected, splited); } - [Fact] - public void SplitNewLine_Ending_With_NewLine_Probably_CRLF () + public static IEnumerable SplitEnvironmentNewLine => + new List + { + new object[] { $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界", new string [] { "First Line 界", "Second Line 界", "Third Line 界" } }, + new object[] { $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界{Environment.NewLine}", new string [] { "First Line 界", "Second Line 界", "Third Line 界", "" } } + }; + + [Theory] + [InlineData ($"First Line 界\nSecond Line 界\nThird Line 界", new string [] { "First Line 界", "Second Line 界", "Third Line 界" })] + public void SplitNewLine_Ending_Without_NewLine_Only_LF (string text, IEnumerable expected) { - var text = $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界{Environment.NewLine}"; var splited = TextFormatter.SplitNewLine (text); - Assert.Equal ("First Line 界", splited [0]); - Assert.Equal ("Second Line 界", splited [1]); - Assert.Equal ("Third Line 界", splited [2]); - Assert.Equal ("", splited [^1]); + Assert.Equal (expected, splited); } - [Fact] - public void SplitNewLine_Ending_Without_NewLine_Only_LF () + [Theory] + [InlineData ($"First Line 界\nSecond Line 界\nThird Line 界\n", new string [] { "First Line 界", "Second Line 界", "Third Line 界", "" })] + public void SplitNewLine_Ending_With_NewLine_Only_LF (string text, IEnumerable expected) { - var text = $"First Line 界\nSecond Line 界\nThird Line 界"; var splited = TextFormatter.SplitNewLine (text); - Assert.Equal ("First Line 界", splited [0]); - Assert.Equal ("Second Line 界", splited [1]); - Assert.Equal ("Third Line 界", splited [^1]); + Assert.Equal (expected, splited); } - [Fact] - public void SplitNewLine_Ending_With_NewLine_Only_LF () + [Theory] + [InlineData ("Single Line 界", 14)] + [InlineData ($"First Line 界\nSecond Line 界\nThird Line 界\n", 14)] + public void MaxWidthLine_With_And_Without_Newlines (string text, int expected) { - var text = $"First Line 界\nSecond Line 界\nThird Line 界\n"; - var splited = TextFormatter.SplitNewLine (text); - Assert.Equal ("First Line 界", splited [0]); - Assert.Equal ("Second Line 界", splited [1]); - Assert.Equal ("Third Line 界", splited [2]); - Assert.Equal ("", splited [^1]); + Assert.Equal (expected, TextFormatter.MaxWidthLine (text)); } - [Fact] - public void MaxWidthLine_With_And_Without_Newlines () + [Theory] + [InlineData ("New Test 你", 10, 10, 20320, 20320, 9, "你")] + [InlineData ("New Test \U0001d539", 10, 11, 120121, 55349, 9, "𝔹")] + public void String_Array_Is_Not_Always_Equal_ToRunes_Array (string text, int runesLength, int stringLength, int runeValue, int stringValue, int index, string expected) { - var text = "Single Line 界"; - Assert.Equal (14, TextFormatter.MaxWidthLine (text)); - - text = $"First Line 界\nSecond Line 界\nThird Line 界\n"; - Assert.Equal (14, TextFormatter.MaxWidthLine (text)); - } - - [Fact] - public void Ustring_Array_Is_Not_Equal_ToRunes_Array_And_String_Array () - { - var text = "New Test 你"; - ustring us = text; - string s = text; - Assert.Equal (10, us.RuneCount); - Assert.Equal (10, s.Length); - // The reason is ustring index is related to byte length and not rune length - Assert.Equal (12, us.Length); - Assert.NotEqual (20320, us [9]); - Assert.Equal (20320, s [9]); - Assert.Equal (228, us [9]); - Assert.Equal ("ä", ((Rune)us [9]).ToString ()); - Assert.Equal ("你", s [9].ToString ()); - - // Rune array is equal to string array - var usToRunes = us.ToRunes (); - Assert.Equal (10, usToRunes.Length); - Assert.Equal (10, s.Length); - Assert.Equal (20320, (int)usToRunes [9]); - Assert.Equal (20320, s [9]); - Assert.Equal ("你", ((Rune)usToRunes [9]).ToString ()); - Assert.Equal ("你", s [9].ToString ()); + var usToRunes = text.ToRunes (); + Assert.Equal (runesLength, usToRunes.Length); + Assert.Equal (stringLength, text.Length); + Assert.Equal (runeValue, usToRunes [index].Value); + Assert.Equal (stringValue, text [index]); + Assert.Equal (expected, usToRunes [index].ToString ()); + if (char.IsHighSurrogate (text [index])) { + // Rune array length isn't equal to string array + Assert.Equal (expected, new string (new char [] { text [index], text [index + 1] })); + } else { + // Rune array length is equal to string array + Assert.Equal (expected, text [index].ToString ()); + } } } } \ No newline at end of file diff --git a/UnitTests/Text/UnicodeTests.cs b/UnitTests/Text/UnicodeTests.cs index 09aac7fd6..6d616ac6f 100644 --- a/UnitTests/Text/UnicodeTests.cs +++ b/UnitTests/Text/UnicodeTests.cs @@ -1,54 +1,24 @@ -using NStack; -using System; -using System.Collections.Generic; -using System.Linq; -using Terminal.Gui; -using Xunit; +using Xunit; using Xunit.Abstractions; // Alias Console to MockConsole so we don't accidentally use Console -using Console = Terminal.Gui.FakeConsole; -namespace Terminal.Gui.TextTests { - public class UnicodeTests { - readonly ITestOutputHelper output; +namespace Terminal.Gui.TextTests; +public class UnicodeTests { + readonly ITestOutputHelper _output; - public UnicodeTests (ITestOutputHelper output) - { - this.output = output; - } + public UnicodeTests (ITestOutputHelper output) + { + this._output = output; + } - [Theory] - [InlineData (0x0000001F, 0x241F)] - [InlineData (0x0000007F, 0x247F)] - [InlineData (0x0000009F, 0x249F)] - [InlineData (0x0001001A, 0x1001A)] - public void MakePrintable_Converts_Control_Chars_To_Proper_Unicode (uint code, uint expected) - { - var actual = ConsoleDriver.MakePrintable (code); - - Assert.Equal (expected, actual.Value); - } - - [Theory] - [InlineData (0x20)] - [InlineData (0x7E)] - [InlineData (0xA0)] - [InlineData (0x010020)] - public void MakePrintable_Does_Not_Convert_Ansi_Chars_To_Unicode (uint code) - { - var actual = ConsoleDriver.MakePrintable (code); - - Assert.Equal (code, actual.Value); - } - - [Fact, AutoInitShutdown] - public void AddRune_On_Clip_Left_Or_Right_Replace_Previous_Or_Next_Wide_Rune_With_Space () - { - var tv = new TextView () { - Width = Dim.Fill (), - Height = Dim.Fill (), - Text = @"これは広いルーンラインです。 + [Fact, AutoInitShutdown] + public void AddRune_On_Clip_Left_Or_Right_Replace_Previous_Or_Next_Wide_Rune_With_Space () + { + var tv = new TextView () { + Width = Dim.Fill (), + Height = Dim.Fill (), + Text = @"これは広いルーンラインです。 これは広いルーンラインです。 これは広いルーンラインです。 これは広いルーンラインです。 @@ -56,18 +26,18 @@ namespace Terminal.Gui.TextTests { これは広いルーンラインです。 これは広いルーンラインです。 これは広いルーンラインです。" - }; - var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (tv); - Application.Top.Add (win); - var lbl = new Label ("ワイドルーン。"); - var dg = new Dialog (new Button ("選ぶ")) { Width = 14, Height = 4 }; - dg.Add (lbl); - Application.Begin (Application.Top); - Application.Begin (dg); - ((FakeDriver)Application.Driver).SetBufferSize (30, 10); + }; + var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () }; + win.Add (tv); + Application.Top.Add (win); + var lbl = new Label ("ワイドルーン。"); + var dg = new Dialog (new Button ("選ぶ")) { Width = 14, Height = 4 }; + dg.Add (lbl); + Application.Begin (Application.Top); + Application.Begin (dg); + ((FakeDriver)Application.Driver).SetBufferSize (30, 10); - var expected = @$" + var expected = @$" ┌────────────────────────────┐ │これは広いルーンラインです。│ │これは広いルーンラインです。│ @@ -80,8 +50,7 @@ namespace Terminal.Gui.TextTests { └────────────────────────────┘ "; - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 30, 10), pos); - } + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + Assert.Equal (new Rect (0, 0, 30, 10), pos); } -} \ No newline at end of file +} diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 87c481f86..0519493bc 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Diagnostics; @@ -252,7 +252,7 @@ namespace UICatalog.Tests { _computedCheckBox = new CheckBox ("Computed Layout", true) { X = 0, Y = 0 }; _settingsPane.Add (_computedCheckBox); - var radioItems = new ustring [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" }; + var radioItems = new string [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" }; _locationFrame = new FrameView ("Location (Pos)") { X = Pos.Left (_computedCheckBox), Y = Pos.Bottom (_computedCheckBox), @@ -272,7 +272,7 @@ namespace UICatalog.Tests { _locationFrame.Add (_xRadioGroup); - radioItems = new ustring [] { "Percent(y)", "AnchorEnd(y)", "Center", "At(y)" }; + radioItems = new string [] { "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 }; @@ -290,7 +290,7 @@ namespace UICatalog.Tests { Width = 40, }; - radioItems = new ustring [] { "Percent(width)", "Fill(width)", "Sized(width)" }; + radioItems = new string [] { "Percent(width)", "Fill(width)", "Sized(width)" }; label = new Label ("width:") { X = 0, Y = 0 }; _sizeFrame.Add (label); _wRadioGroup = new RadioGroup (radioItems) { @@ -301,7 +301,7 @@ namespace UICatalog.Tests { _sizeFrame.Add (_wText); _sizeFrame.Add (_wRadioGroup); - radioItems = new ustring [] { "Percent(height)", "Fill(height)", "Sized(height)" }; + radioItems = new string [] { "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 }; @@ -551,7 +551,7 @@ namespace UICatalog.Tests { // If the view supports a Text property, set it so we have something to look at if (view.GetType ().GetProperty ("Text") != null) { try { - view.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (view, new [] { ustring.Make ("Test Text") }); + view.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (view, new [] { "Test Text" }); } catch (TargetInvocationException e) { MessageBox.ErrorQuery ("Exception", e.InnerException.Message, "Ok"); view = null; @@ -560,8 +560,8 @@ namespace UICatalog.Tests { // If the view supports a Title property, set it so we have something to look at if (view != null && view.GetType ().GetProperty ("Title") != null) { - if (view.GetType ().GetProperty ("Title").PropertyType == typeof (ustring)) { - view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { ustring.Make ("Test Title") }); + if (view.GetType ().GetProperty ("Title").PropertyType == typeof (string)) { + view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { "Test Title" }); } else { view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { "Test Title" }); } @@ -569,7 +569,7 @@ namespace UICatalog.Tests { // If the view supports a Source property, set it so we have something to look at if (view != null && view.GetType ().GetProperty ("Source") != null && view.GetType ().GetProperty ("Source").PropertyType == typeof (Terminal.Gui.IListDataSource)) { - var source = new ListWrapper (new List () { ustring.Make ("Test Text #1"), ustring.Make ("Test Text #2"), ustring.Make ("Test Text #3") }); + var source = new ListWrapper (new List () { "Test Text #1", "Test Text #2", "Test Text #3" }); view?.GetType ().GetProperty ("Source")?.GetSetMethod ()?.Invoke (view, new [] { source }); } diff --git a/UnitTests/View/DrawTests.cs b/UnitTests/View/DrawTests.cs index 32096a712..3f700c2d7 100644 --- a/UnitTests/View/DrawTests.cs +++ b/UnitTests/View/DrawTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using Xunit; using Xunit.Abstractions; @@ -11,23 +11,23 @@ namespace Terminal.Gui.ViewsTests { { this.output = output; } - + // TODO: The tests below that use Label should use View instead. [Fact, AutoInitShutdown] public void Non_Bmp_ConsoleWidth_ColumnWidth_Equal_Two () { - ustring us = "\U0001d539"; - Rune r = 0x1d539; + string us = "\U0001d539"; + Rune r = (Rune)0x1d539; Assert.Equal ("𝔹", us); Assert.Equal ("𝔹", r.ToString ()); Assert.Equal (us, r.ToString ()); - Assert.Equal (2, us.ConsoleWidth); - Assert.Equal (2, Rune.ColumnWidth (r)); + Assert.Equal (2, us.GetColumns ()); + Assert.Equal (2, r.GetColumns ()); var win = new Window () { Title = us }; - var label = new Label (ustring.Make (r)); + var label = new Label (r.ToString ()); var tf = new TextField (us) { Y = 1, Width = 3 }; win.Add (label, tf); var top = Application.Top; @@ -64,18 +64,18 @@ namespace Terminal.Gui.ViewsTests { [Fact, AutoInitShutdown] public void CJK_Compatibility_Ideographs_ConsoleWidth_ColumnWidth_Equal_Two () { - ustring us = "\U0000f900"; - Rune r = 0xf900; + string us = "\U0000f900"; + Rune r = (Rune)0xf900; Assert.Equal ("豈", us); Assert.Equal ("豈", r.ToString ()); Assert.Equal (us, r.ToString ()); - Assert.Equal (2, us.ConsoleWidth); - Assert.Equal (2, Rune.ColumnWidth (r)); + Assert.Equal (2, us.GetColumns ()); + Assert.Equal (2, r.GetColumns ()); var win = new Window () { Title = us }; - var label = new Label (ustring.Make (r)); + var label = new Label (r.ToString ()); var tf = new TextField (us) { Y = 1, Width = 3 }; win.Add (label, tf); var top = Application.Top; diff --git a/UnitTests/View/FrameTests.cs b/UnitTests/View/FrameTests.cs index bad9a343e..25b3c6da2 100644 --- a/UnitTests/View/FrameTests.cs +++ b/UnitTests/View/FrameTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Xml.Linq; diff --git a/UnitTests/View/KeyboardTests.cs b/UnitTests/View/KeyboardTests.cs index db0043ded..6ddd755af 100644 --- a/UnitTests/View/KeyboardTests.cs +++ b/UnitTests/View/KeyboardTests.cs @@ -1,7 +1,7 @@ using System; using Xunit; using Xunit.Abstractions; -using NStack; +using System.Text; // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; @@ -104,7 +104,7 @@ namespace Terminal.Gui.ViewTests { public bool IsKeyDown { get; set; } public bool IsKeyPress { get; set; } public bool IsKeyUp { get; set; } - public override ustring Text { get; set; } + public override string Text { get; set; } public override bool OnKeyDown (KeyEvent keyEvent) { diff --git a/UnitTests/View/Layout/AbsoluteLayoutTests.cs b/UnitTests/View/Layout/AbsoluteLayoutTests.cs index 57a4e8388..d20cab9a9 100644 --- a/UnitTests/View/Layout/AbsoluteLayoutTests.cs +++ b/UnitTests/View/Layout/AbsoluteLayoutTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Xml.Linq; diff --git a/UnitTests/View/Layout/AutoSizeTests.cs b/UnitTests/View/Layout/AutoSizeTests.cs index a1a463dd5..9484c4c81 100644 --- a/UnitTests/View/Layout/AutoSizeTests.cs +++ b/UnitTests/View/Layout/AutoSizeTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using Xunit; @@ -259,7 +259,7 @@ namespace Terminal.Gui.ViewTests { Assert.False (view.AutoSize); Assert.Equal (new Rect (0, 0, 3, 1), view.Frame); Assert.Equal (new Size (3, 1), view.TextFormatter.Size); - Assert.Equal (new List () { "Vie" }, view.TextFormatter.Lines); + Assert.Equal (new List () { "Vie" }, view.TextFormatter.Lines); Assert.Equal (new Rect (0, 0, 10, 4), win.Frame); Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); var expected = @" @@ -279,7 +279,7 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (new Rect (0, 0, 0, 1), view.Frame); Assert.Equal (new Size (0, 1), view.TextFormatter.Size); - Assert.Equal (new List () { ustring.Empty }, view.TextFormatter.Lines); + Assert.Equal (new List () { string.Empty }, view.TextFormatter.Lines); expected = @" ┌────────┐ │ │ @@ -332,7 +332,7 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (new Rect (0, 0, 0, 1), view.Frame); Assert.Equal (new Size (0, 1), view.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Equal (new List () { ustring.Empty }, view.TextFormatter.Lines)); + var exception = Record.Exception (() => Assert.Equal (new List () { string.Empty }, view.TextFormatter.Lines)); Assert.Null (exception); expected = @" ┌────────┐ @@ -367,7 +367,7 @@ namespace Terminal.Gui.ViewTests { Assert.True (label.AutoSize); Assert.Equal (new Rect (0, 0, 5, 1), label.Frame); Assert.Equal (new Size (5, 1), label.TextFormatter.Size); - Assert.Equal (new List () { "Label" }, label.TextFormatter.Lines); + Assert.Equal (new List () { "Label" }, label.TextFormatter.Lines); Assert.Equal (new Rect (0, 0, 10, 4), win.Frame); Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); var expected = @" @@ -423,7 +423,7 @@ namespace Terminal.Gui.ViewTests { Assert.False (label.AutoSize); Assert.Equal (new Rect (0, 0, 3, 1), label.Frame); Assert.Equal (new Size (3, 1), label.TextFormatter.Size); - Assert.Equal (new List () { "Lab" }, label.TextFormatter.Lines); + Assert.Equal (new List () { "Lab" }, label.TextFormatter.Lines); Assert.Equal (new Rect (0, 0, 10, 4), win.Frame); Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); var expected = @" @@ -444,7 +444,7 @@ namespace Terminal.Gui.ViewTests { Assert.False (label.AutoSize); Assert.Equal (new Rect (0, 0, 0, 1), label.Frame); Assert.Equal (new Size (0, 1), label.TextFormatter.Size); - Assert.Equal (new List { ustring.Empty }, label.TextFormatter.Lines); + Assert.Equal (new List { string.Empty }, label.TextFormatter.Lines); expected = @" ┌────────┐ │ │ @@ -477,7 +477,7 @@ namespace Terminal.Gui.ViewTests { Assert.True (label.AutoSize); Assert.Equal (new Rect (0, 0, 5, 1), label.Frame); Assert.Equal (new Size (5, 1), label.TextFormatter.Size); - Assert.Equal (new List () { "Label" }, label.TextFormatter.Lines); + Assert.Equal (new List () { "Label" }, label.TextFormatter.Lines); Assert.Equal (new Rect (0, 0, 10, 4), win.Frame); Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); var expected = @" @@ -552,7 +552,7 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (new Rect (0, 0, 0, 1), label.Frame); Assert.Equal (new Size (0, 1), label.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Equal (new List () { ustring.Empty }, label.TextFormatter.Lines)); + var exception = Record.Exception (() => Assert.Equal (new List () { string.Empty }, label.TextFormatter.Lines)); Assert.Null (exception); expected = @" ┌────────┐ @@ -588,7 +588,7 @@ namespace Terminal.Gui.ViewTests { Assert.True (view.AutoSize); Assert.Equal (new Rect (0, 0, 1, 5), view.Frame); Assert.Equal (new Size (1, 5), view.TextFormatter.Size); - Assert.Equal (new List () { "Views" }, view.TextFormatter.Lines); + Assert.Equal (new List () { "Views" }, view.TextFormatter.Lines); Assert.Equal (new Rect (0, 0, 4, 10), win.Frame); Assert.Equal (new Rect (0, 0, 4, 10), Application.Top.Frame); var expected = @" @@ -681,7 +681,7 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (new Rect (0, 0, 1, 0), view.Frame); Assert.Equal (new Size (1, 0), view.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Equal (new List () { ustring.Empty }, view.TextFormatter.Lines)); + var exception = Record.Exception (() => Assert.Equal (new List () { string.Empty }, view.TextFormatter.Lines)); Assert.Null (exception); expected = @" ┌──┐ @@ -723,7 +723,7 @@ namespace Terminal.Gui.ViewTests { Assert.True (view.AutoSize); Assert.Equal (new Rect (0, 0, 2, 5), view.Frame); Assert.Equal (new Size (2, 5), view.TextFormatter.Size); - Assert.Equal (new List () { "界View" }, view.TextFormatter.Lines); + Assert.Equal (new List () { "界View" }, view.TextFormatter.Lines); Assert.Equal (new Rect (0, 0, 4, 10), win.Frame); Assert.Equal (new Rect (0, 0, 4, 10), Application.Top.Frame); var expected = @" @@ -749,7 +749,7 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (new Rect (0, 0, 2, 5), view.Frame); Assert.Equal (new Size (2, 5), view.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Equal (new List () { "界View" }, view.TextFormatter.Lines)); + var exception = Record.Exception (() => Assert.Equal (new List () { "界View" }, view.TextFormatter.Lines)); Assert.Null (exception); expected = @" ┌──┐ @@ -816,7 +816,7 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (new Rect (0, 0, 2, 0), view.Frame); Assert.Equal (new Size (2, 0), view.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Equal (new List () { ustring.Empty }, view.TextFormatter.Lines)); + var exception = Record.Exception (() => Assert.Equal (new List () { string.Empty }, view.TextFormatter.Lines)); Assert.Null (exception); expected = @" ┌──┐ diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index 7a77c0a33..e4ba06055 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -1187,7 +1187,7 @@ namespace Terminal.Gui.ViewTests { if (listLabels.Count > 0) field.Text = listLabels [count - 1].Text; else - field.Text = NStack.ustring.Empty; + field.Text = string.Empty; } Assert.Equal ($"Absolute({count + 1})", view.Height.ToString ()); } diff --git a/UnitTests/View/Layout/LayoutTests.cs b/UnitTests/View/Layout/LayoutTests.cs index 410f579f8..2734bf313 100644 --- a/UnitTests/View/Layout/LayoutTests.cs +++ b/UnitTests/View/Layout/LayoutTests.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using Xunit; using Xunit.Abstractions; @@ -984,14 +985,14 @@ Y var horizontalView = new View () { Id = "horizontalView", AutoSize = true, - HotKeySpecifier = '_', + HotKeySpecifier = (Rune)'_', Text = text }; var verticalView = new View () { Id = "verticalView", Y = 3, AutoSize = true, - HotKeySpecifier = '_', + HotKeySpecifier = (Rune)'_', Text = text, TextDirection = TextDirection.TopBottom_LeftRight }; diff --git a/UnitTests/View/NavigationTests.cs b/UnitTests/View/NavigationTests.cs index d8d420f3b..d7f7ba809 100644 --- a/UnitTests/View/NavigationTests.cs +++ b/UnitTests/View/NavigationTests.cs @@ -1,7 +1,7 @@ using System; using Xunit; using Xunit.Abstractions; -using NStack; +using System.Text; // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; diff --git a/UnitTests/View/TitleTests.cs b/UnitTests/View/TitleTests.cs index 5ea688698..a2d96fdea 100644 --- a/UnitTests/View/TitleTests.cs +++ b/UnitTests/View/TitleTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Collections.Generic; using System.Xml.Linq; @@ -22,7 +22,7 @@ namespace Terminal.Gui.ViewTests { public void Set_Title_Fires_TitleChanging () { var r = new View (); - Assert.Equal (ustring.Empty, r.Title); + Assert.Equal (string.Empty, r.Title); string expectedOld = null; string expectedDuring = null; @@ -55,7 +55,7 @@ namespace Terminal.Gui.ViewTests { public void Set_Title_Fires_TitleChanged () { var r = new View (); - Assert.Equal (ustring.Empty, r.Title); + Assert.Equal (string.Empty, r.Title); string expectedOld = null; string expected = null; diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index 39301c54e..7c3a862dc 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -1,7 +1,7 @@ using System; using Xunit; using Xunit.Abstractions; -using NStack; +using System.Text; // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; @@ -820,13 +820,13 @@ namespace Terminal.Gui.ViewTests { var horizontalView = new View () { Text = text, AutoSize = true, - HotKeySpecifier = '_' + HotKeySpecifier = (Rune)'_' }; var verticalView = new View () { Text = text, AutoSize = true, - HotKeySpecifier = '_', + HotKeySpecifier = (Rune)'_', TextDirection = TextDirection.TopBottom_LeftRight }; Application.Top.Add (horizontalView, verticalView); @@ -1022,7 +1022,7 @@ cccccccccccccccccccc", output); public bool IsKeyDown { get; set; } public bool IsKeyPress { get; set; } public bool IsKeyUp { get; set; } - public override ustring Text { get; set; } + public override string Text { get; set; } public override bool OnKeyDown (KeyEvent keyEvent) { @@ -1051,7 +1051,7 @@ cccccccccccccccccccc", output); if (idx < Text.Length) { var rune = Text [idx]; if (rune != '\n') { - AddRune (c, r, Text [idx]); + AddRune (c, r, (Rune)Text [idx]); } idx++; if (rune == '\n') { diff --git a/UnitTests/Views/AllViewsTests.cs b/UnitTests/Views/AllViewsTests.cs index 4377c7df0..ed133c90f 100644 --- a/UnitTests/Views/AllViewsTests.cs +++ b/UnitTests/Views/AllViewsTests.cs @@ -87,8 +87,8 @@ namespace Terminal.Gui.ViewsTests { { if (paramType == typeof (Rect)) { pTypes.Add (Rect.Empty); - } else if (paramType == typeof (NStack.ustring)) { - pTypes.Add (NStack.ustring.Empty); + } else if (paramType == typeof (string)) { + pTypes.Add (string.Empty); } else if (paramType == typeof (int)) { pTypes.Add (0); } else if (paramType == typeof (bool)) { diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs index 8e5973b1d..61c831671 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/UnitTests/Views/ButtonTests.cs @@ -22,7 +22,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal ($"{CM.Glyphs.LeftBracket} {CM.Glyphs.RightBracket}", btn.TextFormatter.Text); Assert.False (btn.IsDefault); Assert.Equal (TextAlignment.Centered, btn.TextAlignment); - Assert.Equal ('_', btn.HotKeySpecifier); + Assert.Equal ('_', btn.HotKeySpecifier.Value); Assert.True (btn.CanFocus); Assert.Equal (new Rect (0, 0, 4, 1), btn.Bounds); Assert.Equal (new Rect (0, 0, 4, 1), btn.Frame); @@ -41,7 +41,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal ($"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Test {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}", btn.TextFormatter.Text); Assert.True (btn.IsDefault); Assert.Equal (TextAlignment.Centered, btn.TextAlignment); - Assert.Equal ('_', btn.HotKeySpecifier); + Assert.Equal ('_', btn.HotKeySpecifier.Value); Assert.True (btn.CanFocus); Assert.Equal (new Rect (0, 0, 10, 1), btn.Bounds); Assert.Equal (new Rect (0, 0, 10, 1), btn.Frame); @@ -56,7 +56,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal ($"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Test {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}", btn.TextFormatter.Text); Assert.True (btn.IsDefault); Assert.Equal (TextAlignment.Centered, btn.TextAlignment); - Assert.Equal ('_', btn.HotKeySpecifier); + Assert.Equal ('_', btn.HotKeySpecifier.Value); Assert.True (btn.CanFocus); Assert.Equal (new Rect (0, 0, 10, 1), btn.Bounds); Assert.Equal (new Rect (3, 4, 10, 1), btn.Frame); @@ -172,10 +172,10 @@ namespace Terminal.Gui.ViewsTests { { View b = new Button () { Text = "heya" }; Assert.Equal ("heya", b.Text); - Assert.True (b.TextFormatter.Text.Contains ("heya")); + Assert.Contains ("heya", b.TextFormatter.Text); b.Text = "heyb"; Assert.Equal ("heyb", b.Text); - Assert.True (b.TextFormatter.Text.Contains ("heyb")); + Assert.Contains ("heyb", b.TextFormatter.Text); // with cast Assert.Equal ("heyb", ((Button)b).Text); @@ -365,7 +365,7 @@ namespace Terminal.Gui.ViewsTests { }; var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}"; - btn.X = Pos.AnchorEnd () - Pos.Function (() => TextFormatter.GetTextWidth (btn.TextFormatter.Text)); + btn.X = Pos.AnchorEnd () - Pos.Function (() => btn.TextFormatter.Text.GetColumns ()); var win = new Window () { Width = Dim.Fill (), @@ -430,7 +430,7 @@ namespace Terminal.Gui.ViewsTests { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (label), Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty (txtToFind.Text), TextAlignment = TextAlignment.Centered, IsDefault = true, AutoSize = false @@ -441,7 +441,7 @@ namespace Terminal.Gui.ViewsTests { X = Pos.Right (txtToFind) + 1, Y = Pos.Top (btnFindNext) + 1, Width = 20, - Enabled = !txtToFind.Text.IsEmpty, + Enabled = !string.IsNullOrEmpty (txtToFind.Text), TextAlignment = TextAlignment.Centered, AutoSize = false }; diff --git a/UnitTests/Views/GraphViewTests.cs b/UnitTests/Views/GraphViewTests.cs index a4e780483..b954632b8 100644 --- a/UnitTests/Views/GraphViewTests.cs +++ b/UnitTests/Views/GraphViewTests.cs @@ -8,7 +8,7 @@ using Attribute = Terminal.Gui.Attribute; using System.Text; using System.Text.RegularExpressions; using Xunit.Abstractions; -using Rune = System.Rune; + namespace Terminal.Gui.ViewsTests { @@ -592,7 +592,7 @@ namespace Terminal.Gui.ViewsTests { // user asks for 3 bars per category var series = new MultiBarSeries (3, 7, 1); - var ex = Assert.Throws (() => series.AddBars ("Cars", '#', 1)); + var ex = Assert.Throws (() => series.AddBars ("Cars", (Rune)'#', 1)); Assert.Equal ("Number of values must match the number of bars per category (Parameter 'values')", ex.Message); } @@ -636,15 +636,15 @@ namespace Terminal.Gui.ViewsTests { // Since bar series has no bars yet no labels should be displayed Assert.Empty (fakeXAxis.LabelPoints); - multibarSeries.AddBars ("hey", 'M', 0.5001f, 0.5001f); + multibarSeries.AddBars ("hey", (Rune)'M', 0.5001f, 0.5001f); fakeXAxis.LabelPoints.Clear (); gv.LayoutSubviews (); gv.Draw (); Assert.Equal (4, fakeXAxis.LabelPoints.Single ()); - multibarSeries.AddBars ("there", 'M', 0.24999f, 0.74999f); - multibarSeries.AddBars ("bob", 'M', 1, 2); + multibarSeries.AddBars ("there", (Rune)'M', 0.24999f, 0.74999f); + multibarSeries.AddBars ("bob", (Rune)'M', 1, 2); fakeXAxis.LabelPoints.Clear (); gv.LayoutSubviews (); gv.Draw (); @@ -711,7 +711,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Empty (axisY.LabelPoints); // bar of height 0 - barSeries.Bars.Add (new BarSeries.Bar ("hi", new GraphCellToRender ('.'), 0)); + barSeries.Bars.Add (new BarSeries.Bar ("hi", new GraphCellToRender ((Rune)'.'), 0)); barSeries.Orientation = Orientation.Vertical; // redraw graph @@ -753,9 +753,9 @@ namespace Terminal.Gui.ViewsTests { barSeries.BarEvery = 1f; barSeries.Bars.Add ( - new BarSeries.Bar ("hi1", new GraphCellToRender ('.'), 100)); + new BarSeries.Bar ("hi1", new GraphCellToRender ((Rune)'.'), 100)); barSeries.Bars.Add ( - new BarSeries.Bar ("hi2", new GraphCellToRender ('.'), 100)); + new BarSeries.Bar ("hi2", new GraphCellToRender ((Rune)'.'), 100)); barSeries.Orientation = Orientation.Vertical; @@ -809,11 +809,11 @@ namespace Terminal.Gui.ViewsTests { // 1 bar that is very wide (100 graph units horizontally = screen pos 50 but bounded by screen) barSeries.Bars.Add ( - new BarSeries.Bar ("hi1", new GraphCellToRender ('.'), 100)); + new BarSeries.Bar ("hi1", new GraphCellToRender ((Rune)'.'), 100)); // 1 bar that is shorter barSeries.Bars.Add ( - new BarSeries.Bar ("hi2", new GraphCellToRender ('.'), 5)); + new BarSeries.Bar ("hi2", new GraphCellToRender ((Rune)'.'), 5)); // redraw graph graph.Draw (); @@ -1263,8 +1263,8 @@ namespace Terminal.Gui.ViewsTests { { var gv = GraphViewTests.GetGraph (); var legend = new LegendAnnotation (new Rect (2, 0, 5, 3)); - legend.AddEntry (new GraphCellToRender ('A'), "Ant"); - legend.AddEntry (new GraphCellToRender ('B'), "Bat"); + legend.AddEntry (new GraphCellToRender ((Rune)'A'), "Ant"); + legend.AddEntry (new GraphCellToRender ((Rune)'B'), "Bat"); gv.Annotations.Add (legend); gv.Draw (); @@ -1288,10 +1288,10 @@ namespace Terminal.Gui.ViewsTests { { var gv = GraphViewTests.GetGraph (); var legend = new LegendAnnotation (new Rect (2, 0, 5, 3)); - legend.AddEntry (new GraphCellToRender ('A'), "Ant"); - legend.AddEntry (new GraphCellToRender ('B'), "?"); // this will exercise pad - legend.AddEntry (new GraphCellToRender ('C'), "Cat"); - legend.AddEntry (new GraphCellToRender ('H'), "Hattter"); // not enough space for this oen + legend.AddEntry (new GraphCellToRender ((Rune)'A'), "Ant"); + legend.AddEntry (new GraphCellToRender ((Rune)'B'), "?"); // this will exercise pad + legend.AddEntry (new GraphCellToRender ((Rune)'C'), "Cat"); + legend.AddEntry (new GraphCellToRender ((Rune)'H'), "Hattter"); // not enough space for this oen legend.Border = false; gv.Annotations.Add (legend); diff --git a/UnitTests/Views/LabelTests.cs b/UnitTests/Views/LabelTests.cs index b9b7612f9..eef07ba74 100644 --- a/UnitTests/Views/LabelTests.cs +++ b/UnitTests/Views/LabelTests.cs @@ -62,10 +62,10 @@ Test { View b = new Label () { Text = "heya" }; Assert.Equal ("heya", b.Text); - Assert.True (b.TextFormatter.Text.Contains ("heya")); + Assert.Contains ("heya", b.TextFormatter.Text); b.Text = "heyb"; Assert.Equal ("heyb", b.Text); - Assert.True (b.TextFormatter.Text.Contains ("heyb")); + Assert.Contains ("heyb", b.TextFormatter.Text); // with cast Assert.Equal ("heyb", ((Label)b).Text); @@ -232,7 +232,7 @@ Test Text = "Say Hello 你", AutoSize = true }; - label.X = Pos.AnchorEnd () - Pos.Function (() => TextFormatter.GetTextWidth (label.TextFormatter.Text)); + label.X = Pos.AnchorEnd () - Pos.Function (() => label.TextFormatter.Text.GetColumns ()); var win = new Window () { Width = Dim.Fill (), diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs index 69503c7be..ff011910f 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/UnitTests/Views/ListViewTests.cs @@ -480,7 +480,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (1, lw.StartsWith ("TW")); Assert.Equal (2, lw.StartsWith ("TH")); - lw = new ListWrapper (new List { "One", "Two", "Three" }); + lw = new ListWrapper (new List { "One", "Two", "Three" }); Assert.Equal (1, lw.StartsWith ("t")); Assert.Equal (1, lw.StartsWith ("tw")); diff --git a/UnitTests/Views/MenuTests.cs b/UnitTests/Views/MenuTests.cs index 00d0b84af..661ad0bed 100644 --- a/UnitTests/Views/MenuTests.cs +++ b/UnitTests/Views/MenuTests.cs @@ -1999,10 +1999,10 @@ Edit }; mi.Action = mi.ToggleChecked; var menu = new MenuBar (new MenuBarItem [] { - new MenuBarItem("Nullable Checked",new MenuItem [] { - mi - }) - }); + new MenuBarItem("Nullable Checked",new MenuItem [] { + mi + }) + }); new CheckBox (); var top = Application.Top; top.Add (menu); @@ -2086,12 +2086,12 @@ Edit public void Menu_With_Separator () { var menu = new MenuBar (new MenuBarItem [] { - new MenuBarItem("File",new MenuItem [] { - new MenuItem("_Open", "Open a file", () => { }, null, null, Key.CtrlMask | Key.O), - null, - new MenuItem("_Quit","",null) - }) - }); + new MenuBarItem("File",new MenuItem [] { + new MenuItem("_Open", "Open a file", () => { }, null, null, Key.CtrlMask | Key.O), + null, + new MenuItem("_Quit","",null) + }) + }); Application.Top.Add (menu); Application.Begin (Application.Top); diff --git a/UnitTests/Views/ProgressBarTests.cs b/UnitTests/Views/ProgressBarTests.cs index e3e5e7358..841ffafac 100644 --- a/UnitTests/Views/ProgressBarTests.cs +++ b/UnitTests/Views/ProgressBarTests.cs @@ -178,7 +178,7 @@ namespace Terminal.Gui.ViewsTests { pb.Pulse (); pb.Draw (); if (i == 0) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); @@ -194,8 +194,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 1) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); @@ -210,9 +210,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 2) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); @@ -226,10 +226,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 3) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); @@ -242,11 +242,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 4) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); @@ -259,11 +259,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 5) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); @@ -276,11 +276,11 @@ namespace Terminal.Gui.ViewsTests { } else if (i == 6) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); @@ -293,11 +293,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); @@ -310,11 +310,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); @@ -327,11 +327,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); @@ -344,11 +344,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); @@ -361,11 +361,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); @@ -378,11 +378,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 13) { @@ -395,11 +395,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 14) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); @@ -412,11 +412,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 15) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -429,10 +429,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 16) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -446,9 +446,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 17) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -463,8 +463,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 18) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -480,7 +480,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 19) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -495,8 +495,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 20) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -510,9 +510,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 21) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -525,10 +525,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 22) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -540,11 +540,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 23) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -555,11 +555,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 24) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); @@ -570,11 +570,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 25) { @@ -585,11 +585,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); @@ -600,11 +600,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); @@ -615,11 +615,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); @@ -630,11 +630,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); @@ -645,11 +645,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); @@ -660,11 +660,11 @@ namespace Terminal.Gui.ViewsTests { } else if (i == 30) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); @@ -675,11 +675,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 31) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); @@ -690,11 +690,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 32) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); @@ -706,10 +706,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 33) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); @@ -722,9 +722,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 34) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); @@ -738,8 +738,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 35) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); @@ -754,7 +754,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 36) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); @@ -770,8 +770,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 37) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); @@ -808,7 +808,7 @@ namespace Terminal.Gui.ViewsTests { pb.Pulse (); pb.Draw (); if (i == 0) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); @@ -824,8 +824,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 1) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); @@ -840,9 +840,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 2) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); @@ -856,10 +856,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 3) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); @@ -872,11 +872,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 4) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); @@ -889,11 +889,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 5) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); @@ -906,11 +906,11 @@ namespace Terminal.Gui.ViewsTests { } else if (i == 6) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); @@ -923,11 +923,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); @@ -940,11 +940,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); @@ -957,11 +957,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); @@ -974,11 +974,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); @@ -991,11 +991,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); @@ -1008,11 +1008,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 13) { @@ -1025,11 +1025,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 14) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); @@ -1042,11 +1042,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 15) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1059,10 +1059,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 16) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1076,9 +1076,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 17) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1093,8 +1093,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 18) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1110,9 +1110,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 19) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); @@ -1128,8 +1128,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 20) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); @@ -1144,9 +1144,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 21) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); @@ -1160,10 +1160,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 22) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); @@ -1176,11 +1176,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 23) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); @@ -1193,11 +1193,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 24) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); @@ -1210,11 +1210,11 @@ namespace Terminal.Gui.ViewsTests { } else if (i == 25) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); @@ -1227,11 +1227,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); @@ -1244,11 +1244,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); @@ -1261,11 +1261,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 5, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); @@ -1278,11 +1278,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 6, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); @@ -1295,11 +1295,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 7, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); @@ -1312,11 +1312,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 8, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 32) { @@ -1329,11 +1329,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 6, 0]); Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 9, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); Assert.Equal (' ', (double)driver.Contents [0, 14, 0]); } else if (i == 33) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); @@ -1346,11 +1346,11 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 7, 0]); Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 10, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 34) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1363,10 +1363,10 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 8, 0]); Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 11, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 35) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1380,9 +1380,9 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 9, 0]); Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 12, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 36) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1397,8 +1397,8 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 10, 0]); Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 13, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } else if (i == 37) { Assert.Equal (' ', (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); @@ -1414,7 +1414,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (' ', (double)driver.Contents [0, 11, 0]); Assert.Equal (' ', (double)driver.Contents [0, 12, 0]); Assert.Equal (' ', (double)driver.Contents [0, 13, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 14, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 14, 0]); } } } @@ -1436,46 +1436,46 @@ namespace Terminal.Gui.ViewsTests { pb.Fraction += 0.2F; pb.Draw (); if (i == 0) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); Assert.Equal (' ', (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); } else if (i == 1) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); Assert.Equal (' ', (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); } else if (i == 2) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); Assert.Equal (' ', (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); } else if (i == 3) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); Assert.Equal (' ', (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); } else if (i == 4) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); } else if (i == 5) { - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 0, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 1, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 2, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 3, 0]); - Assert.Equal (CM.Glyphs.BlocksMeterSegment, (double)driver.Contents [0, 4, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 0, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 1, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 2, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 3, 0]); + Assert.Equal (CM.Glyphs.BlocksMeterSegment.Value, (double)driver.Contents [0, 4, 0]); Assert.Equal (' ', (double)driver.Contents [0, 5, 0]); } } diff --git a/UnitTests/Views/RadioGroupTests.cs b/UnitTests/Views/RadioGroupTests.cs index 6c49e962d..381cd3a90 100644 --- a/UnitTests/Views/RadioGroupTests.cs +++ b/UnitTests/Views/RadioGroupTests.cs @@ -28,7 +28,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (Rect.Empty, rg.Frame); Assert.Equal (0, rg.SelectedItem); - rg = new RadioGroup (new NStack.ustring [] { "Test" }); + rg = new RadioGroup (new string [] { "Test" }); Assert.True (rg.CanFocus); Assert.Single (rg.RadioLabels); Assert.Null (rg.X); @@ -38,7 +38,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (new Rect (0, 0, 0, 0), rg.Frame); Assert.Equal (0, rg.SelectedItem); - rg = new RadioGroup (new Rect (1, 2, 20, 5), new NStack.ustring [] { "Test" }); + rg = new RadioGroup (new Rect (1, 2, 20, 5), new string [] { "Test" }); Assert.True (rg.CanFocus); Assert.Single (rg.RadioLabels); Assert.Equal (LayoutStyle.Absolute, rg.LayoutStyle); @@ -49,7 +49,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (new Rect (1, 2, 20, 5), rg.Frame); Assert.Equal (0, rg.SelectedItem); - rg = new RadioGroup (1, 2, new NStack.ustring [] { "Test" }); + rg = new RadioGroup (1, 2, new string [] { "Test" }); Assert.True (rg.CanFocus); Assert.Single (rg.RadioLabels); Assert.Equal (LayoutStyle.Absolute, rg.LayoutStyle); @@ -64,7 +64,7 @@ namespace Terminal.Gui.ViewsTests { [Fact] public void Initialize_SelectedItem_With_Minus_One () { - var rg = new RadioGroup (new NStack.ustring [] { "Test" }, -1); + var rg = new RadioGroup (new string [] { "Test" }, -1); Assert.Equal (-1, rg.SelectedItem); Assert.True (rg.ProcessKey (new KeyEvent (Key.Space, new KeyModifiers ()))); Assert.Equal (0, rg.SelectedItem); @@ -73,7 +73,7 @@ namespace Terminal.Gui.ViewsTests { [Fact, AutoInitShutdown] public void DisplayMode_Width_Height_Vertical_Horizontal_Space () { - var rg = new RadioGroup (new NStack.ustring [] { "Test", "New Test 你" }); + var rg = new RadioGroup (new string [] { "Test", "New Test 你" }); var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () @@ -148,7 +148,7 @@ namespace Terminal.Gui.ViewsTests { { var previousSelectedItem = -1; var selectedItem = -1; - var rg = new RadioGroup (new NStack.ustring [] { "Test", "New Test" }); + var rg = new RadioGroup (new string [] { "Test", "New Test" }); rg.SelectedItemChanged += (s,e) => { previousSelectedItem = e.PreviousSelectedItem; selectedItem = e.SelectedItem; @@ -162,7 +162,7 @@ namespace Terminal.Gui.ViewsTests { [Fact] public void KeyBindings_Command () { - var rg = new RadioGroup (new NStack.ustring [] { "Test", "New Test" }); + var rg = new RadioGroup (new string [] { "Test", "New Test" }); Assert.True (rg.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()))); Assert.True (rg.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()))); @@ -175,7 +175,7 @@ namespace Terminal.Gui.ViewsTests { [Fact] public void ProcessColdKey_HotKey () { - var rg = new RadioGroup (new NStack.ustring [] { "Left", "Right", "Cen_tered", "Justified" }); + var rg = new RadioGroup (new string [] { "Left", "Right", "Cen_tered", "Justified" }); Assert.True (rg.ProcessColdKey (new KeyEvent (Key.t, new KeyModifiers ()))); Assert.Equal (2, rg.SelectedItem); diff --git a/UnitTests/Views/ScrollViewTests.cs b/UnitTests/Views/ScrollViewTests.cs index a9cde6345..76815d1a8 100644 --- a/UnitTests/Views/ScrollViewTests.cs +++ b/UnitTests/Views/ScrollViewTests.cs @@ -1,5 +1,5 @@ using Microsoft.VisualStudio.TestPlatform.Utilities; -using NStack; +using System.Text; using Xunit; using Xunit.Abstractions; @@ -423,7 +423,7 @@ namespace Terminal.Gui.ViewsTests { // private Label labelFill; // private Label labelText; - // public CustomButton (string fill, ustring text, int width, int height) : base () + // public CustomButton (string fill, string text, int width, int height) : base () // { // Width = width; // Height = height; diff --git a/UnitTests/Views/TableViewTests.cs b/UnitTests/Views/TableViewTests.cs index ecddcf112..ad34e26f0 100644 --- a/UnitTests/Views/TableViewTests.cs +++ b/UnitTests/Views/TableViewTests.cs @@ -156,13 +156,13 @@ namespace Terminal.Gui.ViewsTests { [Fact] public void Test_SumColumnWidth_UnicodeLength () { - Assert.Equal (11, "hello there".Sum (c => Rune.ColumnWidth (c))); + Assert.Equal (11, "hello there".EnumerateRunes ().Sum (c => c.GetColumns ())); // Creates a string with the peculiar (french?) r symbol String surrogate = "Les Mise" + Char.ConvertFromUtf32 (Int32.Parse ("0301", NumberStyles.HexNumber)) + "rables"; // The unicode width of this string is shorter than the string length! - Assert.Equal (14, surrogate.Sum (c => Rune.ColumnWidth (c))); + Assert.Equal (14, surrogate.EnumerateRunes ().Sum (c => c.GetColumns ())); Assert.Equal (15, surrogate.Length); } diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index 502dcda8a..7145d10ed 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -1,4 +1,4 @@ -using NStack; +using System.Text; using System; using System.Globalization; using System.Linq; @@ -94,9 +94,9 @@ namespace Terminal.Gui.ViewsTests { { _textField.SelectedStart = 19; _textField.CursorPosition = 12; - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u - Assert.Equal ("TAB to jump u text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump u text fields.", _textField.Text); } [Fact] @@ -610,13 +610,13 @@ namespace Terminal.Gui.ViewsTests { _textField.CursorPosition = 24; _textField.Copy (); Assert.Equal ("text", _textField.SelectedText); - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.Paste (); - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.SelectedStart = 20; _textField.Cut (); _textField.Paste (); - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); } [Fact] @@ -627,17 +627,17 @@ namespace Terminal.Gui.ViewsTests { _textField.CursorPosition = 24; _textField.Copy (); Assert.Equal ("text", _textField.SelectedText); - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.SelectedStart = -1; _textField.Paste (); - Assert.Equal ("TAB to jump between texttext fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between texttext fields.", _textField.Text); _textField.SelectedStart = 24; _textField.Cut (); Assert.Null (_textField.SelectedText); - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.SelectedStart = -1; _textField.Paste (); - Assert.Equal ("TAB to jump between texttext fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between texttext fields.", _textField.Text); } [Fact] @@ -684,10 +684,10 @@ namespace Terminal.Gui.ViewsTests { }; _textField.Text = "changing"; - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); cancel = false; _textField.Text = "changing"; - Assert.Equal ("changing", _textField.Text.ToString ()); + Assert.Equal ("changing", _textField.Text); } [Fact] @@ -699,7 +699,7 @@ namespace Terminal.Gui.ViewsTests { }; _textField.Text = "changed"; - Assert.Equal ("changed", _textField.Text.ToString ()); + Assert.Equal ("changed", _textField.Text); } [Fact] @@ -707,15 +707,15 @@ namespace Terminal.Gui.ViewsTests { public void Used_Is_True_By_Default () { _textField.CursorPosition = 10; - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u - Assert.Equal ("TAB to jumup between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumup between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x73, new KeyModifiers ())); // s - Assert.Equal ("TAB to jumusp between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumusp between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x65, new KeyModifiers ())); // e - Assert.Equal ("TAB to jumusep between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumusep between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x64, new KeyModifiers ())); // d - Assert.Equal ("TAB to jumusedp between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumusedp between text fields.", _textField.Text); } [Fact] @@ -724,15 +724,15 @@ namespace Terminal.Gui.ViewsTests { { _textField.Used = false; _textField.CursorPosition = 10; - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u - Assert.Equal ("TAB to jumu between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumu between text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x73, new KeyModifiers ())); // s - Assert.Equal ("TAB to jumusbetween text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumusbetween text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x65, new KeyModifiers ())); // e - Assert.Equal ("TAB to jumuseetween text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumuseetween text fields.", _textField.Text); _textField.ProcessKey (new KeyEvent ((Key)0x64, new KeyModifiers ())); // d - Assert.Equal ("TAB to jumusedtween text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jumusedtween text fields.", _textField.Text); } [Fact] @@ -740,22 +740,22 @@ namespace Terminal.Gui.ViewsTests { { var tf = new TextField ("ABC"); tf.EnsureFocus (); - Assert.Equal ("ABC", tf.Text.ToString ()); + Assert.Equal ("ABC", tf.Text); Assert.Equal (3, tf.CursorPosition); // now delete the C tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("AB", tf.Text.ToString ()); + Assert.Equal ("AB", tf.Text); Assert.Equal (2, tf.CursorPosition); // then delete the B tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("A", tf.Text.ToString ()); + Assert.Equal ("A", tf.Text); Assert.Equal (1, tf.CursorPosition); // then delete the A tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("", tf.Text.ToString ()); + Assert.Equal ("", tf.Text); Assert.Equal (0, tf.CursorPosition); } @@ -765,24 +765,24 @@ namespace Terminal.Gui.ViewsTests { var tf = new TextField ("ABC"); tf.EnsureFocus (); tf.CursorPosition = 2; - Assert.Equal ("ABC", tf.Text.ToString ()); + Assert.Equal ("ABC", tf.Text); // now delete the B tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("AC", tf.Text.ToString ()); + Assert.Equal ("AC", tf.Text); // then delete the A tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("C", tf.Text.ToString ()); + Assert.Equal ("C", tf.Text); // then delete nothing tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("C", tf.Text.ToString ()); + Assert.Equal ("C", tf.Text); // now delete the C tf.CursorPosition = 1; tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("", tf.Text.ToString ()); + Assert.Equal ("", tf.Text); } [Fact] @@ -791,19 +791,19 @@ namespace Terminal.Gui.ViewsTests { var tf = new TextField (); tf.EnsureFocus (); tf.ProcessKey (new KeyEvent (Key.A, new KeyModifiers ())); - Assert.Equal ("A", tf.Text.ToString ()); + Assert.Equal ("A", tf.Text); // cancel the next keystroke tf.TextChanging += (s, e) => e.Cancel = e.NewText == "AB"; tf.ProcessKey (new KeyEvent (Key.B, new KeyModifiers ())); // B was canceled so should just be A - Assert.Equal ("A", tf.Text.ToString ()); + Assert.Equal ("A", tf.Text); // now delete the A tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())); - Assert.Equal ("", tf.Text.ToString ()); + Assert.Equal ("", tf.Text); } [Fact] @@ -811,11 +811,11 @@ namespace Terminal.Gui.ViewsTests { public void Text_Replaces_Tabs_With_Empty_String () { _textField.Text = "\t\tTAB to jump between text fields."; - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); _textField.Text = ""; Clipboard.Contents = "\t\tTAB to jump between text fields."; _textField.Paste (); - Assert.Equal ("TAB to jump between text fields.", _textField.Text.ToString ()); + Assert.Equal ("TAB to jump between text fields.", _textField.Text); } [Fact] @@ -923,201 +923,201 @@ namespace Terminal.Gui.ViewsTests { Assert.False (tf.ReadOnly); Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ()))); - Assert.Equal ("This is a test.", tf.Text.ToString ()); + Assert.Equal ("This is a test.", tf.Text); tf.CursorPosition = 0; Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ()))); - Assert.Equal ("his is a test.", tf.Text.ToString ()); + Assert.Equal ("his is a test.", tf.Text); tf.ReadOnly = true; Assert.True (tf.ProcessKey (new KeyEvent (Key.D | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("his is a test.", tf.Text.ToString ()); + Assert.Equal ("his is a test.", tf.Text); Assert.True (tf.ProcessKey (new KeyEvent (Key.Delete, new KeyModifiers ()))); - Assert.Equal ("his is a test.", tf.Text.ToString ()); + Assert.Equal ("his is a test.", tf.Text); tf.ReadOnly = false; tf.CursorPosition = 1; Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); tf.CursorPosition = 5; Assert.True (tf.ProcessKey (new KeyEvent (Key.Home | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is is", tf.SelectedText); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.Home | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is is", tf.SelectedText); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.A | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is is", tf.SelectedText); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.End | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (" a test.", tf.SelectedText); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.End | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (" a test.", tf.SelectedText); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.E | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (" a test.", tf.SelectedText); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.Home, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (0, tf.CursorPosition); tf.CursorPosition = 5; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.Home | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (0, tf.CursorPosition); tf.CursorPosition = 5; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.A | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (0, tf.CursorPosition); tf.CursorPosition = 5; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("s", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorUp | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("s", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorDown | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Null (tf.SelectedText); tf.CursorPosition = 7; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("a", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorUp | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is a", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'B' + Key.ShiftMask | Key.AltMask), new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is is a", tf.SelectedText); tf.CursorPosition = 3; tf.SelectedStart = -1; Assert.Null (tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is ", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorDown | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is a ", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'F' + Key.ShiftMask | Key.AltMask), new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal ("is a test.", tf.SelectedText); Assert.Equal (13, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Null (tf.SelectedText); Assert.Equal (12, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (11, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.End, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (13, tf.CursorPosition); tf.CursorPosition = 0; Assert.True (tf.ProcessKey (new KeyEvent (Key.End | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (13, tf.CursorPosition); tf.CursorPosition = 0; Assert.True (tf.ProcessKey (new KeyEvent (Key.E | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (13, tf.CursorPosition); tf.CursorPosition = 0; Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (1, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.F | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.Equal (2, tf.CursorPosition); tf.CursorPosition = 9; tf.ReadOnly = true; Assert.True (tf.ProcessKey (new KeyEvent (Key.K | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); tf.ReadOnly = false; Assert.True (tf.ProcessKey (new KeyEvent (Key.K | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); - Assert.Equal ("est.", Clipboard.Contents.ToString ()); + Assert.Equal ("is is a t", tf.Text); + Assert.Equal ("est.", Clipboard.Contents); Assert.True (tf.ProcessKey (new KeyEvent (Key.Z | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.True (tf.ProcessKey (new KeyEvent (Key.Y | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace | Key.AltMask, new KeyModifiers ()))); - Assert.Equal ("is is a test.", tf.Text.ToString ()); + Assert.Equal ("is is a test.", tf.Text); Assert.True (tf.ProcessKey (new KeyEvent (Key.Y | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (8, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorUp | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (6, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'B' + Key.AltMask), new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (3, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (6, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorDown | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (8, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'F' + Key.AltMask), new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (9, tf.CursorPosition); Assert.True (tf.Used); Assert.True (tf.ProcessKey (new KeyEvent (Key.InsertChar, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); + Assert.Equal ("is is a t", tf.Text); Assert.Equal (9, tf.CursorPosition); Assert.False (tf.Used); tf.SelectedStart = 3; tf.CursorPosition = 7; Assert.Equal ("is a", tf.SelectedText); - Assert.Equal ("est.", Clipboard.Contents.ToString ()); + Assert.Equal ("est.", Clipboard.Contents); Assert.True (tf.ProcessKey (new KeyEvent (Key.C | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); - Assert.Equal ("is a", Clipboard.Contents.ToString ()); + Assert.Equal ("is is a t", tf.Text); + Assert.Equal ("is a", Clipboard.Contents); Assert.True (tf.ProcessKey (new KeyEvent (Key.X | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is t", tf.Text.ToString ()); - Assert.Equal ("is a", Clipboard.Contents.ToString ()); + Assert.Equal ("is t", tf.Text); + Assert.Equal ("is a", Clipboard.Contents); Assert.True (tf.ProcessKey (new KeyEvent (Key.V | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("is is a t", tf.Text.ToString ()); - Assert.Equal ("is a", Clipboard.Contents.ToString ()); + Assert.Equal ("is is a t", tf.Text); + Assert.Equal ("is a", Clipboard.Contents); Assert.Equal (7, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.K | Key.AltMask, new KeyModifiers ()))); - Assert.Equal (" t", tf.Text.ToString ()); - Assert.Equal ("is is a", Clipboard.Contents.ToString ()); + Assert.Equal (" t", tf.Text); + Assert.Equal ("is is a", Clipboard.Contents); tf.Text = "TAB to jump between text fields."; Assert.Equal (0, tf.CursorPosition); Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("to jump between text fields.", tf.Text.ToString ()); + Assert.Equal ("to jump between text fields.", tf.Text); tf.CursorPosition = tf.Text.Length; Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace | Key.CtrlMask, new KeyModifiers ()))); - Assert.Equal ("to jump between text fields", tf.Text.ToString ()); + Assert.Equal ("to jump between text fields", tf.Text); Assert.True (tf.ProcessKey (new KeyEvent (Key.T | Key.CtrlMask, new KeyModifiers ()))); Assert.Equal ("to jump between text fields", tf.SelectedText); Assert.True (tf.ProcessKey (new KeyEvent (Key.D | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()))); - Assert.Equal ("", tf.Text.ToString ()); + Assert.Equal ("", tf.Text); } [Fact] @@ -1150,13 +1150,13 @@ namespace Terminal.Gui.ViewsTests { var oldText = ""; var tf = new TextField () { Width = 10, Text = "-1" }; - tf.TextChanging += (s, e) => newText = e.NewText.ToString (); - tf.TextChanged += (s, e) => oldText = e.OldValue.ToString (); + tf.TextChanging += (s, e) => newText = e.NewText; + tf.TextChanged += (s, e) => oldText = e.OldValue; Application.Top.Add (tf); Application.Begin (Application.Top); - Assert.Equal ("-1", tf.Text.ToString ()); + Assert.Equal ("-1", tf.Text); // InsertText tf.SelectedStart = 1; @@ -1166,7 +1166,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (tf.ProcessKey (new KeyEvent (Key.D2, new KeyModifiers ()))); Assert.Equal ("-2", newText); Assert.Equal ("-1", oldText); - Assert.Equal ("-2", tf.Text.ToString ()); + Assert.Equal ("-2", tf.Text); // DeleteCharLeft tf.SelectedStart = 1; @@ -1176,7 +1176,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()))); Assert.Equal ("-", newText); Assert.Equal ("-2", oldText); - Assert.Equal ("-", tf.Text.ToString ()); + Assert.Equal ("-", tf.Text); // DeleteCharRight tf.Text = "-1"; @@ -1187,7 +1187,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ()))); Assert.Equal ("-", newText); Assert.Equal ("-1", oldText); - Assert.Equal ("-", tf.Text.ToString ()); + Assert.Equal ("-", tf.Text); // Cut tf.Text = "-1"; @@ -1198,7 +1198,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (tf.ProcessKey (new KeyEvent (Key.X | Key.CtrlMask, new KeyModifiers ()))); Assert.Equal ("-", newText); Assert.Equal ("-1", oldText); - Assert.Equal ("-", tf.Text.ToString ()); + Assert.Equal ("-", tf.Text); // Delete word with accented char tf.Text = "Les Misérables movie."; @@ -1213,7 +1213,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (tf.ProcessKey (new KeyEvent (Key.Delete, new KeyModifiers ()))); Assert.Equal ("Les movie.", newText); Assert.Equal ("Les Misérables movie.", oldText); - Assert.Equal ("Les movie.", tf.Text.ToString ()); + Assert.Equal ("Les movie.", tf.Text); } [Fact] @@ -1228,17 +1228,17 @@ namespace Terminal.Gui.ViewsTests { Application.Begin (Application.Top); Application.Driver.SendKeys ('a', ConsoleKey.A, false, false, false); - Assert.Equal ("a", tf.Text.ToString ()); + Assert.Equal ("a", tf.Text); // SuppressKey suppresses the 'j' key Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false); - Assert.Equal ("a", tf.Text.ToString ()); + Assert.Equal ("a", tf.Text); Application.RootKeyEvent -= SuppressKey; // Now that the delegate has been removed we can type j again Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false); - Assert.Equal ("aj", tf.Text.ToString ()); + Assert.Equal ("aj", tf.Text); } [Fact] [AutoInitShutdown] @@ -1254,7 +1254,7 @@ namespace Terminal.Gui.ViewsTests { Application.Begin (Application.Top); var processMouseEventMethod = typeof (Application).GetMethod ("ProcessMouseEvent", BindingFlags.Static | BindingFlags.NonPublic) - ?? throw new Exception ("Expected private method not found 'ProcessMouseEvent', this method was used for testing mouse behaviours"); + ?? throw new Exception ("Expected private method not found 'ProcessMouseEvent', this method was used for testing mouse behaviours"); var mouseEvent = new MouseEvent { Flags = MouseFlags.Button1Clicked, @@ -1367,23 +1367,23 @@ namespace Terminal.Gui.ViewsTests { var tf = new TextField (text) { Width = 30 }; Assert.Equal (21, text.Length); - Assert.Equal (21, tf.Text.RuneCount); - Assert.Equal (21, tf.Text.ConsoleWidth); + Assert.Equal (21, tf.Text.GetRuneCount ()); + Assert.Equal (21, tf.Text.GetColumns ()); var runes = tf.Text.ToRuneList (); Assert.Equal (21, runes.Count); - Assert.Equal (22, tf.Text.Length); + Assert.Equal (21, tf.Text.Length); for (int i = 0; i < runes.Count; i++) { var cs = text [i]; - var cus = (char)runes [i]; + var cus = (char)runes [i].Value; Assert.Equal (cs, cus); } var idx = 15; Assert.Equal ('m', text [idx]); - Assert.Equal ('m', (char)runes [idx]); - Assert.Equal ("m", ustring.Make (runes [idx])); + Assert.Equal ('m', (char)runes [idx].Value); + Assert.Equal ("m", runes [idx].ToString ()); Assert.True (tf.MouseEvent (new MouseEvent { X = idx, @@ -1503,7 +1503,7 @@ Les Miśerables", output); var caption = "Mise" + Char.ConvertFromUtf32 (Int32.Parse ("0301", NumberStyles.HexNumber)) + "rables"; Assert.Equal (11, caption.Length); - Assert.Equal (10, caption.Sum (c => Rune.ColumnWidth (c))); + Assert.Equal (10, caption.EnumerateRunes ().Sum (c => c.GetColumns ())); var tf = GetTextFieldsInView (); diff --git a/UnitTests/Views/TextViewTests.cs b/UnitTests/Views/TextViewTests.cs index dd463d46a..509e75d02 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/UnitTests/Views/TextViewTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Text; using System.Text.RegularExpressions; using Xunit; using Xunit.Abstractions; @@ -31,13 +32,10 @@ namespace Terminal.Gui.ViewsTests { // 1 2 3 // 01234567890123456789012345678901=32 (Length) - var buff = new byte [txt.Length]; - for (int i = 0; i < txt.Length; i++) { - buff [i] = (byte)txt [i]; - } + var buff = Encoding.Unicode.GetBytes(txt); var ms = new System.IO.MemoryStream (buff).ToArray (); _textView = new TextView () { Width = 30, Height = 10 }; - _textView.Text = ms; + _textView.Text = Encoding.Unicode.GetString (ms); } public override void After (MethodInfo methodUnderTest) @@ -987,12 +985,12 @@ namespace Terminal.Gui.ViewsTests { _textView.ProcessKey (new KeyEvent (Key.K | Key.CtrlMask, new KeyModifiers ())); Assert.Equal (0, _textView.CursorPosition.X); Assert.Equal (0, _textView.CursorPosition.Y); - Assert.Equal ("", _textView.Text.ToString ()); - Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.", Clipboard.Contents.ToString ()); + Assert.Equal ("", _textView.Text); + Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.", Clipboard.Contents); // Paste _textView.ProcessKey (new KeyEvent (Key.Y | Key.CtrlMask, new KeyModifiers ())); - Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.", _textView.Text.ToString ()); + Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.", _textView.Text); break; default: iterationsFinished = true; @@ -1895,7 +1893,7 @@ namespace Terminal.Gui.ViewsTests { for (int i = lCount; i >= 0; i--) { var r = line [i]; - sumLength += Rune.ColumnWidth (r); + sumLength += ((Rune)r).GetColumns (); if (r == '\t') { sumLength += tabWidth + 1; } @@ -2014,7 +2012,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (8, tv.Text.Length); Assert.Equal (text, tv.Text); Assert.False (tv.IsDirty); - Assert.Equal ('\u2400', ConsoleDriver.MakePrintable ((Rune)tv.Text [4])); + Assert.Equal ((Rune)'\u2400', ((Rune)tv.Text [4]).MakePrintable ()); } } @@ -2200,21 +2198,21 @@ line. var txt = "This is a text."; var txtRunes = TextModel.ToRunes (txt); Assert.Equal (txt.Length, txtRunes.Count); - Assert.Equal ('T', txtRunes [0]); - Assert.Equal ('h', txtRunes [1]); - Assert.Equal ('i', txtRunes [2]); - Assert.Equal ('s', txtRunes [3]); - Assert.Equal (' ', txtRunes [4]); - Assert.Equal ('i', txtRunes [5]); - Assert.Equal ('s', txtRunes [6]); - Assert.Equal (' ', txtRunes [7]); - Assert.Equal ('a', txtRunes [8]); - Assert.Equal (' ', txtRunes [9]); - Assert.Equal ('t', txtRunes [10]); - Assert.Equal ('e', txtRunes [11]); - Assert.Equal ('x', txtRunes [12]); - Assert.Equal ('t', txtRunes [13]); - Assert.Equal ('.', txtRunes [^1]); + Assert.Equal ('T', txtRunes [0].Value); + Assert.Equal ('h', txtRunes [1].Value); + Assert.Equal ('i', txtRunes [2].Value); + Assert.Equal ('s', txtRunes [3].Value); + Assert.Equal (' ', txtRunes [4].Value); + Assert.Equal ('i', txtRunes [5].Value); + Assert.Equal ('s', txtRunes [6].Value); + Assert.Equal (' ', txtRunes [7].Value); + Assert.Equal ('a', txtRunes [8].Value); + Assert.Equal (' ', txtRunes [9].Value); + Assert.Equal ('t', txtRunes [10].Value); + Assert.Equal ('e', txtRunes [11].Value); + Assert.Equal ('x', txtRunes [12].Value); + Assert.Equal ('t', txtRunes [13].Value); + Assert.Equal ('.', txtRunes [^1].Value); int col = 0; Assert.True (TextModel.SetCol (ref col, 80, 79)); @@ -2224,11 +2222,11 @@ line. var start = 0; var x = 8; Assert.Equal (8, TextModel.GetColFromX (txtRunes, start, x)); - Assert.Equal ('a', txtRunes [start + x]); + Assert.Equal ('a', txtRunes [start + x].Value); start = 1; x = 7; Assert.Equal (7, TextModel.GetColFromX (txtRunes, start, x)); - Assert.Equal ('a', txtRunes [start + x]); + Assert.Equal ('a', txtRunes [start + x].Value); Assert.Equal ((15, 15), TextModel.DisplaySize (txtRunes)); Assert.Equal ((6, 6), TextModel.DisplaySize (txtRunes, 1, 7)); diff --git a/UnitTests/Views/WindowTests.cs b/UnitTests/Views/WindowTests.cs index f21998157..242e34a67 100644 --- a/UnitTests/Views/WindowTests.cs +++ b/UnitTests/Views/WindowTests.cs @@ -5,7 +5,7 @@ using Xunit.Abstractions; // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; -using NStack; +using System.Text; using Terminal.Gui; namespace Terminal.Gui.ViewsTests { @@ -23,7 +23,7 @@ namespace Terminal.Gui.ViewsTests { // Parameterless var r = new Window (); Assert.NotNull (r); - Assert.Equal (ustring.Empty, r.Title); + Assert.Equal (string.Empty, r.Title); Assert.Equal (LayoutStyle.Computed, r.LayoutStyle); Assert.Equal ("Window()((0,0,0,0))", r.ToString ()); Assert.True (r.CanFocus);