From a637f8a29c4cd2e53d30cf8200e49808c7104309 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 10 Apr 2023 17:34:52 -0600 Subject: [PATCH] Fixes #2486 - Removes old `Border` and fixes a litany of related things (#2525) * Added View.BorderStyle and renamed BorderStyle enum to LineStyle * Fixed a lot of things and broke everything else * Fixed things * Updated DialogTests * Updates including Rect unit tests * Fixed Dialog & MessagBox tests * Fixed AllviewsTester bug * Fixed AllviewsTester bug * Removed Border class * Renamed View privates with _ * Removed comments in MessageBox.cs --- ReactiveExample/LoginView.cs | 6 +- .../Configuration/ConfigurationManager.cs | 2 +- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 19 +- Terminal.Gui/Drawing/LineCanvas.cs | 47 +- Terminal.Gui/Drawing/Thickness.cs | 2 +- .../FileServices/DefaultFileOperations.cs | 3 +- Terminal.Gui/Resources/config.json | 28 +- Terminal.Gui/Text/TextFormatter.cs | 796 ++--- Terminal.Gui/View/Border.cs | 112 +- Terminal.Gui/View/Frame.cs | 11 +- Terminal.Gui/View/View.cs | 629 ++-- Terminal.Gui/Views/Button.cs | 7 + Terminal.Gui/Views/Dialog.cs | 97 +- Terminal.Gui/Views/FrameView.cs | 32 +- Terminal.Gui/Views/Label.cs | 4 + Terminal.Gui/Views/Menu.cs | 4 +- Terminal.Gui/Views/MessageBox.cs | 137 +- Terminal.Gui/Views/TileView.cs | 24 +- Terminal.Gui/Views/Toplevel.cs | 154 +- Terminal.Gui/Views/Window.cs | 120 +- Terminal.Gui/Views/Wizard/Wizard.cs | 28 +- UICatalog/KeyBindingsDialog.cs | 9 +- UICatalog/Scenario.cs | 3 +- UICatalog/Scenarios/AllViewsTester.cs | 22 +- .../Scenarios/BackgroundWorkerCollection.cs | 6 +- UICatalog/Scenarios/BordersComparisons.cs | 20 +- UICatalog/Scenarios/BordersOnContainers.cs | 183 +- UICatalog/Scenarios/Clipping.cs | 9 +- UICatalog/Scenarios/ConfigurationEditor.cs | 2 +- UICatalog/Scenarios/CsvEditor.cs | 14 +- UICatalog/Scenarios/Dialogs.cs | 8 +- UICatalog/Scenarios/DynamicMenuBar.cs | 6 +- UICatalog/Scenarios/DynamicStatusBar.cs | 6 +- UICatalog/Scenarios/Editor.cs | 7 +- UICatalog/Scenarios/Frames.cs | 4 +- UICatalog/Scenarios/InteractiveTree.cs | 2 +- UICatalog/Scenarios/Keys.cs | 19 +- UICatalog/Scenarios/LineDrawing.cs | 26 +- UICatalog/Scenarios/MultiColouredTable.cs | 2 +- UICatalog/Scenarios/Notepad.cs | 2 +- .../Scenarios/RuneWidthGreaterThanOne.cs | 40 +- UICatalog/Scenarios/SingleBackgroundWorker.cs | 2 +- UICatalog/Scenarios/Snake.cs | 10 +- UICatalog/Scenarios/TableEditor.cs | 4 +- UICatalog/Scenarios/TileViewExperiment.cs | 14 +- UICatalog/Scenarios/TileViewNesting.cs | 2 +- UICatalog/Scenarios/ViewExperiments.cs | 14 +- UICatalog/Scenarios/WindowsAndFrameViews.cs | 24 +- UICatalog/Scenarios/Wizards.cs | 3 +- UICatalog/UICatalog.cs | 4 +- UnitTests/Application/ApplicationTests.cs | 8 +- UnitTests/Configuration/ThemeTests.cs | 11 +- .../ConsoleDrivers/ConsoleDriverTests.cs | 6 +- UnitTests/Dialogs/DialogTests.cs | 274 +- UnitTests/Dialogs/MessageBoxTests.cs | 431 ++- UnitTests/Dialogs/WizardTests.cs | 8 +- UnitTests/Drawing/LineCanvasTests.cs | 148 +- UnitTests/Text/TextFormatterTests.cs | 2571 +++++++---------- UnitTests/Text/UnicodeTests.cs | 8 +- UnitTests/UICatalog/ScenarioTests.cs | 23 +- UnitTests/View/BorderTests.cs | 640 +--- UnitTests/View/DrawTests.cs | 340 +++ UnitTests/View/FrameTests.cs | 31 +- UnitTests/View/Layout/AutoSizeTests.cs | 838 ++++++ UnitTests/View/Layout/DimTests.cs | 36 +- UnitTests/View/Layout/LayoutTests.cs | 71 +- UnitTests/View/Layout/PosTests.cs | 28 +- UnitTests/View/NavigationTests.cs | 28 +- UnitTests/View/ViewTests.cs | 16 +- UnitTests/Views/ButtonTests.cs | 24 +- UnitTests/Views/ContextMenuTests.cs | 4 +- UnitTests/Views/FrameViewTests.cs | 7 +- UnitTests/Views/LabelTests.cs | 912 ++++++ UnitTests/Views/MenuTests.cs | 2 +- UnitTests/Views/ScrollBarViewTests.cs | 8 +- UnitTests/Views/ScrollViewTests.cs | 6 +- UnitTests/Views/ToplevelTests.cs | 89 +- UnitTests/Views/WindowTests.cs | 6 +- 78 files changed, 5222 insertions(+), 4081 deletions(-) create mode 100644 UnitTests/View/DrawTests.cs create mode 100644 UnitTests/View/Layout/AutoSizeTests.cs create mode 100644 UnitTests/Views/LabelTests.cs diff --git a/ReactiveExample/LoginView.cs b/ReactiveExample/LoginView.cs index 365374eff..1bd36fcff 100644 --- a/ReactiveExample/LoginView.cs +++ b/ReactiveExample/LoginView.cs @@ -9,10 +9,10 @@ namespace ReactiveExample { public class LoginView : Window, IViewFor { readonly CompositeDisposable _disposable = new CompositeDisposable(); - public LoginView (LoginViewModel viewModel) : base("Reactive Extensions Example") { + public LoginView (LoginViewModel viewModel) : base() { + Title = "Reactive Extensions Example"; ViewModel = viewModel; - var title = TitleLabel (); - var usernameLengthLabel = UsernameLengthLabel (title); + var usernameLengthLabel = UsernameLengthLabel (TitleLabel ()); var usernameInput = UsernameInput (usernameLengthLabel); var passwordLengthLabel = PasswordLengthLabel (usernameInput); var passwordInput = PasswordInput (passwordLengthLabel); diff --git a/Terminal.Gui/Configuration/ConfigurationManager.cs b/Terminal.Gui/Configuration/ConfigurationManager.cs index d642f863c..a0cabdf51 100644 --- a/Terminal.Gui/Configuration/ConfigurationManager.cs +++ b/Terminal.Gui/Configuration/ConfigurationManager.cs @@ -73,7 +73,7 @@ namespace Terminal.Gui { /// /// /// [SerializableConfigurationProperty(Scope = typeof(Configuration.ThemeManager.ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))] - /// public static BorderStyle DefaultBorderStyle { + /// public static LineStyle DefaultBorderStyle { /// ... /// [AttributeUsage (AttributeTargets.Property, AllowMultiple = false, Inherited = false)] diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index a357a173f..698e604d7 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -951,12 +951,12 @@ namespace Terminal.Gui { /// Off = 0b_0000_0000, /// - /// When enabled, will draw a + /// When enabled, will draw a /// ruler in the frame for any side with a padding value greater than 0. /// FrameRuler = 0b_0000_0001, /// - /// When Enabled, will use + /// When Enabled, will use /// 'L', 'R', 'T', and 'B' for padding instead of ' '. /// FramePadding = 0b_0000_0010, @@ -977,9 +977,10 @@ namespace Terminal.Gui { /// Number of rows to pad on the bottom (if 0 the border will not appear on the bottom). /// If set to true and any padding dimension is > 0 the border will be drawn. /// If set to true it will clear the content area (the area inside the padding) with the current color, otherwise the content area will be left untouched. - /// The to be used if defined. + /// The line style to be used. + [ObsoleteAttribute ("This method is obsolete in v2. Use use LineCanvas or Frame instead.", false)] public virtual void DrawWindowFrame (Rect region, int paddingLeft = 0, int paddingTop = 0, int paddingRight = 0, - int paddingBottom = 0, bool border = true, bool fill = false, Border borderContent = null) + int paddingBottom = 0, bool border = true, bool fill = false, LineStyle lineStyle = LineStyle.Single) { char clearChar = ' '; char leftChar = clearChar; @@ -1019,16 +1020,16 @@ namespace Terminal.Gui { // fbottom is location of bottom frame line int fbottom = ftop + fheight + 1; - var borderStyle = borderContent == null ? BorderStyle.Single : borderContent.BorderStyle; + var borderStyle = lineStyle; Rune hLine = default, vLine = default, uRCorner = default, uLCorner = default, lLCorner = default, lRCorner = default; if (border) { switch (borderStyle) { - case BorderStyle.None: + case LineStyle.None: break; - case BorderStyle.Single: + case LineStyle.Single: hLine = HLine; vLine = VLine; uRCorner = URCorner; @@ -1036,7 +1037,7 @@ namespace Terminal.Gui { lLCorner = LLCorner; lRCorner = LRCorner; break; - case BorderStyle.Double: + case LineStyle.Double: hLine = HDLine; vLine = VDLine; uRCorner = URDCorner; @@ -1044,7 +1045,7 @@ namespace Terminal.Gui { lLCorner = LLDCorner; lRCorner = LRDCorner; break; - case BorderStyle.Rounded: + case LineStyle.Rounded: hLine = HRLine; vLine = VRLine; uRCorner = URRCorner; diff --git a/Terminal.Gui/Drawing/LineCanvas.cs b/Terminal.Gui/Drawing/LineCanvas.cs index a56a18c5d..5d0910644 100644 --- a/Terminal.Gui/Drawing/LineCanvas.cs +++ b/Terminal.Gui/Drawing/LineCanvas.cs @@ -4,15 +4,38 @@ using System.Linq; namespace Terminal.Gui { + /// + /// Defines the style of lines for a . + /// + public enum LineStyle { + /// + /// No border is drawn. + /// + None, + /// + /// The border is drawn using single-width line glyphs. + /// + Single, + /// + /// The border is drawn using double-width line glyphs. + /// + Double, + /// + /// The border is drawn using single-width line glyphs with rounded corners. + /// + Rounded, + // TODO: Support Ruler + ///// + ///// The border is drawn as a diagnostic ruler ("|123456789..."). + ///// + //Ruler + } /// /// Facilitates box drawing and line intersection detection /// and rendering. Does not support diagonal lines. /// public class LineCanvas { - - - private List lines = new List (); Dictionary runeResolvers = new Dictionary { @@ -43,7 +66,7 @@ namespace Terminal.Gui { /// Positive for Down/Right. Negative for Up/Left. /// Direction of the line. /// The style of line to use - public void AddLine (Point from, int length, Orientation orientation, BorderStyle style) + public void AddLine (Point from, int length, Orientation orientation, LineStyle style) { lines.Add (new StraightLine (from, length, orientation, style)); } @@ -102,10 +125,10 @@ namespace Terminal.Gui { public Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects) { - var useRounded = intersects.Any (i => i.Line.Style == BorderStyle.Rounded && i.Line.Length != 0); + var useRounded = intersects.Any (i => i.Line.Style == LineStyle.Rounded && i.Line.Length != 0); - bool doubleHorizontal = intersects.Any (l => l.Line.Orientation == Orientation.Horizontal && l.Line.Style == BorderStyle.Double); - bool doubleVertical = intersects.Any (l => l.Line.Orientation == Orientation.Vertical && l.Line.Style == BorderStyle.Double); + bool doubleHorizontal = intersects.Any (l => l.Line.Orientation == Orientation.Horizontal && l.Line.Style == LineStyle.Double); + bool doubleVertical = intersects.Any (l => l.Line.Orientation == Orientation.Vertical && l.Line.Style == LineStyle.Double); if (doubleHorizontal) { @@ -199,10 +222,10 @@ namespace Terminal.Gui { } // TODO: Remove these two once we have all of the below ported to IntersectionRuneResolvers - var useDouble = intersects.Any (i => i.Line.Style == BorderStyle.Double); - var useRounded = intersects.Any (i => i.Line.Style == BorderStyle.Rounded); + var useDouble = intersects.Any (i => i.Line.Style == LineStyle.Double); + var useRounded = intersects.Any (i => i.Line.Style == LineStyle.Rounded); // TODO: Support ruler - //var useRuler = intersects.Any (i => i.Line.Style == BorderStyle.Ruler && i.Line.Length != 0); + //var useRuler = intersects.Any (i => i.Line.Style == LineStyle.Ruler && i.Line.Length != 0); // TODO: maybe make these resolvers to for simplicity? // or for dotted lines later on or that kind of thing? @@ -470,9 +493,9 @@ namespace Terminal.Gui { public Point Start { get; } public int Length { get; } public Orientation Orientation { get; } - public BorderStyle Style { get; } + public LineStyle Style { get; } - public StraightLine (Point start, int length, Orientation orientation, BorderStyle style) + public StraightLine (Point start, int length, Orientation orientation, LineStyle style) { this.Start = start; this.Length = length; diff --git a/Terminal.Gui/Drawing/Thickness.cs b/Terminal.Gui/Drawing/Thickness.cs index e9576746a..fdb16200d 100644 --- a/Terminal.Gui/Drawing/Thickness.cs +++ b/Terminal.Gui/Drawing/Thickness.cs @@ -179,7 +179,7 @@ namespace Terminal.Gui { Application.Driver.FillRect (new Rect (rect.X, rect.Y + Math.Max (0, rect.Height - Bottom), rect.Width, Bottom), bottomChar); } - // TODO: This should be moved to LineCanvas as a new BorderStyle.Ruler + // TODO: This should be moved to LineCanvas as a new LineStyle.Ruler if ((ConsoleDriver.Diagnostics & ConsoleDriver.DiagnosticFlags.FrameRuler) == ConsoleDriver.DiagnosticFlags.FrameRuler) { // Top var hruler = new Ruler () { Length = rect.Width, Orientation = Orientation.Horizontal }; diff --git a/Terminal.Gui/FileServices/DefaultFileOperations.cs b/Terminal.Gui/FileServices/DefaultFileOperations.cs index bf403a98b..83780c241 100644 --- a/Terminal.Gui/FileServices/DefaultFileOperations.cs +++ b/Terminal.Gui/FileServices/DefaultFileOperations.cs @@ -67,7 +67,8 @@ namespace Terminal.Gui { }; tf.SelectAll (); - var dlg = new Dialog (title) { + var dlg = new Dialog () { + Title = title, Width = Dim.Percent (50), Height = 4 }; diff --git a/Terminal.Gui/Resources/config.json b/Terminal.Gui/Resources/config.json index b59236606..63238ae1c 100644 --- a/Terminal.Gui/Resources/config.json +++ b/Terminal.Gui/Resources/config.json @@ -36,35 +36,9 @@ "Themes": [ { "Default": { - "Dialog.DefaultBorder": { - "BorderStyle": "Single", - "DrawMarginFrame": true, - "BorderThickness": { - "Left": 0, - "Top": 0, - "Right": 0, - "Bottom": 0 - }, - "BorderBrush": "Black", - "Background": "Black", - "Padding": { - "Left": 0, - "Top": 0, - "Right": 0, - "Bottom": 0 - }, - "Effect3D": true, - "Effect3DOffset": { - "X": 1, - "Y": 1 - }, - "Effect3DBrush": { - "Foreground": "Gray", - "Background": "DarkGray" - } - }, "Dialog.DefaultButtonAlignment": "Center", "FrameView.DefaultBorderStyle": "Single", + "Window.DefaultBorderStyle": "Single", "ColorSchemes": [ { "TopLevel": { diff --git a/Terminal.Gui/Text/TextFormatter.cs b/Terminal.Gui/Text/TextFormatter.cs index f0d63486d..d3cd9fa30 100644 --- a/Terminal.Gui/Text/TextFormatter.cs +++ b/Terminal.Gui/Text/TextFormatter.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Text; using NStack; +using Rune = System.Rune; namespace Terminal.Gui { /// @@ -113,253 +115,8 @@ namespace Terminal.Gui { /// Provides text formatting capabilities for console apps. Supports, hotkeys, horizontal alignment, multiple lines, and word-based line wrap. /// public class TextFormatter { - List lines = new List (); - ustring text; - TextAlignment textAlignment; - VerticalTextAlignment textVerticalAlignment; - TextDirection textDirection; - Attribute textColor = -1; - bool needsFormat; - Key hotKey; - Size size; - /// - /// Event invoked when the is changed. - /// - public event EventHandler HotKeyChanged; - - /// - /// The text to be displayed. This text is never modified. - /// - public virtual ustring Text { - get => text; - set { - text = value; - - if (text != null && text.RuneCount > 0 && (Size.Width == 0 || Size.Height == 0 || Size.Width != text.ConsoleWidth)) { - // 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); - } - - NeedsFormat = true; - } - } - - /// - /// Used by to resize the view's with the . - /// Setting to true only work if the and are null or - /// values and doesn't work with layout, - /// to avoid breaking the and settings. - /// - public bool AutoSize { get; set; } - - /// - /// Gets or sets a flag that determines whether will have trailing spaces preserved - /// or not when is enabled. If `true` any trailing spaces will be trimmed when - /// either the property is changed or when is set to `true`. - /// The default is `false`. - /// - public bool PreserveTrailingSpaces { get; set; } - - /// - /// Controls the horizontal text-alignment property. - /// - /// The text alignment. - public TextAlignment Alignment { - get => textAlignment; - set { - textAlignment = value; - NeedsFormat = true; - } - } - - /// - /// Controls the vertical text-alignment property. - /// - /// The text vertical alignment. - public VerticalTextAlignment VerticalAlignment { - get => textVerticalAlignment; - set { - textVerticalAlignment = value; - NeedsFormat = true; - } - } - - /// - /// Controls the text-direction property. - /// - /// The text vertical alignment. - public TextDirection Direction { - get => textDirection; - set { - textDirection = value; - NeedsFormat = true; - } - } - - /// - /// Check if it is a horizontal direction - /// - public static bool IsHorizontalDirection (TextDirection textDirection) - { - switch (textDirection) { - case TextDirection.LeftRight_TopBottom: - case TextDirection.LeftRight_BottomTop: - case TextDirection.RightLeft_TopBottom: - case TextDirection.RightLeft_BottomTop: - return true; - default: - return false; - } - } - - /// - /// Check if it is a vertical direction - /// - public static bool IsVerticalDirection (TextDirection textDirection) - { - switch (textDirection) { - case TextDirection.TopBottom_LeftRight: - case TextDirection.TopBottom_RightLeft: - case TextDirection.BottomTop_LeftRight: - case TextDirection.BottomTop_RightLeft: - return true; - default: - return false; - } - } - - /// - /// Check if it is Left to Right direction - /// - public static bool IsLeftToRight (TextDirection textDirection) - { - switch (textDirection) { - case TextDirection.LeftRight_TopBottom: - case TextDirection.LeftRight_BottomTop: - return true; - default: - return false; - } - } - - /// - /// Check if it is Top to Bottom direction - /// - public static bool IsTopToBottom (TextDirection textDirection) - { - switch (textDirection) { - case TextDirection.TopBottom_LeftRight: - case TextDirection.TopBottom_RightLeft: - return true; - default: - return false; - } - } - - /// - /// Gets or sets the size of the area the text will be constrained to when formatted. - /// - public Size Size { - get => size; - set { - size = value; - NeedsFormat = true; - } - } - - /// - /// The specifier character for the hotkey (e.g. '_'). Set to '\xffff' to disable hotkey support for this View instance. The default is '\xffff'. - /// - public Rune HotKeySpecifier { get; set; } = (Rune)0xFFFF; - - /// - /// The position in the text of the hotkey. The hotkey will be rendered using the hot color. - /// - public int HotKeyPos { get => hotKeyPos; set => hotKeyPos = value; } - - /// - /// Gets the hotkey. Will be an upper case letter or digit. - /// - public Key HotKey { - get => hotKey; - internal set { - if (hotKey != value) { - var oldKey = hotKey; - hotKey = value; - HotKeyChanged?.Invoke (this, new KeyChangedEventArgs(oldKey,value)); - } - } - } - - /// - /// Gets the cursor position from . If the is defined, the cursor will be positioned over it. - /// - public int CursorPosition { get; set; } - - /// - /// Gets the formatted lines. - /// - /// - /// - /// Upon a 'get' of this property, if the text needs to be formatted (if is true) - /// will be called internally. - /// - /// - 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 - }; - NeedsFormat = false; - return lines; - } - - if (NeedsFormat) { - var shown_text = text; - if (FindHotKey (text, HotKeySpecifier, true, out hotKeyPos, out Key newHotKey)) { - HotKey = newHotKey; - shown_text = RemoveHotKeySpecifier (Text, hotKeyPos, HotKeySpecifier); - shown_text = ReplaceHotKeyWithTag (shown_text, hotKeyPos); - } - - if (IsVerticalDirection (textDirection)) { - var colsWidth = GetSumMaxCharWidth (shown_text, 0, 1); - lines = Format (shown_text, Size.Height, textVerticalAlignment == VerticalTextAlignment.Justified, Size.Width > colsWidth, - PreserveTrailingSpaces, 0, textDirection); - if (!AutoSize) { - colsWidth = GetMaxColsForWidth (lines, Size.Width); - if (lines.Count > colsWidth) { - lines.RemoveRange (colsWidth, lines.Count - colsWidth); - } - } - } else { - lines = Format (shown_text, Size.Width, textAlignment == TextAlignment.Justified, Size.Height > 1, - PreserveTrailingSpaces, 0, textDirection); - if (!AutoSize && lines.Count > Size.Height) { - lines.RemoveRange (Size.Height, lines.Count - Size.Height); - } - } - - NeedsFormat = false; - } - return lines; - } - } - - /// - /// Gets or sets whether the needs to format the text when is called. - /// If it is false when Draw is called, the Draw call will be faster. - /// - /// - /// - /// This is set to true when the properties of are set. - /// - /// - public bool NeedsFormat { get => needsFormat; set => needsFormat = value; } + #region Static Members static ustring StripCRLF (ustring str, bool keepNewLine = false) { @@ -487,12 +244,12 @@ namespace Terminal.Gui { /// Formats the provided text to fit within the width provided using word wrapping. /// /// The text to word wrap - /// The width to contain the text to - /// If true, the wrapped text will keep the trailing spaces. - /// If false, the trailing spaces will be trimmed. - /// The tab width. + /// The number of columns to constrain the text to + /// If trailing spaces at the end of wrapped lines will be preserved. + /// If , trailing spaces at the end of wrapped lines will be trimmed. + /// The number of columns used for a tab. /// The text direction. - /// Returns a list of word wrapped lines. + /// A list of word wrapped lines. /// /// /// This method does not do any justification. @@ -500,8 +257,11 @@ namespace Terminal.Gui { /// /// This method strips Newline ('\n' and '\r\n') sequences before processing. /// + /// + /// If is at most one space will be preserved at the end of the last line. + /// /// - public static List WordWrap (ustring text, int width, bool preserveTrailingSpaces = false, int tabWidth = 0, + public static List WordWrapText (ustring text, int width, bool preserveTrailingSpaces = false, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { if (width < 0) { @@ -516,33 +276,7 @@ namespace Terminal.Gui { } var runes = StripCRLF (text).ToRuneList (); - if (!preserveTrailingSpaces) { - if (IsHorizontalDirection (textDirection)) { - while ((end = start + Math.Max (GetMaxLengthForWidth (runes.GetRange (start, runes.Count - start), width), 1)) < runes.Count) { - while (runes [end] != ' ' && end > start) - end--; - if (end == start) - end = start + GetMaxLengthForWidth (runes.GetRange (end, runes.Count - end), width); - lines.Add (ustring.Make (runes.GetRange (start, end - start))); - start = end; - if (runes [end] == ' ') { - start++; - } - } - } else { - while ((end = start + width) < runes.Count) { - while (runes [end] != ' ' && end > start) - end--; - if (end == start) - end = start + width; - lines.Add (ustring.Make (runes.GetRange (start, end - start))); - start = end; - if (runes [end] == ' ') { - start++; - } - } - } - } else { + if (preserveTrailingSpaces) { while ((end = start) < runes.Count) { end = GetNextWhiteSpace (start, width, out bool incomplete); if (end == 0 && incomplete) { @@ -556,6 +290,85 @@ namespace Terminal.Gui { break; } } + } else { + if (IsHorizontalDirection (textDirection)) { + //if (GetLengthThatFits (runes.GetRange (start, runes.Count - start), width) > 0) { + // // while there's still runes left and end is not past end... + // while (start < runes.Count && + // (end = start + Math.Max (GetLengthThatFits (runes.GetRange (start, runes.Count - start), width) - 1, 0)) < runes.Count) { + // // end now points to start + LengthThatFits + // // Walk back over trailing spaces + // while (runes [end] == ' ' && end > start) { + // end--; + // } + // // end now points to start + LengthThatFits - any trailing spaces; start saving new line + // var line = runes.GetRange (start, end - start + 1); + + // if (end == start && width > 1) { + // // it was all trailing spaces; now walk forward to next non-space + // do { + // start++; + // } while (start < runes.Count && runes [start] == ' '); + + // // start now points to first non-space we haven't seen yet or we're done + // if (start < runes.Count) { + // // we're not done. we have remaining = width - line.Count columns left; + // var remaining = width - line.Count; + // if (remaining > 1) { + // // add a space for all the spaces we walked over + // line.Add (' '); + // } + // var count = GetLengthThatFits (runes.GetRange (start, runes.Count - start), width - line.Count); + + // // [start..count] now has rest of line + // line.AddRange (runes.GetRange (start, count)); + // start += count; + // } + // } else { + // start += line.Count; + // } + + // //// if the previous line was just a ' ' and the new line is just a ' ' + // //// don't add new line + // //if (line [0] == ' ' && (lines.Count > 0 && lines [lines.Count - 1] [0] == ' ')) { + // //} else { + // //} + // lines.Add (ustring.Make (line)); + + // // move forward to next non-space + // while (width > 1 && start < runes.Count && runes [start] == ' ') { + // start++; + // } + // } + //} + + while ((end = start + Math.Max (GetLengthThatFits (runes.GetRange (start, runes.Count - start), width), 1)) < runes.Count) { + while (runes [end] != ' ' && 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++; + } + } + + } else { + while ((end = start + width) < runes.Count) { + while (runes [end] != ' ' && end > start) { + end--; + } + if (end == start) { + end = start + width; + } + lines.Add (ustring.Make (runes.GetRange (start, end - start))); + start = end; + if (runes [end] == ' ') { + start++; + } + } + } } int GetNextWhiteSpace (int from, int cWidth, out bool incomplete, int cLength = 0) @@ -618,7 +431,7 @@ namespace Terminal.Gui { /// Justifies text within a specified width. /// /// The text to justify. - /// If the text length is greater that width it will be clipped. + /// The number of columns to clip the text to. Text longer than will be clipped. /// Alignment. /// The text direction. /// Justified and clipped text. @@ -631,7 +444,7 @@ namespace Terminal.Gui { /// Justifies text within a specified width. /// /// The text to justify. - /// If the text length is greater that width it will be clipped. + /// The number of columns to clip the text to. Text longer than will be clipped. /// Justify. /// The text direction. /// Justified and clipped text. @@ -648,7 +461,7 @@ namespace Terminal.Gui { int slen = runes.Count; if (slen > width) { if (IsHorizontalDirection (textDirection)) { - return ustring.Make (runes.GetRange (0, GetMaxLengthForWidth (text, width))); + return ustring.Make (runes.GetRange (0, GetLengthThatFits (text, width))); } else { return ustring.Make (runes.GetRange (0, width)); } @@ -656,7 +469,7 @@ namespace Terminal.Gui { if (justify) { return Justify (text, width, ' ', textDirection); } else if (IsHorizontalDirection (textDirection) && GetTextWidth (text) > width) { - return ustring.Make (runes.GetRange (0, GetMaxLengthForWidth (text, width))); + return ustring.Make (runes.GetRange (0, GetLengthThatFits (text, width))); } return text; } @@ -711,28 +524,29 @@ namespace Terminal.Gui { } static char [] whitespace = new char [] { ' ', '\t' }; - private int hotKeyPos = -1; /// /// Reformats text into lines, applying text alignment and optionally wrapping text to new lines on word boundaries. /// /// - /// The width to bound the text to for word wrapping and clipping. + /// The number of columns to constrain the text to for word wrapping and clipping. /// Specifies how the text will be aligned horizontally. - /// If true, the text will be wrapped to new lines as need. If false, forces text to fit a single line. Line breaks are converted to spaces. The text will be clipped to width - /// If true and 'wordWrap' also true, the wrapped text will keep the trailing spaces. If false, the trailing spaces will be trimmed. - /// The tab width. + /// If , the text will be wrapped to new lines no longer than . + /// If , forces text to fit a single line. Line breaks are converted to spaces. The text will be clipped to . + /// If trailing spaces at the end of wrapped lines will be preserved. + /// If , trailing spaces at the end of wrapped lines will be trimmed. + /// The number of columns used for a tab. /// The text direction. /// A list of word wrapped lines. /// /// - /// An empty text string will result in one empty line. + /// An empty string will result in one empty line. /// /// - /// If width is 0, a single, empty line will be returned. + /// If is 0, a single, empty line will be returned. /// /// - /// If width is int.MaxValue, the text will be formatted to the maximum width possible. + /// 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) @@ -744,22 +558,24 @@ namespace Terminal.Gui { /// Reformats text into lines, applying text alignment and optionally wrapping text to new lines on word boundaries. /// /// - /// The width to bound the text to for word wrapping and clipping. + /// The number of columns to constrain the text to for word wrapping and clipping. /// Specifies whether the text should be justified. - /// If true, the text will be wrapped to new lines as need. If false, forces text to fit a single line. Line breaks are converted to spaces. The text will be clipped to width - /// If true and 'wordWrap' also true, the wrapped text will keep the trailing spaces. If false, the trailing spaces will be trimmed. - /// The tab width. + /// If , the text will be wrapped to new lines no longer than . + /// If , forces text to fit a single line. Line breaks are converted to spaces. The text will be clipped to . + /// If trailing spaces at the end of wrapped lines will be preserved. + /// If , trailing spaces at the end of wrapped lines will be trimmed. + /// The number of columns used for a tab. /// The text direction. /// A list of word wrapped lines. /// /// - /// An empty text string will result in one empty line. + /// An empty string will result in one empty line. /// /// - /// If width is 0, a single, empty line will be returned. + /// If is 0, a single, empty line will be returned. /// /// - /// If width is int.MaxValue, the text will be formatted to the maximum width possible. + /// 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, @@ -787,7 +603,7 @@ namespace Terminal.Gui { for (int i = 0; i < runeCount; i++) { Rune c = runes [i]; if (c == '\n') { - var wrappedLines = WordWrap (ustring.Make (runes.GetRange (lp, i - lp)), width, preserveTrailingSpaces, tabWidth, textDirection); + var wrappedLines = WordWrapText (ustring.Make (runes.GetRange (lp, i - lp)), width, preserveTrailingSpaces, tabWidth, textDirection); foreach (var line in wrappedLines) { lineResult.Add (ClipAndJustify (line, width, justify, textDirection)); } @@ -797,7 +613,7 @@ namespace Terminal.Gui { lp = i + 1; } } - foreach (var line in WordWrap (ustring.Make (runes.GetRange (lp, runeCount - lp)), width, preserveTrailingSpaces, tabWidth, textDirection)) { + foreach (var line in WordWrapText (ustring.Make (runes.GetRange (lp, runeCount - lp)), width, preserveTrailingSpaces, tabWidth, textDirection)) { lineResult.Add (ClipAndJustify (line, width, justify, textDirection)); } @@ -817,14 +633,15 @@ namespace Terminal.Gui { } /// - /// Computes the maximum width needed to render the text (single line or multiple lines) given a minimum width. + /// Computes the maximum width needed to render the text (single line or multiple lines, word wrapped) given + /// a number of columns to constrain the text to. /// - /// Max width of lines. + /// Width of the longest line after formatting the text constrained by . /// Text, may contain newlines. - /// The minimum width for the text. - public static int MaxWidth (ustring text, int width) + /// The number of columns to constrain the text to for formatting. + public static int MaxWidth (ustring text, int maxColumns) { - var result = TextFormatter.Format (text, width, false, true); + var result = TextFormatter.Format (text: text, width: maxColumns, justify: false, wordWrap: true); var max = 0; result.ForEach (s => { var m = 0; @@ -837,11 +654,11 @@ namespace Terminal.Gui { } /// - /// Determines the line with the highest width in the + /// Returns the width of the widest line in the text, accounting for wide-glyphs (uses ). /// if it contains newlines. /// /// Text, may contain newlines. - /// The highest line width. + /// The length of the longest line. public static int MaxWidthLine (ustring text) { var result = TextFormatter.SplitNewLine (text); @@ -849,7 +666,7 @@ namespace Terminal.Gui { } /// - /// Gets the total width of the passed text. + /// Gets the number of columns the passed text will use, ignoring newlines and accounting for wide-glyphs (uses ). /// /// /// The text width. @@ -896,39 +713,30 @@ namespace Terminal.Gui { } /// - /// Gets the index position from the text based on the . + /// Gets the number of the Runes in a that will fit in . /// /// The text. - /// The width. + /// The width. /// The index of the text that fit the width. - public static int GetMaxLengthForWidth (ustring text, int width) - { - var runes = text.ToRuneList (); - var runesLength = 0; - var runeIdx = 0; - for (; runeIdx < runes.Count; runeIdx++) { - var runeWidth = Math.Max (Rune.ColumnWidth (runes [runeIdx]), 1); - if (runesLength + runeWidth > width) { - break; - } - runesLength += runeWidth; - } - return runeIdx; - } + public static int GetLengthThatFits (ustring text, int columns) => GetLengthThatFits (text?.ToRuneList (), columns); /// - /// Gets the index position from the list based on the . + /// Gets the number of the Runes in a list of Runes that will fit in . /// - /// The runes. - /// The width. - /// The index of the list that fit the width. - public static int GetMaxLengthForWidth (List runes, int width) + /// The list of runes. + /// The width. + /// The index of the last Rune in that fit in . + public static int GetLengthThatFits (List runes, int columns) { + if (runes == null || runes.Count == 0) { + return 0; + } + var runesLength = 0; var runeIdx = 0; for (; runeIdx < runes.Count; runeIdx++) { var runeWidth = Math.Max (Rune.ColumnWidth (runes [runeIdx]), 1); - if (runesLength + runeWidth > width) { + if (runesLength + runeWidth > columns) { break; } runesLength += runeWidth; @@ -959,7 +767,7 @@ namespace Terminal.Gui { } /// - /// Calculates the rectangle required to hold text, assuming no word wrapping. + /// Calculates the rectangle required to hold text, assuming no word wrapping or justification. /// /// The x location of the rectangle /// The y location of the rectangle @@ -1145,6 +953,296 @@ namespace Terminal.Gui { } return start; } + #endregion // Static Members + + List _lines = new List (); + ustring _text; + TextAlignment _textAlignment; + VerticalTextAlignment _textVerticalAlignment; + TextDirection _textDirection; + Attribute _textColor = -1; + Key _hotKey; + int _hotKeyPos = -1; + Size _size; + + /// + /// Event invoked when the is changed. + /// + public event EventHandler HotKeyChanged; + + /// + /// The text to be displayed. This text is never modified. + /// + public virtual ustring Text { + get => _text; + set { + _text = value; + + if (_text != null && _text.RuneCount > 0 && (Size.Width == 0 || Size.Height == 0 || Size.Width != _text.ConsoleWidth)) { + // 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); + } + + NeedsFormat = true; + } + } + + /// + /// Used by to resize the view's with the . + /// Setting to true only work if the and are null or + /// values and doesn't work with layout, + /// to avoid breaking the and settings. + /// + public bool AutoSize { get; set; } + + /// + /// Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved + /// or not when is enabled. + /// If trailing spaces at the end of wrapped lines will be removed when + /// is formatted for display. The default is . + /// + public bool PreserveTrailingSpaces { get; set; } + + /// + /// Controls the horizontal text-alignment property. + /// + /// The text alignment. + public TextAlignment Alignment { + get => _textAlignment; + set { + _textAlignment = value; + NeedsFormat = true; + } + } + + /// + /// Controls the vertical text-alignment property. + /// + /// The text vertical alignment. + public VerticalTextAlignment VerticalAlignment { + get => _textVerticalAlignment; + set { + _textVerticalAlignment = value; + NeedsFormat = true; + } + } + + /// + /// Controls the text-direction property. + /// + /// The text vertical alignment. + public TextDirection Direction { + get => _textDirection; + set { + _textDirection = value; + NeedsFormat = true; + } + } + + /// + /// Check if it is a horizontal direction + /// + public static bool IsHorizontalDirection (TextDirection textDirection) + { + switch (textDirection) { + case TextDirection.LeftRight_TopBottom: + case TextDirection.LeftRight_BottomTop: + case TextDirection.RightLeft_TopBottom: + case TextDirection.RightLeft_BottomTop: + return true; + default: + return false; + } + } + + /// + /// Check if it is a vertical direction + /// + public static bool IsVerticalDirection (TextDirection textDirection) + { + switch (textDirection) { + case TextDirection.TopBottom_LeftRight: + case TextDirection.TopBottom_RightLeft: + case TextDirection.BottomTop_LeftRight: + case TextDirection.BottomTop_RightLeft: + return true; + default: + return false; + } + } + + /// + /// Check if it is Left to Right direction + /// + public static bool IsLeftToRight (TextDirection textDirection) + { + switch (textDirection) { + case TextDirection.LeftRight_TopBottom: + case TextDirection.LeftRight_BottomTop: + return true; + default: + return false; + } + } + + /// + /// Check if it is Top to Bottom direction + /// + public static bool IsTopToBottom (TextDirection textDirection) + { + switch (textDirection) { + case TextDirection.TopBottom_LeftRight: + case TextDirection.TopBottom_RightLeft: + return true; + default: + return false; + } + } + + // TODO: This is not implemented! + /// + /// + /// + public bool WordWrap { get; set; } = false; + + + /// + /// Gets or sets the size of the area the text will be constrained to when formatted. + /// + /// + /// Does not return the size the formatted text; just the value that was set. + /// + public Size Size { + get { + return _size; + } + set { + _size = value; + NeedsFormat = true; + } + } + + /// + /// The specifier character for the hotkey (e.g. '_'). Set to '\xffff' to disable hotkey support for this View instance. The default is '\xffff'. + /// + public Rune HotKeySpecifier { get; set; } = (Rune)0xFFFF; + + /// + /// The position in the text of the hotkey. The hotkey will be rendered using the hot color. + /// + public int HotKeyPos { get => _hotKeyPos; set => _hotKeyPos = value; } + + /// + /// Gets the hotkey. Will be an upper case letter or digit. + /// + public Key HotKey { + get => _hotKey; + internal set { + if (_hotKey != value) { + var oldKey = _hotKey; + _hotKey = value; + HotKeyChanged?.Invoke (this, new KeyChangedEventArgs (oldKey, value)); + } + } + } + + /// + /// Gets the cursor position from . If the is defined, the cursor will be positioned over it. + /// + public int CursorPosition { get; set; } + + /// + /// Gets the size required to hold the formatted text, given the constraints placed by . + /// + /// + /// Causes a format, resetting . + /// + /// + public Size GetFormattedSize () + { + var lines = Lines; + var width = Lines.Max (line => TextFormatter.GetTextWidth (line)); + var height = Lines.Count; + return new Size (width, height); + } + + /// + /// Gets the formatted lines. + /// + /// + /// + /// Upon a 'get' of this property, if the text needs to be formatted (if is true) + /// will be called internally. + /// + /// + 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 + }; + NeedsFormat = false; + return _lines; + } + + if (NeedsFormat) { + var shown_text = _text; + if (FindHotKey (_text, HotKeySpecifier, true, out _hotKeyPos, out Key newHotKey)) { + HotKey = newHotKey; + shown_text = RemoveHotKeySpecifier (Text, _hotKeyPos, HotKeySpecifier); + shown_text = ReplaceHotKeyWithTag (shown_text, _hotKeyPos); + } + + if (IsVerticalDirection (_textDirection)) { + var colsWidth = GetSumMaxCharWidth (shown_text, 0, 1); + _lines = Format (shown_text, Size.Height, _textVerticalAlignment == VerticalTextAlignment.Justified, Size.Width > colsWidth, + PreserveTrailingSpaces, 0, _textDirection); + if (!AutoSize) { + colsWidth = GetMaxColsForWidth (_lines, Size.Width); + if (_lines.Count > colsWidth) { + _lines.RemoveRange (colsWidth, _lines.Count - colsWidth); + } + } + } else { + _lines = Format (shown_text, Size.Width, _textAlignment == TextAlignment.Justified, Size.Height > 1, + PreserveTrailingSpaces, 0, _textDirection); + if (!AutoSize && _lines.Count > Size.Height) { + _lines.RemoveRange (Size.Height, _lines.Count - Size.Height); + } + } + + NeedsFormat = false; + } + return _lines; + } + } + + /// + /// Gets or sets whether the needs to format the text when is called. + /// If it is false when Draw is called, the Draw call will be faster. + /// + /// + /// + /// This is set to true when the properties of are set. + /// + /// + public bool NeedsFormat { get; set; } + + /// + /// Causes the to reformat the text. + /// + /// The formatted text. + public string Format () + { + var sb = new StringBuilder (); + // Lines_get causes a Format + foreach (var line in Lines) { + sb.AppendLine (line.ToString ()); + } + return sb.ToString (); + } /// /// Draws the text held by to using the colors specified. @@ -1157,7 +1255,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 (ustring.IsNullOrEmpty (_text)) { return; } @@ -1166,7 +1264,7 @@ namespace Terminal.Gui { // Use "Lines" to ensure a Format (don't use "lines")) var linesFormated = Lines; - switch (textDirection) { + switch (_textDirection) { case TextDirection.TopBottom_RightLeft: case TextDirection.LeftRight_BottomTop: case TextDirection.RightLeft_BottomTop: @@ -1175,7 +1273,7 @@ namespace Terminal.Gui { break; } - var isVertical = IsVerticalDirection (textDirection); + var isVertical = IsVerticalDirection (_textDirection); var maxBounds = bounds; if (Application.Driver != null) { maxBounds = containerBounds == default @@ -1205,9 +1303,9 @@ namespace Terminal.Gui { break; - var runes = lines [line].ToRunes (); + var runes = _lines [line].ToRunes (); - switch (textDirection) { + switch (_textDirection) { case TextDirection.RightLeft_BottomTop: case TextDirection.RightLeft_TopBottom: case TextDirection.BottomTop_LeftRight: @@ -1220,52 +1318,52 @@ namespace Terminal.Gui { int x, y; // Horizontal Alignment - if (textAlignment == TextAlignment.Right || (textAlignment == TextAlignment.Justified && !IsLeftToRight (textDirection))) { + if (_textAlignment == TextAlignment.Right || (_textAlignment == TextAlignment.Justified && !IsLeftToRight (_textDirection))) { if (isVertical) { var runesWidth = GetSumMaxCharWidth (Lines, line); x = bounds.Right - runesWidth; - CursorPosition = bounds.Width - runesWidth + (hotKeyPos > -1 ? hotKeyPos : 0); + CursorPosition = bounds.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0); } else { var runesWidth = GetTextWidth (ustring.Make (runes)); x = bounds.Right - runesWidth; - CursorPosition = bounds.Width - runesWidth + (hotKeyPos > -1 ? hotKeyPos : 0); + CursorPosition = bounds.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0); } - } else if (textAlignment == TextAlignment.Left || textAlignment == TextAlignment.Justified) { + } else if (_textAlignment == TextAlignment.Left || _textAlignment == TextAlignment.Justified) { if (isVertical) { var runesWidth = line > 0 ? GetSumMaxCharWidth (Lines, 0, line) : 0; x = bounds.Left + runesWidth; } else { x = bounds.Left; } - CursorPosition = hotKeyPos > -1 ? hotKeyPos : 0; - } else if (textAlignment == TextAlignment.Centered) { + CursorPosition = _hotKeyPos > -1 ? _hotKeyPos : 0; + } else if (_textAlignment == TextAlignment.Centered) { if (isVertical) { var runesWidth = GetSumMaxCharWidth (Lines, line); x = bounds.Left + line + ((bounds.Width - runesWidth) / 2); - CursorPosition = (bounds.Width - runesWidth) / 2 + (hotKeyPos > -1 ? hotKeyPos : 0); + CursorPosition = (bounds.Width - runesWidth) / 2 + (_hotKeyPos > -1 ? _hotKeyPos : 0); } else { var runesWidth = GetTextWidth (ustring.Make (runes)); x = bounds.Left + (bounds.Width - runesWidth) / 2; - CursorPosition = (bounds.Width - runesWidth) / 2 + (hotKeyPos > -1 ? hotKeyPos : 0); + CursorPosition = (bounds.Width - runesWidth) / 2 + (_hotKeyPos > -1 ? _hotKeyPos : 0); } } else { throw new ArgumentOutOfRangeException (); } // Vertical Alignment - if (textVerticalAlignment == VerticalTextAlignment.Bottom || (textVerticalAlignment == VerticalTextAlignment.Justified && !IsTopToBottom (textDirection))) { + if (_textVerticalAlignment == VerticalTextAlignment.Bottom || (_textVerticalAlignment == VerticalTextAlignment.Justified && !IsTopToBottom (_textDirection))) { if (isVertical) { y = bounds.Bottom - runes.Length; } else { y = bounds.Bottom - Lines.Count + line; } - } else if (textVerticalAlignment == VerticalTextAlignment.Top || textVerticalAlignment == VerticalTextAlignment.Justified) { + } else if (_textVerticalAlignment == VerticalTextAlignment.Top || _textVerticalAlignment == VerticalTextAlignment.Justified) { if (isVertical) { y = bounds.Top; } else { y = bounds.Top + line; } - } else if (textVerticalAlignment == VerticalTextAlignment.Middle) { + } else if (_textVerticalAlignment == VerticalTextAlignment.Middle) { if (isVertical) { var s = (bounds.Height - runes.Length) / 2; y = bounds.Top + s; @@ -1307,8 +1405,8 @@ namespace Terminal.Gui { } } if (HotKeyPos > -1 && idx == HotKeyPos) { - if ((isVertical && textVerticalAlignment == VerticalTextAlignment.Justified) || - (!isVertical && textAlignment == TextAlignment.Justified)) { + if ((isVertical && _textVerticalAlignment == VerticalTextAlignment.Justified) || + (!isVertical && _textAlignment == TextAlignment.Justified)) { CursorPosition = idx - start; } Application.Driver?.SetAttribute (hotColor); diff --git a/Terminal.Gui/View/Border.cs b/Terminal.Gui/View/Border.cs index 80fe7c853..a68a48e27 100644 --- a/Terminal.Gui/View/Border.cs +++ b/Terminal.Gui/View/Border.cs @@ -6,115 +6,5 @@ using System.Text; using System.Collections.Generic; namespace Terminal.Gui { - /// - /// Specifies the border style for a and to be used by the class. - /// - public enum BorderStyle { - /// - /// No border is drawn. - /// - None, - /// - /// The border is drawn using single-width line glyphs. - /// - Single, - /// - /// The border is drawn using double-width line glyphs. - /// - Double, - /// - /// The border is drawn using single-width line glyphs with rounded corners. - /// - Rounded, - // TODO: Support Ruler - ///// - ///// The border is drawn as a diagnostic ruler ("|123456789..."). - ///// - //Ruler - } - - /// - /// Defines the visual border for a . Also provides helper APIS for rendering the border. - /// - public class Border { - - /// - /// Raised if any of the properties that define the border are changed. - /// - public event Action BorderChanged; - - private BorderStyle _style; - private Color _forgroundColor; - private Color _backgroundColor; - - /// - /// Specifies the for a view. - /// - [JsonInclude, JsonConverter (typeof (JsonStringEnumConverter))] - public BorderStyle BorderStyle { - get => _style; - set { - _style = value; - OnBorderChanged (); - } - } - - /// - /// Gets or sets the that draws the outer border color. - /// - [JsonInclude, JsonConverter (typeof (ColorJsonConverter))] - public Color ForgroundColor { - get => _forgroundColor; - set { - _forgroundColor = value; - OnBorderChanged (); - } - } - - /// - /// Gets or sets the that fills the area between the bounds of a . - /// - [JsonInclude, JsonConverter (typeof (ColorJsonConverter))] - public Color BackgroundColor { - get => _backgroundColor; - set { - _backgroundColor = value; - OnBorderChanged (); - } - } - - // TODO: These are all temporary to keep code compiling - /// - /// - /// - public bool DrawMarginFrame { get; set; } - /// - /// - /// - public Point Effect3DOffset { get; set; } = new Point (1, 1); - /// - /// - /// - public bool Effect3D { get; set; } - /// - /// - /// - public Thickness BorderThickness { get; set; } = new Thickness (0); - /// - /// - /// - public object Effect3DBrush { get; set; } - /// - /// - /// - public Thickness PaddingThickness { get; set; } = new Thickness (0); - - /// - /// Invoke the event. - /// - public virtual void OnBorderChanged () - { - BorderChanged?.Invoke (this); - } - } + } \ No newline at end of file diff --git a/Terminal.Gui/View/Frame.cs b/Terminal.Gui/View/Frame.cs index 6bc6c7c5e..c99ed7173 100644 --- a/Terminal.Gui/View/Frame.cs +++ b/Terminal.Gui/View/Frame.cs @@ -10,6 +10,7 @@ namespace Terminal.Gui { // TODO: v2 - If a Frame has focus, navigation keys (e.g Command.NextView) should cycle through SubViews of the Frame // QUESTION: How does a user navigate out of a Frame to another Frame, or back into the Parent's SubViews? + /// /// Frames are a special form of that act as adornments; they appear outside of the /// enabling borders, menus, etc... @@ -111,7 +112,7 @@ namespace Terminal.Gui { Driver.SetAttribute (prevAttr); } - if (Id == "BorderFrame" && BorderStyle != BorderStyle.None) { + if (Id == "BorderFrame" && BorderStyle != LineStyle.None) { var lc = new LineCanvas (); var drawTop = Thickness.Top > 0 && Frame.Width > 1 && Frame.Height > 1; @@ -131,9 +132,9 @@ namespace Terminal.Gui { // Add a short horiz line for ╔╡ lc.AddLine (screenBounds.Location, 1, Orientation.Horizontal, BorderStyle); // Add a short vert line for ╔╡ - lc.AddLine (new Point (screenBounds.X + 1, screenBounds.Location.Y), 0, Orientation.Vertical, BorderStyle.Single); + lc.AddLine (new Point (screenBounds.X + 1, screenBounds.Location.Y), 0, Orientation.Vertical, LineStyle.Single); // Add a short vert line for ╞ - lc.AddLine (new Point (screenBounds.X + 1 + (titleWidth + 1), screenBounds.Location.Y), 0, Orientation.Vertical, BorderStyle.Single); + lc.AddLine (new Point (screenBounds.X + 1 + (titleWidth + 1), screenBounds.Location.Y), 0, Orientation.Vertical, LineStyle.Single); // Add the right hand line for ╞═════╗ lc.AddLine (new Point (screenBounds.X + 1 + (titleWidth + 1), screenBounds.Location.Y), Frame.Width - (titleWidth + 3), Orientation.Horizontal, BorderStyle); } @@ -195,7 +196,7 @@ namespace Terminal.Gui { /// /// /// - public BorderStyle BorderStyle { get; set; } = BorderStyle.None; + public new LineStyle BorderStyle { get; set; } = LineStyle.None; /// /// Defines the rectangle that the will use to draw its content. @@ -206,6 +207,8 @@ namespace Terminal.Gui { var prev = _thickness; _thickness = value; if (prev != _thickness) { + + Parent?.LayoutFrames (); OnThicknessChanged (); } diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs index fa5de39fb..8567cd28d 100644 --- a/Terminal.Gui/View/View.cs +++ b/Terminal.Gui/View/View.cs @@ -118,19 +118,16 @@ namespace Terminal.Gui { /// /// public partial class View : Responder, ISupportInitializeNotification { - internal enum Direction { Forward, Backward } - // container == SuperView View _superView = null; - View focused = null; - Direction focusDirection; - bool autoSize; - - ShortcutHelper shortcutHelper; + View _focused = null; + Direction _focusDirection; + bool _autoSize; + ShortcutHelper _shortcutHelper; /// /// Event fired when this view is added to another. @@ -187,16 +184,26 @@ namespace Terminal.Gui { /// public event EventHandler HotKeyChanged; - Key hotKey = Key.Null; + Key _hotKey = Key.Null; /// /// Gets or sets the HotKey defined for this view. A user pressing HotKey on the keyboard while this view has focus will cause the Clicked event to fire. /// public virtual Key HotKey { - get => hotKey; + get => _hotKey; set { - if (hotKey != value) { - hotKey = TextFormatter.HotKey = (value == Key.Unknown ? Key.Null : value); + if (_hotKey != value) { + var v = value == Key.Unknown ? Key.Null : value; + if (_hotKey != Key.Null && ContainsKeyBinding (Key.Space | _hotKey)) { + if (v == Key.Null) { + ClearKeybinding (Key.Space | _hotKey); + } else { + ReplaceKeyBinding (Key.Space | _hotKey, Key.Space | v); + } + } else if (v != Key.Null) { + AddKeyBinding (Key.Space | v, Command.Accept); + } + _hotKey = TextFormatter.HotKey = v; } } } @@ -222,10 +229,10 @@ namespace Terminal.Gui { /// This is the global setting that can be used as a global shortcut to invoke an action if provided. /// public Key Shortcut { - get => shortcutHelper.Shortcut; + get => _shortcutHelper.Shortcut; set { - if (shortcutHelper.Shortcut != value && (ShortcutHelper.PostShortcutValidation (value) || value == Key.Null)) { - shortcutHelper.Shortcut = value; + if (_shortcutHelper.Shortcut != value && (ShortcutHelper.PostShortcutValidation (value) || value == Key.Null)) { + _shortcutHelper.Shortcut = value; } } } @@ -233,7 +240,7 @@ namespace Terminal.Gui { /// /// The keystroke combination used in the as string. /// - public ustring ShortcutTag => ShortcutHelper.GetShortcutTag (shortcutHelper.Shortcut); + public ustring ShortcutTag => ShortcutHelper.GetShortcutTag (_shortcutHelper.Shortcut); /// /// The action to run if the is defined. @@ -247,12 +254,12 @@ namespace Terminal.Gui { public object Data { get; set; } internal Direction FocusDirection { - get => SuperView?.FocusDirection ?? focusDirection; + get => SuperView?.FocusDirection ?? _focusDirection; set { if (SuperView != null) SuperView.FocusDirection = value; else - focusDirection = value; + _focusDirection = value; } } @@ -262,23 +269,23 @@ namespace Terminal.Gui { /// public static ConsoleDriver Driver => Application.Driver; - static readonly IList empty = new List (0).AsReadOnly (); + static readonly IList _empty = new List (0).AsReadOnly (); // This is null, and allocated on demand. - List subviews; + List _subviews; /// /// This returns a list of the subviews contained by this view. /// /// The subviews. - public IList Subviews => subviews?.AsReadOnly () ?? empty; + public IList Subviews => _subviews?.AsReadOnly () ?? _empty; // Internally, we use InternalSubviews rather than subviews, as we do not expect us // to make the same mistakes our users make when they poke at the Subviews. - internal IList InternalSubviews => subviews ?? empty; + internal IList InternalSubviews => _subviews ?? _empty; // This is null, and allocated on demand. - List tabIndexes; + List _tabIndexes; /// /// Configurable keybindings supported by the control @@ -290,30 +297,30 @@ namespace Terminal.Gui { /// This returns a tab index list of the subviews contained by this view. /// /// The tabIndexes. - public IList TabIndexes => tabIndexes?.AsReadOnly () ?? empty; + public IList TabIndexes => _tabIndexes?.AsReadOnly () ?? _empty; - int tabIndex = -1; + int _tabIndex = -1; /// /// Indicates the index of the current from the list. /// public int TabIndex { - get { return tabIndex; } + get { return _tabIndex; } set { if (!CanFocus) { - tabIndex = -1; + _tabIndex = -1; return; - } else if (SuperView?.tabIndexes == null || SuperView?.tabIndexes.Count == 1) { - tabIndex = 0; + } else if (SuperView?._tabIndexes == null || SuperView?._tabIndexes.Count == 1) { + _tabIndex = 0; return; - } else if (tabIndex == value) { + } else if (_tabIndex == value) { return; } - tabIndex = value > SuperView.tabIndexes.Count - 1 ? SuperView.tabIndexes.Count - 1 : value < 0 ? 0 : value; - tabIndex = GetTabIndex (tabIndex); - if (SuperView.tabIndexes.IndexOf (this) != tabIndex) { - SuperView.tabIndexes.Remove (this); - SuperView.tabIndexes.Insert (tabIndex, this); + _tabIndex = value > SuperView._tabIndexes.Count - 1 ? SuperView._tabIndexes.Count - 1 : value < 0 ? 0 : value; + _tabIndex = GetTabIndex (_tabIndex); + if (SuperView._tabIndexes.IndexOf (this) != _tabIndex) { + SuperView._tabIndexes.Remove (this); + SuperView._tabIndexes.Insert (_tabIndex, this); SetTabIndex (); } } @@ -322,8 +329,8 @@ namespace Terminal.Gui { int GetTabIndex (int idx) { var i = 0; - foreach (var v in SuperView.tabIndexes) { - if (v.tabIndex == -1 || v == this) { + foreach (var v in SuperView._tabIndexes) { + if (v._tabIndex == -1 || v == this) { continue; } i++; @@ -334,60 +341,60 @@ namespace Terminal.Gui { void SetTabIndex () { var i = 0; - foreach (var v in SuperView.tabIndexes) { - if (v.tabIndex == -1) { + foreach (var v in SuperView._tabIndexes) { + if (v._tabIndex == -1) { continue; } - v.tabIndex = i; + v._tabIndex = i; i++; } } - bool tabStop = true; + bool _tabStop = true; /// /// This only be if the is also /// and the focus can be avoided by setting this to /// public bool TabStop { - get => tabStop; + get => _tabStop; set { - if (tabStop == value) { + if (_tabStop == value) { return; } - tabStop = CanFocus && value; + _tabStop = CanFocus && value; } } - bool oldCanFocus; - int oldTabIndex; + bool _oldCanFocus; + int _oldTabIndex; /// public override bool CanFocus { get => base.CanFocus; set { - if (!addingView && IsInitialized && SuperView?.CanFocus == false && value) { + if (!_addingView && IsInitialized && SuperView?.CanFocus == false && value) { throw new InvalidOperationException ("Cannot set CanFocus to true if the SuperView CanFocus is false!"); } if (base.CanFocus != value) { base.CanFocus = value; switch (value) { - case false when tabIndex > -1: + case false when _tabIndex > -1: TabIndex = -1; break; - case true when SuperView?.CanFocus == false && addingView: + case true when SuperView?.CanFocus == false && _addingView: SuperView.CanFocus = true; break; } - if (value && tabIndex == -1) { - TabIndex = SuperView != null ? SuperView.tabIndexes.IndexOf (this) : -1; + if (value && _tabIndex == -1) { + TabIndex = SuperView != null ? SuperView._tabIndexes.IndexOf (this) : -1; } TabStop = value; if (!value && SuperView?.Focused == this) { - SuperView.focused = null; + SuperView._focused = null; } if (!value && HasFocus) { SetHasFocus (false, this); @@ -400,21 +407,21 @@ namespace Terminal.Gui { Application.EnsuresTopOnFront (); } } - if (subviews != null && IsInitialized) { - foreach (var view in subviews) { + if (_subviews != null && IsInitialized) { + foreach (var view in _subviews) { if (view.CanFocus != value) { if (!value) { - view.oldCanFocus = view.CanFocus; - view.oldTabIndex = view.tabIndex; + view._oldCanFocus = view.CanFocus; + view._oldTabIndex = view._tabIndex; view.CanFocus = false; - view.tabIndex = -1; + view._tabIndex = -1; } else { - if (addingView) { - view.addingView = true; + if (_addingView) { + view._addingView = true; } - view.CanFocus = view.oldCanFocus; - view.tabIndex = view.oldTabIndex; - view.addingView = false; + view.CanFocus = view._oldCanFocus; + view._tabIndex = view._oldTabIndex; + view._addingView = false; } } } @@ -426,7 +433,7 @@ namespace Terminal.Gui { } // The frame for the object. Superview relative. - Rect frame; + Rect _frame; /// /// Gets or sets an identifier for the view; @@ -465,9 +472,9 @@ namespace Terminal.Gui { /// /// public virtual Rect Frame { - get => frame; + get => _frame; set { - frame = new Rect (value.X, value.Y, Math.Max (value.Width, 0), Math.Max (value.Height, 0)); + _frame = new Rect (value.X, value.Y, Math.Max (value.Width, 0), Math.Max (value.Height, 0)); if (IsInitialized || LayoutStyle == LayoutStyle.Absolute) { TextFormatter.Size = GetSizeNeededForTextAndHotKey (); LayoutFrames (); @@ -490,6 +497,9 @@ namespace Terminal.Gui { /// title will take up the first row and the second row will be filled with spaces. /// The Border is not part of the View's content and is not clipped by the View's `ClipArea`. /// + /// + /// provides a simple helper for turning a simple border frame on or off. + /// public Frame BorderFrame { get; private set; } /// @@ -501,6 +511,19 @@ namespace Terminal.Gui { /// public Frame Padding { get; private set; } + /// + /// Helper to get the total thickness of the , , and . + /// + /// A thickness that describes the sum of the Frames' thicknesses. + public Thickness GetFramesThickness () + { + var left = Margin.Thickness.Left + BorderFrame.Thickness.Left + Padding.Thickness.Left; + var top = Margin.Thickness.Top + BorderFrame.Thickness.Top + Padding.Thickness.Top; + var right = Margin.Thickness.Right + BorderFrame.Thickness.Right + Padding.Thickness.Right; + var bottom = Margin.Thickness.Bottom + BorderFrame.Thickness.Bottom + Padding.Thickness.Bottom; + return new Thickness (left, top, right, bottom); + } + /// /// Helper to get the X and Y offset of the Bounds from the Frame. This is the sum of the Left and Top properties of /// , and . @@ -530,8 +553,7 @@ namespace Terminal.Gui { BorderFrame.ThicknessChanged -= ThicknessChangedHandler; BorderFrame.Dispose (); } - // TODO: create default for borderstyle - BorderFrame = new Frame () { Id = "BorderFrame", Thickness = new Thickness (0), BorderStyle = BorderStyle.Single }; + BorderFrame = new Frame () { Id = "BorderFrame", Thickness = new Thickness (0) }; BorderFrame.ThicknessChanged += ThicknessChangedHandler; BorderFrame.Parent = this; @@ -546,7 +568,7 @@ namespace Terminal.Gui { Padding.Parent = this; } - ustring title = ustring.Empty; + ustring _title = ustring.Empty; /// /// The title to be displayed for this . The title will be displayed if . @@ -554,18 +576,18 @@ namespace Terminal.Gui { /// /// The title. public ustring Title { - get => title; + get => _title; set { - if (!OnTitleChanging (title, value)) { - var old = title; - title = value; + if (!OnTitleChanging (_title, value)) { + var old = _title; + _title = value; SetNeedsDisplay (); #if DEBUG - if (title != null && string.IsNullOrEmpty (Id)) { - Id = title.ToString (); + if (_title != null && string.IsNullOrEmpty (Id)) { + Id = _title.ToString (); } #endif // DEBUG - OnTitleChanged (old, title); + OnTitleChanged (old, _title); } } } @@ -680,7 +702,7 @@ namespace Terminal.Gui { return dim; } - Pos x, y; + Pos _x, _y; /// /// Gets or sets the X position for the view (the column). Only used if the is . @@ -690,13 +712,13 @@ namespace Terminal.Gui { /// If is changing this property has no effect and its value is indeterminate. /// public Pos X { - get => VerifyIsIntialized (x); + get => VerifyIsIntialized (_x); set { - if (ForceValidatePosDim && !ValidatePosDim (x, value)) { + if (ForceValidatePosDim && !ValidatePosDim (_x, value)) { throw new ArgumentException (); } - x = value; + _x = value; OnResizeNeeded (); } @@ -710,18 +732,18 @@ namespace Terminal.Gui { /// If is changing this property has no effect and its value is indeterminate. /// public Pos Y { - get => VerifyIsIntialized (y); + get => VerifyIsIntialized (_y); set { - if (ForceValidatePosDim && !ValidatePosDim (y, value)) { + if (ForceValidatePosDim && !ValidatePosDim (_y, value)) { throw new ArgumentException (); } - y = value; + _y = value; OnResizeNeeded (); } } - Dim width, height; + Dim _width, _height; /// /// Gets or sets the width of the view. Only used the is . @@ -731,18 +753,18 @@ namespace Terminal.Gui { /// If is changing this property has no effect and its value is indeterminate. /// public Dim Width { - get => VerifyIsIntialized (width); + get => VerifyIsIntialized (_width); set { - if (ForceValidatePosDim && !ValidatePosDim (width, value)) { + if (ForceValidatePosDim && !ValidatePosDim (_width, value)) { throw new ArgumentException ("ForceValidatePosDim is enabled", nameof (Width)); } - width = value; + _width = value; if (ForceValidatePosDim) { - var isValidNewAutSize = autoSize && IsValidAutoSizeWidth (width); + var isValidNewAutSize = AutoSize && IsValidAutoSizeWidth (_width); - if (IsAdded && autoSize && !isValidNewAutSize) { + if (IsAdded && AutoSize && !isValidNewAutSize) { throw new InvalidOperationException ("Must set AutoSize to false before set the Width."); } } @@ -756,18 +778,18 @@ namespace Terminal.Gui { /// The height. /// If is changing this property has no effect and its value is indeterminate. public Dim Height { - get => VerifyIsIntialized (height); + get => VerifyIsIntialized (_height); set { - if (ForceValidatePosDim && !ValidatePosDim (height, value)) { + if (ForceValidatePosDim && !ValidatePosDim (_height, value)) { throw new ArgumentException ("ForceValidatePosDim is enabled", nameof (Height)); } - height = value; + _height = value; if (ForceValidatePosDim) { - var isValidNewAutSize = autoSize && IsValidAutoSizeHeight (height); + var isValidNewAutSize = AutoSize && IsValidAutoSizeHeight (_height); - if (IsAdded && autoSize && !isValidNewAutSize) { + if (IsAdded && AutoSize && !isValidNewAutSize) { throw new InvalidOperationException ("Must set AutoSize to false before set the Height."); } } @@ -815,7 +837,7 @@ namespace Terminal.Gui { case true: 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 && + if (_frame.Width < colWidth && (Width == null || (Bounds.Width >= 0 && Width is Dim.DimAbsolute && @@ -826,7 +848,7 @@ namespace Terminal.Gui { } break; default: - if (frame.Height < 1 && + if (_frame.Height < 1 && (Height == null || (Height is Dim.DimAbsolute && Height.Anchor (0) == 0))) { @@ -855,7 +877,7 @@ namespace Terminal.Gui { } /// - /// Gets or sets the which can be handled differently by any derived class. + /// Gets or sets the used to format . /// public TextFormatter TextFormatter { get; set; } @@ -874,14 +896,14 @@ namespace Terminal.Gui { /// /// Initializes a new instance of a class with the absolute - /// dimensions specified in the parameter. + /// dimensions specified in the parameter. /// /// The region covered by this view. /// /// This constructor initialize a View with a of . /// Use to initialize a View with of /// - public View (Rect frame) : this (frame, null, null) { } + public View (Rect frame) : this (frame, null) { } /// /// Initializes a new instance of using layout. @@ -936,10 +958,9 @@ namespace Terminal.Gui { /// /// Location. /// text to initialize the property with. - /// The . - public View (Rect rect, ustring text, Border border = null) + public View (Rect rect, ustring text) { - SetInitialProperties (text, rect, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom, border); + SetInitialProperties (text, rect, LayoutStyle.Absolute, TextDirection.LeftRight_TopBottom); } /// @@ -957,10 +978,9 @@ namespace Terminal.Gui { /// /// text to initialize the property with. /// The text direction. - /// The . - public View (ustring text, TextDirection direction = TextDirection.LeftRight_TopBottom, Border border = null) + public View (ustring text, TextDirection direction = TextDirection.LeftRight_TopBottom) { - SetInitialProperties (text, Rect.Empty, LayoutStyle.Computed, direction, border); + SetInitialProperties (text, Rect.Empty, LayoutStyle.Computed, direction); } // TODO: v2 - Remove constructors with parameters @@ -971,22 +991,19 @@ namespace Terminal.Gui { /// /// /// - /// void SetInitialProperties (ustring text, Rect rect, LayoutStyle layoutStyle = LayoutStyle.Computed, - TextDirection direction = TextDirection.LeftRight_TopBottom, Border border = null) + TextDirection direction = TextDirection.LeftRight_TopBottom) { TextFormatter = new TextFormatter (); TextFormatter.HotKeyChanged += TextFormatter_HotKeyChanged; TextDirection = direction; - shortcutHelper = new ShortcutHelper (); + _shortcutHelper = new ShortcutHelper (); CanFocus = false; TabIndex = -1; TabStop = false; LayoutStyle = layoutStyle; - Border = border; - Text = text == null ? ustring.Empty : text; LayoutStyle = layoutStyle; var r = rect.IsEmpty ? TextFormatter.CalcRect (0, 0, text, direction) : rect; @@ -998,14 +1015,6 @@ namespace Terminal.Gui { LayoutFrames (); } - // TODO: v2 - Hack for now - private void Border_BorderChanged (Border border) - { - //if (!border.DrawMarginFrame) BorderFrame.BorderStyle = BorderStyle.None; - BorderFrame.BorderStyle = border.BorderStyle; - BorderFrame.Thickness = new Thickness (BorderFrame.BorderStyle == BorderStyle.None ? 0 : 1); - } - /// /// Can be overridden if the has /// different format than the default. @@ -1013,30 +1022,35 @@ namespace Terminal.Gui { protected virtual void UpdateTextFormatterText () { if (TextFormatter != null) { - TextFormatter.Text = text; + TextFormatter.Text = _text; } } /// - /// Called whenever the view needs to be resized. - /// Can be overridden if the view resize behavior is - /// different than the default. + /// Called whenever the view needs to be resized. Sets and + /// triggers a call. /// /// + /// + /// Can be overridden if the view resize behavior is different than the default. + /// protected virtual void OnResizeNeeded () { - var actX = x is Pos.PosAbsolute ? x.Anchor (0) : frame.X; - var actY = y is Pos.PosAbsolute ? y.Anchor (0) : frame.Y; + var actX = _x is Pos.PosAbsolute ? _x.Anchor (0) : _frame.X; + var actY = _y is Pos.PosAbsolute ? _y.Anchor (0) : _frame.Y; if (AutoSize) { + //if (TextAlignment == TextAlignment.Justified) { + // throw new InvalidOperationException ("TextAlignment.Justified cannot be used with AutoSize"); + //} var s = GetAutoSize (); - var w = width is Dim.DimAbsolute && width.Anchor (0) > s.Width ? width.Anchor (0) : s.Width; - var h = height is Dim.DimAbsolute && height.Anchor (0) > s.Height ? height.Anchor (0) : s.Height; - frame = new Rect (new Point (actX, actY), new Size (w, h)); // Set frame, not Frame! + var w = _width is Dim.DimAbsolute && _width.Anchor (0) > s.Width ? _width.Anchor (0) : s.Width; + var h = _height is Dim.DimAbsolute && _height.Anchor (0) > s.Height ? _height.Anchor (0) : s.Height; + _frame = new Rect (new Point (actX, actY), new Size (w, h)); // Set frame, not Frame! } else { - var w = width is Dim.DimAbsolute ? width.Anchor (0) : frame.Width; - var h = height is Dim.DimAbsolute ? height.Anchor (0) : frame.Height; + var w = _width is Dim.DimAbsolute ? _width.Anchor (0) : _frame.Width; + var h = _height is Dim.DimAbsolute ? _height.Anchor (0) : _frame.Height; // BUGBUG: v2 - ? - If layoutstyle is absolute, this overwrites the current frame h/w with 0. Hmmm... - frame = new Rect (new Point (actX, actY), new Size (w, h)); // Set frame, not Frame! + _frame = new Rect (new Point (actX, actY), new Size (w, h)); // Set frame, not Frame! } @@ -1108,10 +1122,10 @@ namespace Terminal.Gui { } _superView?.SetSubViewNeedsDisplay (); - if (subviews == null) + if (_subviews == null) return; - foreach (var view in subviews) + foreach (var view in _subviews) if (view.Frame.IntersectsWith (region)) { var childRegion = Rect.Intersect (view.Frame, region); childRegion.X -= view.Frame.X; @@ -1147,7 +1161,7 @@ namespace Terminal.Gui { _superView.SetSubViewNeedsDisplay (); } - internal bool addingView; + internal bool _addingView; /// /// Adds a subview (child) to this view. @@ -1161,28 +1175,28 @@ namespace Terminal.Gui { if (view == null) { return; } - if (subviews == null) { - subviews = new List (); + if (_subviews == null) { + _subviews = new List (); } - if (tabIndexes == null) { - tabIndexes = new List (); + if (_tabIndexes == null) { + _tabIndexes = new List (); } - subviews.Add (view); - tabIndexes.Add (view); + _subviews.Add (view); + _tabIndexes.Add (view); view._superView = this; if (view.CanFocus) { - addingView = true; + _addingView = true; if (SuperView?.CanFocus == false) { - SuperView.addingView = true; + SuperView._addingView = true; SuperView.CanFocus = true; - SuperView.addingView = false; + SuperView._addingView = false; } CanFocus = true; - view.tabIndex = tabIndexes.IndexOf (view); - addingView = false; + view._tabIndex = _tabIndexes.IndexOf (view); + _addingView = false; } if (view.Enabled && !Enabled) { - view.oldEnabled = true; + view._oldEnabled = true; view.Enabled = false; } SetNeedsLayout (); @@ -1219,12 +1233,12 @@ namespace Terminal.Gui { /// public virtual void RemoveAll () { - if (subviews == null) { + if (_subviews == null) { return; } - while (subviews.Count > 0) { - Remove (subviews [0]); + while (_subviews.Count > 0) { + Remove (_subviews [0]); } } @@ -1235,29 +1249,29 @@ namespace Terminal.Gui { /// public virtual void Remove (View view) { - if (view == null || subviews == null) return; + if (view == null || _subviews == null) return; var touched = view.Frame; - subviews.Remove (view); - tabIndexes.Remove (view); + _subviews.Remove (view); + _tabIndexes.Remove (view); view._superView = null; - view.tabIndex = -1; + view._tabIndex = -1; SetNeedsLayout (); SetNeedsDisplay (); - foreach (var v in subviews) { + foreach (var v in _subviews) { if (v.Frame.IntersectsWith (touched)) view.SetNeedsDisplay (); } OnRemoved (new SuperViewChangedEventArgs (this, view)); - if (focused == view) { - focused = null; + if (_focused == view) { + _focused = null; } } void PerformActionForSubview (View subview, Action action) { - if (subviews.Contains (subview)) { + if (_subviews.Contains (subview)) { action (subview); } @@ -1275,8 +1289,8 @@ namespace Terminal.Gui { public void BringSubviewToFront (View subview) { PerformActionForSubview (subview, x => { - subviews.Remove (x); - subviews.Add (x); + _subviews.Remove (x); + _subviews.Add (x); }); } @@ -1290,8 +1304,8 @@ namespace Terminal.Gui { public void SendSubviewToBack (View subview) { PerformActionForSubview (subview, x => { - subviews.Remove (x); - subviews.Insert (0, subview); + _subviews.Remove (x); + _subviews.Insert (0, subview); }); } @@ -1305,10 +1319,10 @@ namespace Terminal.Gui { public void SendSubviewBackwards (View subview) { PerformActionForSubview (subview, x => { - var idx = subviews.IndexOf (x); + var idx = _subviews.IndexOf (x); if (idx > 0) { - subviews.Remove (x); - subviews.Insert (idx - 1, x); + _subviews.Remove (x); + _subviews.Insert (idx - 1, x); } }); } @@ -1323,10 +1337,10 @@ namespace Terminal.Gui { public void BringSubviewForward (View subview) { PerformActionForSubview (subview, x => { - var idx = subviews.IndexOf (x); - if (idx + 1 < subviews.Count) { - subviews.Remove (x); - subviews.Insert (idx + 1, x); + var idx = _subviews.IndexOf (x); + if (idx + 1 < _subviews.Count) { + _subviews.Remove (x); + _subviews.Insert (idx + 1, x); } }); } @@ -1379,10 +1393,10 @@ namespace Terminal.Gui { public Point ScreenToView (int x, int y) { if (SuperView == null) { - return new Point (x - Frame.X, y - frame.Y); + return new Point (x - Frame.X, y - _frame.Y); } else { var parent = SuperView.ScreenToView (x, y); - return new Point (parent.X - frame.X, parent.Y - frame.Y); + return new Point (parent.X - _frame.X, parent.Y - _frame.Y); } } @@ -1399,7 +1413,7 @@ namespace Terminal.Gui { return new Point (x - Frame.X + boundsOffset.X, y - Frame.Y + boundsOffset.Y); } else { var parent = SuperView.ScreenToView (x, y); - return new Point (parent.X - frame.X, parent.Y - frame.Y); + return new Point (parent.X - _frame.X, parent.Y - _frame.Y); } } @@ -1577,16 +1591,16 @@ namespace Terminal.Gui { // BUGBUG: v2 - This needs to support children of Frames too - if (focused == null && SuperView != null) { + if (_focused == null && SuperView != null) { SuperView.EnsureFocus (); - } else if (focused?.Visible == true && focused?.Enabled == true && focused?.Frame.Width > 0 && focused.Frame.Height > 0) { - focused.PositionCursor (); - } else if (focused?.Visible == true && focused?.Enabled == false) { - focused = null; + } else if (_focused?.Visible == true && _focused?.Enabled == true && _focused?.Frame.Width > 0 && _focused.Frame.Height > 0) { + _focused.PositionCursor (); + } else if (_focused?.Visible == true && _focused?.Enabled == false) { + _focused = null; } else if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0) { Move (TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition, 0); } else { - Move (frame.X, frame.Y); + Move (_frame.X, _frame.Y); } } @@ -1609,11 +1623,11 @@ namespace Terminal.Gui { } // Remove focus down the chain of subviews if focus is removed - if (!value && focused != null) { - var f = focused; + if (!value && _focused != null) { + var f = _focused; f.OnLeave (view); f.SetHasFocus (false, view); - focused = null; + _focused = null; } } @@ -1625,10 +1639,10 @@ namespace Terminal.Gui { { var view = e.Child; view.IsAdded = true; - view.x ??= view.frame.X; - view.y ??= view.frame.Y; - view.width ??= view.frame.Width; - view.height ??= view.frame.Height; + view._x ??= view._frame.X; + view._y ??= view._frame.Y; + view._width ??= view._frame.Width; + view._height ??= view._frame.Height; view.Added?.Invoke (this, e); } @@ -1674,7 +1688,7 @@ namespace Terminal.Gui { /// Returns the currently focused view inside this view, or null if nothing is focused. /// /// The focused. - public View Focused => focused; + public View Focused => _focused; /// /// Returns the most focused view in the chain of subviews (the leaf view that has the focus). @@ -1691,7 +1705,7 @@ namespace Terminal.Gui { } } - ColorScheme colorScheme; + ColorScheme _colorScheme; /// /// The color scheme for this view, if it is not defined, it returns the 's @@ -1699,14 +1713,14 @@ namespace Terminal.Gui { /// public virtual ColorScheme ColorScheme { get { - if (colorScheme == null) { + if (_colorScheme == null) { return SuperView?.ColorScheme; } - return colorScheme; + return _colorScheme; } set { - if (colorScheme != value) { - colorScheme = value; + if (_colorScheme != value) { + _colorScheme = value; SetNeedsDisplay (); } } @@ -1722,7 +1736,7 @@ namespace Terminal.Gui { { if (row < 0 || col < 0) return; - if (row > frame.Height - 1 || col > frame.Width - 1) + if (row > _frame.Height - 1 || col > _frame.Width - 1) return; Move (col, row); Driver.AddRune (ch); @@ -1800,8 +1814,8 @@ namespace Terminal.Gui { // Draw subviews // TODO: Implement OnDrawSubviews (cancelable); - if (subviews != null) { - foreach (var view in subviews) { + if (_subviews != null) { + foreach (var view in _subviews) { if (view.Visible) { //!view._needsDisplay.IsEmpty || view._childNeedsDisplay || view.LayoutNeeded) { if (true) { //view.Frame.IntersectsWith (bounds)) { // && (view.Frame.IntersectsWith (bounds) || bounds.X < 0 || bounds.Y < 0)) { if (view.LayoutNeeded) { @@ -1903,10 +1917,10 @@ namespace Terminal.Gui { if (!view.CanFocus || !view.Visible || !view.Enabled) { return; } - if (focused?._hasFocus == true && focused == view) { + if (_focused?._hasFocus == true && _focused == view) { return; } - if ((focused?._hasFocus == true && focused?.SuperView == view) || view == this) { + if ((_focused?._hasFocus == true && _focused?.SuperView == view) || view == this) { if (!view._hasFocus) { view._hasFocus = true; @@ -1921,13 +1935,13 @@ namespace Terminal.Gui { if (c == null) throw new ArgumentException ("the specified view is not part of the hierarchy of this view"); - if (focused != null) - focused.SetHasFocus (false, view); + if (_focused != null) + _focused.SetHasFocus (false, view); - var f = focused; - focused = view; - focused.SetHasFocus (true, f); - focused.EnsureFocus (); + var f = _focused; + _focused = view; + _focused.SetHasFocus (true, f); + _focused.EnsureFocus (); // Send focus upwards if (SuperView != null) { @@ -2151,10 +2165,10 @@ namespace Terminal.Gui { } if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) return true; - if (subviews == null || subviews.Count == 0) + if (_subviews == null || _subviews.Count == 0) return false; - foreach (var view in subviews) + foreach (var view in _subviews) if (view.Enabled && view.ProcessHotKey (keyEvent)) return true; return false; @@ -2178,10 +2192,10 @@ namespace Terminal.Gui { } if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) return true; - if (subviews == null || subviews.Count == 0) + if (_subviews == null || _subviews.Count == 0) return false; - foreach (var view in subviews) + foreach (var view in _subviews) if (view.Enabled && view.ProcessColdKey (keyEvent)) return true; return false; @@ -2252,7 +2266,7 @@ namespace Terminal.Gui { /// public void EnsureFocus () { - if (focused == null && subviews?.Count > 0) { + if (_focused == null && _subviews?.Count > 0) { if (FocusDirection == Direction.Forward) { FocusFirst (); } else { @@ -2270,13 +2284,13 @@ namespace Terminal.Gui { return; } - if (tabIndexes == null) { + if (_tabIndexes == null) { SuperView?.SetFocus (this); return; } - foreach (var view in tabIndexes) { - if (view.CanFocus && view.tabStop && view.Visible && view.Enabled) { + foreach (var view in _tabIndexes) { + if (view.CanFocus && view._tabStop && view.Visible && view.Enabled) { SetFocus (view); return; } @@ -2292,16 +2306,16 @@ namespace Terminal.Gui { return; } - if (tabIndexes == null) { + if (_tabIndexes == null) { SuperView?.SetFocus (this); return; } - for (var i = tabIndexes.Count; i > 0;) { + for (var i = _tabIndexes.Count; i > 0;) { i--; - var v = tabIndexes [i]; - if (v.CanFocus && v.tabStop && v.Visible && v.Enabled) { + var v = _tabIndexes [i]; + if (v.CanFocus && v._tabStop && v.Visible && v.Enabled) { SetFocus (v); return; } @@ -2319,18 +2333,18 @@ namespace Terminal.Gui { } FocusDirection = Direction.Backward; - if (tabIndexes == null || tabIndexes.Count == 0) + if (_tabIndexes == null || _tabIndexes.Count == 0) return false; - if (focused == null) { + if (_focused == null) { FocusLast (); - return focused != null; + return _focused != null; } var focusedIdx = -1; - for (var i = tabIndexes.Count; i > 0;) { + for (var i = _tabIndexes.Count; i > 0;) { i--; - var w = tabIndexes [i]; + var w = _tabIndexes [i]; if (w.HasFocus) { if (w.FocusPrev ()) @@ -2338,19 +2352,19 @@ namespace Terminal.Gui { focusedIdx = i; continue; } - if (w.CanFocus && focusedIdx != -1 && w.tabStop && w.Visible && w.Enabled) { - focused.SetHasFocus (false, w); + if (w.CanFocus && focusedIdx != -1 && w._tabStop && w.Visible && w.Enabled) { + _focused.SetHasFocus (false, w); - if (w.CanFocus && w.tabStop && w.Visible && w.Enabled) + if (w.CanFocus && w._tabStop && w.Visible && w.Enabled) w.FocusLast (); SetFocus (w); return true; } } - if (focused != null) { - focused.SetHasFocus (false, this); - focused = null; + if (_focused != null) { + _focused.SetHasFocus (false, this); + _focused = null; } return false; } @@ -2366,16 +2380,16 @@ namespace Terminal.Gui { } FocusDirection = Direction.Forward; - if (tabIndexes == null || tabIndexes.Count == 0) + if (_tabIndexes == null || _tabIndexes.Count == 0) return false; - if (focused == null) { + if (_focused == null) { FocusFirst (); - return focused != null; + return _focused != null; } var focusedIdx = -1; - for (var i = 0; i < tabIndexes.Count; i++) { - var w = tabIndexes [i]; + for (var i = 0; i < _tabIndexes.Count; i++) { + var w = _tabIndexes [i]; if (w.HasFocus) { if (w.FocusNext ()) @@ -2383,19 +2397,19 @@ namespace Terminal.Gui { focusedIdx = i; continue; } - if (w.CanFocus && focusedIdx != -1 && w.tabStop && w.Visible && w.Enabled) { - focused.SetHasFocus (false, w); + if (w.CanFocus && focusedIdx != -1 && w._tabStop && w.Visible && w.Enabled) { + _focused.SetHasFocus (false, w); - if (w.CanFocus && w.tabStop && w.Visible && w.Enabled) + if (w.CanFocus && w._tabStop && w.Visible && w.Enabled) w.FocusFirst (); SetFocus (w); return true; } } - if (focused != null) { - focused.SetHasFocus (false, this); - focused = null; + if (_focused != null) { + _focused.SetHasFocus (false, this); + _focused = null; } return false; } @@ -2406,7 +2420,7 @@ namespace Terminal.Gui { return null; } - return view.focused != null ? GetMostFocused (view.focused) : view; + return view._focused != null ? GetMostFocused (view._focused) : view; } /// @@ -2510,10 +2524,10 @@ namespace Terminal.Gui { // horizontal - (newX, newW) = GetNewLocationAndDimension (superviewFrame.X, superviewFrame.Width, x, width, autosize.Width); + (newX, newW) = GetNewLocationAndDimension (superviewFrame.X, superviewFrame.Width, _x, _width, autosize.Width); // vertical - (newY, newH) = GetNewLocationAndDimension (superviewFrame.Y, superviewFrame.Height, y, height, autosize.Height); + (newY, newH) = GetNewLocationAndDimension (superviewFrame.Y, superviewFrame.Height, _y, _height, autosize.Height); var r = new Rect (newX, newY, newW, newH); if (Frame != r) { @@ -2773,33 +2787,36 @@ namespace Terminal.Gui { v.LayoutNeeded = false; } - ustring text; + ustring _text; /// /// The text displayed by the . /// /// /// - /// If provided, the text will be drawn before any subviews are drawn. + /// The text will be drawn before any subviews are drawn. /// /// /// The text will be drawn starting at the view origin (0, 0) and will be formatted according - /// to the property. If the view's height is greater than 1, the - /// text will word-wrap to additional lines if it does not fit horizontally. If the view's height - /// is 1, the text will be clipped. + /// to and . /// /// + /// The text will word-wrap to additional lines if it does not fit horizontally. If 's height + /// is 1, the text will be clipped. + /// + /// /// Set the to enable hotkey support. To disable hotkey support set to /// (Rune)0xffff. /// /// public virtual ustring Text { - get => text; + get => _text; set { - text = value; + _text = value; if (IsInitialized) { SetHotKey (); UpdateTextFormatterText (); + //TextFormatter.Format (); OnResizeNeeded (); } @@ -2808,8 +2825,8 @@ namespace Terminal.Gui { UpdateTextFormatterText (); #if DEBUG - if (text != null && string.IsNullOrEmpty (Id)) { - Id = text.ToString (); + if (_text != null && string.IsNullOrEmpty (Id)) { + Id = _text.ToString (); } #endif } @@ -2829,12 +2846,12 @@ namespace Terminal.Gui { /// /// public virtual bool AutoSize { - get => autoSize; + get => _autoSize; set { var v = ResizeView (value); TextFormatter.AutoSize = v; - if (autoSize != v) { - autoSize = v; + if (_autoSize != v) { + _autoSize = v; TextFormatter.NeedsFormat = true; UpdateTextFormatterText (); OnResizeNeeded (); @@ -2843,11 +2860,10 @@ namespace Terminal.Gui { } /// - /// Gets or sets a flag that determines whether will have trailing spaces preserved - /// or not when is enabled. If - /// any trailing spaces will be trimmed when either the property is changed or - /// when is set to . - /// The default is . + /// Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved + /// or not when is enabled. + /// If trailing spaces at the end of wrapped lines will be removed when + /// is formatted for display. The default is . /// public virtual bool PreserveTrailingSpaces { get => TextFormatter.PreserveTrailingSpaces; @@ -2905,7 +2921,7 @@ namespace Terminal.Gui { != TextFormatter.IsHorizontalDirection (newDirection); TextFormatter.Direction = newDirection; - var isValidOldAutoSize = autoSize && IsValidAutoSize (out var _); + var isValidOldAutoSize = AutoSize && IsValidAutoSize (out var _); UpdateTextFormatterText (); @@ -2941,7 +2957,7 @@ namespace Terminal.Gui { /// public bool IsAdded { get; private set; } - bool oldEnabled; + bool _oldEnabled; /// public override bool Enabled { @@ -2961,14 +2977,14 @@ namespace Terminal.Gui { OnEnabledChanged (); SetNeedsDisplay (); - if (subviews != null) { - foreach (var view in subviews) { + if (_subviews != null) { + foreach (var view in _subviews) { if (!value) { - view.oldEnabled = view.Enabled; + view._oldEnabled = view.Enabled; view.Enabled = false; } else { - view.Enabled = view.oldEnabled; - view.addingView = false; + view.Enabled = view._oldEnabled; + view._addingView = false; } } } @@ -3001,32 +3017,42 @@ namespace Terminal.Gui { } } - // TODO: v2 Nuke teh Border property (rename BorderFrame to Border) - Border border; - - /// - public virtual Border Border { - get => border; + /// + /// Gets or sets whether the view has a one row/col thick border. + /// + /// + /// + /// This is a helper for manipulating the view's . Setting this property to any value other than + /// is equivalent to setting 's + /// to `1` and to the value. + /// + /// + /// Setting this property to is equivalent to setting 's + /// to `0` and to . + /// + /// + /// For more advanced customization of the view's border, manipulate see directly. + /// + /// + public LineStyle BorderStyle { + get { + return BorderFrame?.BorderStyle ?? LineStyle.None; + } set { - if (border != value) { - border = value; - - SetNeedsDisplay (); - - if (border != null) { - Border_BorderChanged (border); - border.BorderChanged += Border_BorderChanged; - } - + if (BorderFrame == null) { + throw new InvalidOperationException ("BorderFrame is null; this is likely a bug."); } + if (value != LineStyle.None) { + BorderFrame.Thickness = new Thickness (1); + } else { + BorderFrame.Thickness = new Thickness (0); + } + BorderFrame.BorderStyle = value; + LayoutFrames (); + SetNeedsLayout (); } } - // TODO: v2 nuke This - /// - /// - public virtual bool IgnoreBorderPropertyOnRedraw { get; set; } - /// /// Pretty prints the View /// @@ -3041,8 +3067,8 @@ namespace Terminal.Gui { if (TextFormatter == null) { return; // throw new InvalidOperationException ("Can't set HotKey unless a TextFormatter has been created"); } - TextFormatter.FindHotKey (text, HotKeySpecifier, true, out _, out var hk); - if (hotKey != hk) { + TextFormatter.FindHotKey (_text, HotKeySpecifier, true, out _, out var hk); + if (_hotKey != hk) { HotKey = hk; } } @@ -3080,11 +3106,11 @@ namespace Terminal.Gui { var canSizeH = TrySetHeight (nBounds.Height - GetHotKeySpecifierLength (false), out var rH); if (canSizeW) { aSize = true; - width = rW; + _width = rW; } if (canSizeH) { aSize = true; - height = rH; + _height = rH; } if (aSize) { Bounds = new Rect (Bounds.X, Bounds.Y, canSizeW ? rW : Bounds.Width, canSizeH ? rH : Bounds.Height); @@ -3094,31 +3120,31 @@ namespace Terminal.Gui { } /// - /// Gets the dimensions required to fit using the text specified by the + /// Gets the Frame dimensions required to fit using the text specified by the /// property and accounting for any characters. - /// . /// /// The required to fit the text. public Size GetAutoSize () { var rect = TextFormatter.CalcRect (Bounds.X, Bounds.Y, TextFormatter.Text, TextFormatter.Direction); - return new Size (rect.Size.Width - GetHotKeySpecifierLength (), - rect.Size.Height - GetHotKeySpecifierLength (false)); + var newWidth = rect.Size.Width - GetHotKeySpecifierLength () + Margin.Thickness.Horizontal + BorderFrame.Thickness.Horizontal + Padding.Thickness.Horizontal; + var newHeight = rect.Size.Height - GetHotKeySpecifierLength (false) + Margin.Thickness.Vertical + BorderFrame.Thickness.Vertical + Padding.Thickness.Vertical; + return new Size (newWidth, newHeight); } bool IsValidAutoSize (out Size autoSize) { - var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection); + var rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection); autoSize = new Size (rect.Size.Width - GetHotKeySpecifierLength (), rect.Size.Height - GetHotKeySpecifierLength (false)); return !(ForceValidatePosDim && (!(Width is Dim.DimAbsolute) || !(Height is Dim.DimAbsolute)) - || frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength () - || frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false)); + || _frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength () + || _frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false)); } bool IsValidAutoSizeWidth (Dim width) { - var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection); + var rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection); var dimValue = width.Anchor (0); return !(ForceValidatePosDim && (!(width is Dim.DimAbsolute)) || dimValue != rect.Size.Width - GetHotKeySpecifierLength ()); @@ -3126,7 +3152,7 @@ namespace Terminal.Gui { bool IsValidAutoSizeHeight (Dim height) { - var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection); + var rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection); var dimValue = height.Anchor (0); return !(ForceValidatePosDim && (!(height is Dim.DimAbsolute)) || dimValue != rect.Size.Height - GetHotKeySpecifierLength (false)); @@ -3180,8 +3206,8 @@ namespace Terminal.Gui { // BUGBUG: This IGNORES what Text is set to, using on only the current View size. This doesn't seem to make sense. // BUGBUG: This uses Frame; in v2 it should be Bounds - return new Size (frame.Size.Width + GetHotKeySpecifierLength (), - frame.Size.Height + GetHotKeySpecifierLength (false)); + return new Size (_frame.Size.Width + GetHotKeySpecifierLength (), + _frame.Size.Height + GetHotKeySpecifierLength (false)); } /// @@ -3278,7 +3304,6 @@ namespace Terminal.Gui { Margin?.Dispose (); Margin = null; BorderFrame?.Dispose (); - Border = null; Padding?.Dispose (); Padding = null; @@ -3312,8 +3337,8 @@ namespace Terminal.Gui { public virtual void BeginInit () { if (!IsInitialized) { - oldCanFocus = CanFocus; - oldTabIndex = tabIndex; + _oldCanFocus = CanFocus; + _oldTabIndex = _tabIndex; UpdateTextDirection (TextDirection); UpdateTextFormatterText (); @@ -3329,8 +3354,8 @@ namespace Terminal.Gui { } - if (subviews?.Count > 0) { - foreach (var view in subviews) { + if (_subviews?.Count > 0) { + foreach (var view in _subviews) { if (!view.IsInitialized) { view.BeginInit (); } @@ -3344,8 +3369,8 @@ namespace Terminal.Gui { public void EndInit () { IsInitialized = true; - if (subviews != null) { - foreach (var view in subviews) { + if (_subviews != null) { + foreach (var view in _subviews) { if (!view.IsInitialized) { view.EndInit (); } diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index ff615ce56..f2b62afbd 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -163,7 +163,14 @@ namespace Terminal.Gui { } } + /// + /// + /// public bool NoDecorations {get;set;} + + /// + /// + /// public bool NoPadding {get;set;} /// diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index 8b7203c6b..df882f608 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -32,114 +32,93 @@ namespace Terminal.Gui { [SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))] public static ButtonAlignments DefaultButtonAlignment { get; set; } = ButtonAlignments.Center; + // TODO: Reenable once border/borderframe design is settled /// /// Defines the default border styling for . Can be configured via . /// - [SerializableConfigurationProperty (Scope = typeof (ThemeScope))] - public static Border DefaultBorder { get; set; } = new Border () { - BorderStyle = BorderStyle.Single, - }; + //[SerializableConfigurationProperty (Scope = typeof (ThemeScope))] + //public static Border DefaultBorder { get; set; } = new Border () { + // LineStyle = LineStyle.Single, + //}; internal List - public partial class TileView : View { + public class TileView : View { TileView parentTileView; /// @@ -23,7 +23,7 @@ namespace Terminal.Gui { /// new instances use /// or . /// - public partial class Tile { + public class Tile { /// /// The that is contained in this . /// Add new child views to this member for multiple @@ -43,7 +43,7 @@ namespace Terminal.Gui { /// /// /// Title are not rendered for root level tiles - /// is . + /// is . /// public string Title { get => _title; @@ -373,12 +373,12 @@ namespace Terminal.Gui { } /// - /// BUGBUG: v2 Temporary for now + /// The line style to use when drawing the splitter lines. /// - public BorderStyle BorderStyle { get; set; } = BorderStyle.None; + public LineStyle LineStyle { get; set; } = LineStyle.None; /// - /// Overriden so no Frames get drawn (BUGBUG: v2 fix this hack) + /// Overridden so no Frames get drawn (BUGBUG: v2 fix this hack) /// /// /// @@ -403,11 +403,11 @@ namespace Terminal.Gui { if (IsRootTileView ()) { if (HasBorder ()) { - lc.AddLine (new Point (0, 0), bounds.Width - 1, Orientation.Horizontal, BorderStyle); - lc.AddLine (new Point (0, 0), bounds.Height - 1, Orientation.Vertical, BorderStyle); + lc.AddLine (new Point (0, 0), bounds.Width - 1, Orientation.Horizontal, LineStyle); + lc.AddLine (new Point (0, 0), bounds.Height - 1, Orientation.Vertical, LineStyle); - lc.AddLine (new Point (bounds.Width - 1, bounds.Height - 1), -bounds.Width + 1, Orientation.Horizontal, BorderStyle); - lc.AddLine (new Point (bounds.Width - 1, bounds.Height - 1), -bounds.Height + 1, Orientation.Vertical, BorderStyle); + lc.AddLine (new Point (bounds.Width - 1, bounds.Height - 1), -bounds.Width + 1, Orientation.Horizontal, LineStyle); + lc.AddLine (new Point (bounds.Width - 1, bounds.Height - 1), -bounds.Height + 1, Orientation.Vertical, LineStyle); } foreach (var line in allLines) { @@ -428,7 +428,7 @@ namespace Terminal.Gui { length += 2; } - lc.AddLine (origin, length, line.Orientation, BorderStyle); + lc.AddLine (origin, length, line.Orientation, LineStyle); } } @@ -1070,7 +1070,7 @@ namespace Terminal.Gui { private bool HasBorder () { - return BorderStyle != BorderStyle.None; + return LineStyle != LineStyle.None; } /// diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index 8be5055ee..e5c92f317 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -615,78 +615,88 @@ namespace Terminal.Gui { } /// - /// Ensures the new position of the is within the bounds of the screen (e.g. for dragging a Window). + /// Gets a new location of the that is within the Bounds of the 's + /// (e.g. for dragging a Window). /// The `out` parameters are the new X and Y coordinates. /// + /// + /// If does not have a or it's SuperView is not + /// the position will be bound by the and . + /// /// The Toplevel that is to be moved. - /// The target x location. - /// The target y location. - /// The x location after ensuring will remain visible. - /// The y location after ensuring will remain visible. - /// The new top most menuBar - /// The new top most statusBar - /// The that is Application.Top - internal View EnsureVisibleBounds (Toplevel top, int x, int y, - out int nx, out int ny, out MenuBar mb, out StatusBar sb) + /// The target x location. + /// The target y location. + /// The x location that will ensure will be visible. + /// The y location that will ensure will be visible. + /// The new top most menuBar + /// The new top most statusBar + /// + /// Either (if does not have a Super View) or + /// 's SuperView. This can be used to ensure LayoutSubviews is called on the correct View. + /// + internal View GetLocationThatFits (Toplevel top, int targetX, int targetY, + out int nx, out int ny, out MenuBar menuBar, out StatusBar statusBar) { - int l; + int maxWidth; View superView; if (top?.SuperView == null || top == Application.Top || top?.SuperView == Application.Top) { - l = Driver.Cols; + maxWidth = Driver.Cols; superView = Application.Top; } else { - l = top.SuperView.Frame.Width; + // Use the SuperView's Bounds, not Frame + maxWidth = top.SuperView.Bounds.Width; superView = top.SuperView; } + // BUGBUG: v2 hack for now var mfLength = top.BorderFrame.Thickness.Top > 0 ? 2 : 1; - if (top.Frame.Width <= l) { - nx = Math.Max (x, 0); - nx = nx + top.Frame.Width > l ? Math.Max (l - top.Frame.Width, 0) : nx; + if (top.Frame.Width <= maxWidth) { + nx = Math.Max (targetX, 0); + nx = nx + top.Frame.Width > maxWidth ? Math.Max (maxWidth - top.Frame.Width, 0) : nx; if (nx + mfLength > top.Frame.X + top.Frame.Width) { nx = Math.Max (top.Frame.Right - mfLength, 0); } } else { - nx = x; + nx = targetX; } //System.Diagnostics.Debug.WriteLine ($"nx:{nx}, rWidth:{rWidth}"); - bool m, s; + bool menuVisible, statusVisible; if (top?.SuperView == null || top == Application.Top || top?.SuperView == Application.Top) { - m = Application.Top.MenuBar?.Visible == true; - mb = Application.Top.MenuBar; + menuVisible = Application.Top.MenuBar?.Visible == true; + menuBar = Application.Top.MenuBar; } else { var t = top.SuperView; while (t is not Toplevel) { t = t.SuperView; } - m = ((Toplevel)t).MenuBar?.Visible == true; - mb = ((Toplevel)t).MenuBar; + menuVisible = ((Toplevel)t).MenuBar?.Visible == true; + menuBar = ((Toplevel)t).MenuBar; } if (top?.SuperView == null || top == Application.Top || top?.SuperView == Application.Top) { - l = m ? 1 : 0; + maxWidth = menuVisible ? 1 : 0; } else { - l = 0; + maxWidth = 0; } - ny = Math.Max (y, l); + ny = Math.Max (targetY, maxWidth); if (top?.SuperView == null || top == Application.Top || top?.SuperView == Application.Top) { - s = Application.Top.StatusBar?.Visible == true; - sb = Application.Top.StatusBar; + statusVisible = Application.Top.StatusBar?.Visible == true; + statusBar = Application.Top.StatusBar; } else { var t = top.SuperView; while (t is not Toplevel) { t = t.SuperView; } - s = ((Toplevel)t).StatusBar?.Visible == true; - sb = ((Toplevel)t).StatusBar; + statusVisible = ((Toplevel)t).StatusBar?.Visible == true; + statusBar = ((Toplevel)t).StatusBar; } if (top?.SuperView == null || top == Application.Top || top?.SuperView == Application.Top) { - l = s ? Driver.Rows - 1 : Driver.Rows; + maxWidth = statusVisible ? Driver.Rows - 1 : Driver.Rows; } else { - l = s ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height; + maxWidth = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height; } - ny = Math.Min (ny, l); - if (top.Frame.Height <= l) { - ny = ny + top.Frame.Height >= l ? Math.Max (l - top.Frame.Height, m ? 1 : 0) : ny; + ny = Math.Min (ny, maxWidth); + if (top.Frame.Height <= maxWidth) { + ny = ny + top.Frame.Height >= maxWidth ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0) : ny; if (ny + mfLength > top.Frame.Y + top.Frame.Height) { ny = Math.Max (top.Frame.Bottom - mfLength, 0); } @@ -714,7 +724,7 @@ namespace Terminal.Gui { /// The Toplevel to adjust. public virtual void PositionToplevel (Toplevel top) { - var superView = EnsureVisibleBounds (top, top.Frame.X, top.Frame.Y, + var superView = GetLocationThatFits (top, top.Frame.X, top.Frame.Y, out int nx, out int ny, out _, out StatusBar sb); bool layoutSubviews = false; if ((superView != top || top?.SuperView != null || (top != Application.Top && top.Modal) @@ -739,53 +749,47 @@ namespace Terminal.Gui { layoutSubviews = true; } - if (layoutSubviews) { + if (superView.LayoutNeeded || layoutSubviews) { superView.LayoutSubviews (); } + if (LayoutNeeded) { + LayoutSubviews (); + } } /// - //public override void Redraw (Rect bounds) - //{ - // if (!Visible) { - // return; - // } + public override void Redraw (Rect bounds) + { + if (!Visible) { + return; + } - // if (!_needsDisplay.IsEmpty || _childNeedsDisplay || LayoutNeeded) { - // Driver.SetAttribute (GetNormalColor ()); + if (!_needsDisplay.IsEmpty || _childNeedsDisplay || LayoutNeeded) { + Driver.SetAttribute (Enabled ? Colors.Base.Normal : Colors.Base.Disabled); + LayoutSubviews (); + PositionToplevels (); - // // This is the Application.Top. Clear just the region we're being asked to redraw - // // (the bounds passed to us). - // Clear (); - // Driver.SetAttribute (Enabled ? Colors.Base.Normal : Colors.Base.Disabled); + if (this == Application.MdiTop) { + foreach (var top in Application.MdiChildes.AsEnumerable ().Reverse ()) { + if (top.Frame.IntersectsWith (bounds)) { + if (top != this && !top.IsCurrentTop && !OutsideTopFrame (top) && top.Visible) { + top.SetNeedsLayout (); + top.SetNeedsDisplay (top.Bounds); + top.Redraw (top.Bounds); + } + } + } + } - // LayoutSubviews (); - // PositionToplevels (); - - // if (this == Application.MdiTop) { - // foreach (var top in Application.MdiChildes.AsEnumerable ().Reverse ()) { - // if (top.Frame.IntersectsWith (bounds)) { - // if (top != this && !top.IsCurrentTop && !OutsideTopFrame (top) && top.Visible) { - // top.SetNeedsLayout (); - // top.SetNeedsDisplay (top.Bounds); - // top.Redraw (top.Bounds); - // } - // } - // } - // } - - // foreach (var view in Subviews) { - // if (view.Frame.IntersectsWith (bounds) && !OutsideTopFrame (this)) { - // view.SetNeedsLayout (); - // view.SetNeedsDisplay (view.Bounds); - // } - // } - - // // BUGBUG: shouldn't we just return here? the call to base.Redraw below is redundant - // } - - // base.Redraw (Bounds); - //} + foreach (var view in Subviews) { + if (view.Frame.IntersectsWith (bounds) && !OutsideTopFrame (this)) { + view.SetNeedsLayout (); + view.SetNeedsDisplay (view.Bounds); + } + } + } + base.Redraw (Bounds); + } bool OutsideTopFrame (Toplevel top) { @@ -840,7 +844,7 @@ namespace Terminal.Gui { } else { SuperView.SetNeedsDisplay (); } - EnsureVisibleBounds (this, mouseEvent.X + (SuperView == null ? mouseEvent.OfX - start.X : Frame.X - start.X), + GetLocationThatFits (this, mouseEvent.X + (SuperView == null ? mouseEvent.OfX - start.X : Frame.X - start.X), mouseEvent.Y + (SuperView == null ? mouseEvent.OfY - start.Y : Frame.Y - start.Y), out nx, out ny, out _, out _); diff --git a/Terminal.Gui/Views/Window.cs b/Terminal.Gui/Views/Window.cs index b0ac74b57..0643122c3 100644 --- a/Terminal.Gui/Views/Window.cs +++ b/Terminal.Gui/Views/Window.cs @@ -8,124 +8,56 @@ using static Terminal.Gui.ConfigurationManager; namespace Terminal.Gui { /// - /// A that draws a border around its with a Title at the top. + /// A with set to . /// /// - /// The 'client area' of a is a rectangle deflated by one or more rows/columns from . A this time there is no - /// API to determine this rectangle. + /// + /// This is a helper class to simplify creating a with a border. + /// /// public class Window : Toplevel { /// - /// Initializes a new instance of the class with an optional title using positioning. + /// Initializes a new instance of the class using positioning. /// - /// Superview-relative rectangle specifying the location and size - /// Title - /// - /// This constructor initializes a Window with a of . Use constructors - /// that do not take Rect parameters to initialize a Window with . - /// - public Window (Rect frame, ustring title = null) : this (frame, title, padding: 0, border: null) - { - } - - /// - /// Initializes a new instance of the class with an optional title using positioning. - /// - /// Title. - /// - /// This constructor initializes a View with a of . - /// Use , , , and properties to dynamically control the size and location of the view. - /// - public Window (ustring title = null) : this (title, padding: 0, border: null) - { + public Window () : base () { + SetInitialProperties (); } /// /// Initializes a new instance of the class using positioning. /// - public Window () : this (title: null) { } - - /// - /// Initializes a new instance of the using positioning with the specified frame for its location, with the specified frame padding, - /// and an optional title. - /// - /// Superview-relative rectangle specifying the location and size - /// Title - /// Number of characters to use for padding of the drawn frame. - /// The . - /// - /// This constructor initializes a Window with a of . Use constructors - /// that do not take Rect parameters to initialize a Window with of - /// - public Window (Rect frame, ustring title = null, int padding = 0, Border border = null) : base (frame) + public Window (Rect frame) : base (frame) { - SetInitialProperties (title, frame, padding, border); + SetInitialProperties (); } - /// - /// Initializes a new instance of the using positioning, - /// and an optional title. - /// - /// Title. - /// Number of characters to use for padding of the drawn frame. - /// The . - /// - /// This constructor initializes a View with a of . - /// Use , , , and properties to dynamically control the size and location of the view. - /// - public Window (ustring title = null, int padding = 0, Border border = null) : base () - { - SetInitialProperties (title, Rect.Empty, padding, border); - } + // TODO: enable this + ///// + ///// The default for 's border. The default is . + ///// + ///// + ///// This property can be set in a Theme to change the default for all s. + ///// + /////[SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))] + ////public static ColorScheme DefaultColorScheme { get; set; } = Colors.Base; /// - /// The default for . The default is . + /// The default for 's border. The default is . /// /// - /// This property can be set in a Theme to change the default for all s. + /// This property can be set in a Theme to change the default for all s. /// - ///[SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))] - public static BorderStyle DefaultBorderStyle { get; set; } = BorderStyle.Single; + [SerializableConfigurationProperty (Scope = typeof (ThemeScope)), JsonConverter (typeof (JsonStringEnumConverter))] + public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single; - void SetInitialProperties (ustring title, Rect frame, int padding = 0, Border border = null) + void SetInitialProperties () { CanFocus = true; - ColorScheme = Colors.Base; - if (title == null) title = ustring.Empty; - Title = title; - - if (border == null) { - // TODO: v2 this is a hack until Border gets refactored - Border = new Border () { - BorderStyle = DefaultBorderStyle, - PaddingThickness = new Thickness (padding), - }; - } else { - Border = border; - } - BorderFrame.Thickness = new Thickness (1); - BorderFrame.BorderStyle = Border.BorderStyle; - //BorderFrame.ColorScheme = ColorScheme; - BorderFrame.Data = "BorderFrame"; - - // TODO: Hack until Border is refactored - Padding.Thickness = Border.PaddingThickness ?? Padding.Thickness; - - if (frame.IsEmpty) { - // Make it bigger to fit the margin, border, & padding - frame = new Rect (frame.Location, new Size (Margin.Thickness.Horizontal + BorderFrame.Thickness.Horizontal + Padding.Thickness.Horizontal + 1, Margin.Thickness.Vertical + BorderFrame.Thickness.Vertical + Padding.Thickness.Vertical + 1)); - } + ColorScheme = Colors.Base; // TODO: make this a theme property + BorderStyle = DefaultBorderStyle; } - ///// - ///// Enumerates the various s in the embedded . - ///// - ///// The enumerator. - //public new IEnumerator GetEnumerator () - //{ - // return contentView.GetEnumerator (); - //} - + // TODO: Are these overrides really needed? /// public override void Add (View view) { diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index dab47327e..6c76db666 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -134,7 +134,7 @@ namespace Terminal.Gui { public WizardStep (ustring title) { this.Title = title; // this.Title holds just the "Wizard Title"; base.Title holds "Wizard Title - Step Title" - this.Border.BorderStyle = BorderStyle.Rounded; + this.BorderStyle = LineStyle.Rounded; base.Add (contentView); helpTextView.ReadOnly = true; @@ -274,26 +274,12 @@ namespace Terminal.Gui { /// The Wizard will be vertically and horizontally centered in the container. /// After initialization use X, Y, Width, and Height change size and position. /// - public Wizard () : this (ustring.Empty) - { - } + public Wizard () : base () { - /// - /// Initializes a new instance of the class using positioning. - /// - /// Sets the for the Wizard. - /// - /// The Wizard will be vertically and horizontally centered in the container. - /// After initialization use X, Y, Width, and Height change size and position. - /// - public Wizard (ustring title) : base (title) - { - wizardTitle = title; // Using Justify causes the Back and Next buttons to be hard justified against // the left and right edge ButtonAlignment = ButtonAlignments.Justify; - this.Border.BorderStyle = BorderStyle.Double; - this.Border.PaddingThickness = new Thickness (0); + BorderStyle = LineStyle.Double; //// Add a horiz separator //var separator = new LineView (Graphs.Orientation.Horizontal) { @@ -736,9 +722,7 @@ namespace Terminal.Gui { } if (base.Modal) { ColorScheme = Colors.Dialog; - Border.BorderStyle = BorderStyle.Rounded; -// Border.Effect3D = true; -// Border.DrawMarginFrame = true; + BorderStyle = LineStyle.Rounded; } else { if (SuperView != null) { ColorScheme = SuperView.ColorScheme; @@ -746,9 +730,7 @@ namespace Terminal.Gui { ColorScheme = Colors.Base; } CanFocus = true; -// Border.Effect3D = false; - Border.BorderStyle = BorderStyle.None; -// Border.DrawMarginFrame = false; + BorderStyle = LineStyle.None; } } } diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index 278f9981a..d299b67ee 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -122,9 +122,12 @@ namespace UICatalog { } } - public KeyBindingsDialog () : base("Keybindings", 50,10) + public KeyBindingsDialog () : base() { - if(ViewTracker.Instance == null) { + Title = "Keybindings"; + Height = 50; + Width = 10; + if (ViewTracker.Instance == null) { ViewTracker.Initialize (); } @@ -178,7 +181,7 @@ namespace UICatalog { Key? key = null; // prompt user to hit a key - var dlg = new Dialog ("Enter Key"); + var dlg = new Dialog () { Title = "Enter Key" }; dlg.KeyPress += (s, k) => { key = k.KeyEvent.Key; Application.RequestStop (); diff --git a/UICatalog/Scenario.cs b/UICatalog/Scenario.cs index d52c45ac3..3b3c40b66 100644 --- a/UICatalog/Scenario.cs +++ b/UICatalog/Scenario.cs @@ -78,7 +78,8 @@ namespace UICatalog { ConfigurationManager.Themes.Theme = Theme; ConfigurationManager.Apply (); - Win = new Window ($"{Application.QuitKey} to Quit - Scenario: {GetName ()}") { + Win = new Window () { + Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", X = 0, Y = 0, Width = Dim.Fill (), diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index febe96012..7ead40e18 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -91,7 +91,14 @@ namespace UICatalog.Scenarios { _settingsPane.SetFocus (); }; _classListView.SelectedItemChanged += (s,args) => { - ClearClass (_curView); + // Remove existing class, if any + if (_curView != null) { + _curView.LayoutComplete -= LayoutCompleteHandler; + _hostPane.Remove (_curView); + _curView.Dispose (); + _curView = null; + _hostPane.Clear (); + } _curView = CreateClass (_viewClasses.Values.ToArray () [_classListView.SelectedItem]); }; _leftPane.Add (_classListView); @@ -347,19 +354,10 @@ namespace UICatalog.Scenarios { .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsPublic && myType.IsSubclassOf (typeof (View)))) { types.Add (type); } + types.Add (typeof (View)); return types; } - - void ClearClass (View view) - { - // Remove existing class, if any - if (view != null) { - view.LayoutComplete -= LayoutCompleteHandler; - _hostPane.Remove (view); - view.Dispose (); - _hostPane.Clear (); - } - } + View CreateClass (Type type) { diff --git a/UICatalog/Scenarios/BackgroundWorkerCollection.cs b/UICatalog/Scenarios/BackgroundWorkerCollection.cs index 4e6f0862f..be7666b92 100644 --- a/UICatalog/Scenarios/BackgroundWorkerCollection.cs +++ b/UICatalog/Scenarios/BackgroundWorkerCollection.cs @@ -345,14 +345,14 @@ namespace UICatalog.Scenarios { }; LayoutStarted += (s,e) => { - var btnsWidth = start.Bounds.Width + close.Bounds.Width + 2 - 1; + var btnsWidth = start.Frame.Width + close.Frame.Width + 2 - 1; var shiftLeft = Math.Max ((Bounds.Width - btnsWidth) / 2 - 2, 0); - shiftLeft += close.Bounds.Width + 1; + shiftLeft += close.Frame.Width + 1; close.X = Pos.AnchorEnd (shiftLeft); close.Y = Pos.AnchorEnd (1); - shiftLeft += start.Bounds.Width + 1; + shiftLeft += start.Frame.Width + 1; start.X = Pos.AnchorEnd (shiftLeft); start.Y = Pos.AnchorEnd (1); }; diff --git a/UICatalog/Scenarios/BordersComparisons.cs b/UICatalog/Scenarios/BordersComparisons.cs index ba1dc86ed..8c319a2a1 100644 --- a/UICatalog/Scenarios/BordersComparisons.cs +++ b/UICatalog/Scenarios/BordersComparisons.cs @@ -9,18 +9,13 @@ namespace UICatalog.Scenarios { { Application.Init (); - var borderStyle = BorderStyle.Double; + var borderStyle = LineStyle.Double; var borderThickness = new Thickness (1, 2, 3, 4); var padding = 1; Application.Top.Text = $"Border Thickness: {borderThickness}\nPadding: {padding}"; - var win = new Window (new Rect (5, 5, 40, 20), "Window", - padding: padding, - border: new Border () { - BorderStyle = borderStyle, - BorderThickness = borderThickness - }); + var win = new Window (new Rect (5, 5, 40, 20)) { Title = "Window" }; var tf1 = new TextField ("1234567890") { Width = 10 }; @@ -77,14 +72,9 @@ namespace UICatalog.Scenarios { topLevel.Add (tf3, button2, label2, tv2, tf4); Application.Top.Add (topLevel); - var frameView = new FrameView (new Rect (95, 5, 40, 20), "FrameView", null, - border: new Border () { - BorderStyle = borderStyle, - BorderThickness = borderThickness - } - ); - //frameView.BorderFrame.Thickness = borderThickness; - //frameView.BorderFrame.BorderStyle = borderStyle; + var frameView = new FrameView (new Rect (95, 5, 40, 20), "FrameView", null); + frameView.BorderFrame.Thickness = borderThickness; + frameView.BorderFrame.BorderStyle = borderStyle; //frameView.Padding.Thickness = paddingThickness; var tf5 = new TextField ("1234567890") { Width = 10 }; diff --git a/UICatalog/Scenarios/BordersOnContainers.cs b/UICatalog/Scenarios/BordersOnContainers.cs index 02a3e993c..e375c6526 100644 --- a/UICatalog/Scenarios/BordersOnContainers.cs +++ b/UICatalog/Scenarios/BordersOnContainers.cs @@ -7,28 +7,18 @@ namespace UICatalog.Scenarios { public class BordersOnContainers : Window { public BordersOnContainers (NStack.ustring title, string typeName, View smartView) { - var borderStyle = BorderStyle.Double; - var drawMarginFrame = false; + var borderStyle = LineStyle.Double; var borderThickness = new Thickness (1, 2, 3, 4); var borderBrush = Colors.Base.HotFocus.Foreground; var padding = new Thickness (1, 2, 3, 4); var background = Colors.Base.HotNormal.Foreground; - var effect3D = true; smartView.X = Pos.Center (); smartView.Y = 0; smartView.Width = 40; smartView.Height = 20; - smartView.Border = new Border () { - BorderStyle = borderStyle, - DrawMarginFrame = drawMarginFrame, - BorderThickness = borderThickness, - ForgroundColor = borderBrush, - PaddingThickness = padding, - BackgroundColor = background, - Effect3D = effect3D, - //Title = typeName - }; + smartView.BorderStyle = borderStyle; + smartView.ColorScheme = Colors.TopLevel; var tf1 = new TextField ("1234567890") { Width = 10 }; @@ -66,16 +56,16 @@ namespace UICatalog.Scenarios { }; paddingTopEdit.TextChanging += (s, e) => { try { - smartView.Border.PaddingThickness = new Thickness (smartView.Border.PaddingThickness.Left, - int.Parse (e.NewText.ToString ()), smartView.Border.PaddingThickness.Right, - smartView.Border.PaddingThickness.Bottom); + smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Left, + int.Parse (e.NewText.ToString ()), smartView.Padding.Thickness.Right, + smartView.Padding.Thickness.Bottom); } catch { if (!e.NewText.IsEmpty) { e.Cancel = true; } } }; - paddingTopEdit.Text = $"{smartView.Border.PaddingThickness.Top}"; + paddingTopEdit.Text = $"{smartView.Padding.Thickness.Top}"; Add (paddingTopEdit); @@ -86,16 +76,16 @@ namespace UICatalog.Scenarios { }; paddingLeftEdit.TextChanging += (s, e) => { try { - smartView.Border.PaddingThickness = new Thickness (int.Parse (e.NewText.ToString ()), - smartView.Border.PaddingThickness.Top, smartView.Border.PaddingThickness.Right, - smartView.Border.PaddingThickness.Bottom); + smartView.Padding.Thickness = new Thickness (int.Parse (e.NewText.ToString ()), + smartView.Padding.Thickness.Top, smartView.Padding.Thickness.Right, + smartView.Padding.Thickness.Bottom); } catch { if (!e.NewText.IsEmpty) { e.Cancel = true; } } }; - paddingLeftEdit.Text = $"{smartView.Border.PaddingThickness.Left}"; + paddingLeftEdit.Text = $"{smartView.Padding.Thickness.Left}"; Add (paddingLeftEdit); var paddingRightEdit = new TextField ("") { @@ -105,16 +95,16 @@ namespace UICatalog.Scenarios { }; paddingRightEdit.TextChanging += (s, e) => { try { - smartView.Border.PaddingThickness = new Thickness (smartView.Border.PaddingThickness.Left, - smartView.Border.PaddingThickness.Top, int.Parse (e.NewText.ToString ()), - smartView.Border.PaddingThickness.Bottom); + smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Left, + smartView.Padding.Thickness.Top, int.Parse (e.NewText.ToString ()), + smartView.Padding.Thickness.Bottom); } catch { if (!e.NewText.IsEmpty) { e.Cancel = true; } } }; - paddingRightEdit.Text = $"{smartView.Border.PaddingThickness.Right}"; + paddingRightEdit.Text = $"{smartView.Padding.Thickness.Right}"; Add (paddingRightEdit); var paddingBottomEdit = new TextField ("") { @@ -124,8 +114,8 @@ namespace UICatalog.Scenarios { }; paddingBottomEdit.TextChanging += (s, e) => { try { - smartView.Border.PaddingThickness = new Thickness (smartView.Border.PaddingThickness.Left, - smartView.Border.PaddingThickness.Top, smartView.Border.PaddingThickness.Right, + smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Left, + smartView.Padding.Thickness.Top, smartView.Padding.Thickness.Right, int.Parse (e.NewText.ToString ())); } catch { if (!e.NewText.IsEmpty) { @@ -133,7 +123,7 @@ namespace UICatalog.Scenarios { } } }; - paddingBottomEdit.Text = $"{smartView.Border.PaddingThickness.Bottom}"; + paddingBottomEdit.Text = $"{smartView.Padding.Thickness.Bottom}"; Add (paddingBottomEdit); var replacePadding = new Button ("Replace all based on top") { @@ -141,7 +131,7 @@ namespace UICatalog.Scenarios { Y = 5 }; replacePadding.Clicked += (s, e) => { - smartView.Border.PaddingThickness = new Thickness (smartView.Border.PaddingThickness.Top); + smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Top); if (paddingTopEdit.Text.IsEmpty) { paddingTopEdit.Text = "0"; } @@ -160,16 +150,16 @@ namespace UICatalog.Scenarios { }; borderTopEdit.TextChanging += (s, e) => { try { - smartView.Border.BorderThickness = new Thickness (smartView.Border.BorderThickness.Left, - int.Parse (e.NewText.ToString ()), smartView.Border.BorderThickness.Right, - smartView.Border.BorderThickness.Bottom); + smartView.BorderFrame.Thickness = new Thickness (smartView.BorderFrame.Thickness.Left, + int.Parse (e.NewText.ToString ()), smartView.BorderFrame.Thickness.Right, + smartView.BorderFrame.Thickness.Bottom); } catch { if (!e.NewText.IsEmpty) { e.Cancel = true; } } }; - borderTopEdit.Text = $"{smartView.Border.BorderThickness.Top}"; + borderTopEdit.Text = $"{smartView.BorderFrame.Thickness.Top}"; Add (borderTopEdit); @@ -180,16 +170,16 @@ namespace UICatalog.Scenarios { }; borderLeftEdit.TextChanging += (s, e) => { try { - smartView.Border.BorderThickness = new Thickness (int.Parse (e.NewText.ToString ()), - smartView.Border.BorderThickness.Top, smartView.Border.BorderThickness.Right, - smartView.Border.BorderThickness.Bottom); + smartView.BorderFrame.Thickness = new Thickness (int.Parse (e.NewText.ToString ()), + smartView.BorderFrame.Thickness.Top, smartView.BorderFrame.Thickness.Right, + smartView.BorderFrame.Thickness.Bottom); } catch { if (!e.NewText.IsEmpty) { e.Cancel = true; } } }; - borderLeftEdit.Text = $"{smartView.Border.BorderThickness.Left}"; + borderLeftEdit.Text = $"{smartView.BorderFrame.Thickness.Left}"; Add (borderLeftEdit); var borderRightEdit = new TextField ("") { @@ -199,16 +189,16 @@ namespace UICatalog.Scenarios { }; borderRightEdit.TextChanging += (s, e) => { try { - smartView.Border.BorderThickness = new Thickness (smartView.Border.BorderThickness.Left, - smartView.Border.BorderThickness.Top, int.Parse (e.NewText.ToString ()), - smartView.Border.BorderThickness.Bottom); + smartView.BorderFrame.Thickness = new Thickness (smartView.BorderFrame.Thickness.Left, + smartView.BorderFrame.Thickness.Top, int.Parse (e.NewText.ToString ()), + smartView.BorderFrame.Thickness.Bottom); } catch { if (!e.NewText.IsEmpty) { e.Cancel = true; } } }; - borderRightEdit.Text = $"{smartView.Border.BorderThickness.Right}"; + borderRightEdit.Text = $"{smartView.BorderFrame.Thickness.Right}"; Add (borderRightEdit); var borderBottomEdit = new TextField ("") { @@ -218,8 +208,8 @@ namespace UICatalog.Scenarios { }; borderBottomEdit.TextChanging += (s, e) => { try { - smartView.Border.BorderThickness = new Thickness (smartView.Border.BorderThickness.Left, - smartView.Border.BorderThickness.Top, smartView.Border.BorderThickness.Right, + smartView.BorderFrame.Thickness = new Thickness (smartView.BorderFrame.Thickness.Left, + smartView.BorderFrame.Thickness.Top, smartView.BorderFrame.Thickness.Right, int.Parse (e.NewText.ToString ())); } catch { if (!e.NewText.IsEmpty) { @@ -227,7 +217,7 @@ namespace UICatalog.Scenarios { } } }; - borderBottomEdit.Text = $"{smartView.Border.BorderThickness.Bottom}"; + borderBottomEdit.Text = $"{smartView.BorderFrame.Thickness.Bottom}"; Add (borderBottomEdit); var replaceBorder = new Button ("Replace all based on top") { @@ -235,7 +225,7 @@ namespace UICatalog.Scenarios { Y = 5 }; replaceBorder.Clicked += (s, e) => { - smartView.Border.BorderThickness = new Thickness (smartView.Border.BorderThickness.Top); + smartView.BorderFrame.Thickness = new Thickness (smartView.BorderFrame.Thickness.Top); if (borderTopEdit.Text.IsEmpty) { borderTopEdit.Text = "0"; } @@ -247,101 +237,19 @@ namespace UICatalog.Scenarios { Add (new Label ("BorderStyle:")); - var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast ().ToList (); + var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast ().ToList (); var rbBorderStyle = new RadioGroup (borderStyleEnum.Select ( e => NStack.ustring.Make (e.ToString ())).ToArray ()) { X = 2, Y = 1, - SelectedItem = (int)smartView.Border.BorderStyle + SelectedItem = (int)smartView.BorderStyle }; Add (rbBorderStyle); - var cbDrawMarginFrame = new CheckBox ("Draw Margin Frame", smartView.Border.DrawMarginFrame) { - X = Pos.AnchorEnd (20), - Y = 0, - Width = 5 - }; - cbDrawMarginFrame.Toggled += (s, e) => { - try { - smartView.Border.DrawMarginFrame = (bool)cbDrawMarginFrame.Checked; - if (cbDrawMarginFrame.Checked != smartView.Border.DrawMarginFrame) { - cbDrawMarginFrame.Checked = smartView.Border.DrawMarginFrame; - } - } catch { } - }; - Add (cbDrawMarginFrame); - rbBorderStyle.SelectedItemChanged += (s, e) => { - smartView.Border.BorderStyle = (BorderStyle)e.SelectedItem; + smartView.BorderStyle = (LineStyle)e.SelectedItem; smartView.SetNeedsDisplay (); - if (cbDrawMarginFrame.Checked != smartView.Border.DrawMarginFrame) { - cbDrawMarginFrame.Checked = smartView.Border.DrawMarginFrame; - } - }; - - var cbEffect3D = new CheckBox ("Draw 3D effects", smartView.Border.Effect3D) { - X = Pos.AnchorEnd (20), - Y = 1, - Width = 5 - }; - Add (cbEffect3D); - - Add (new Label ("Effect3D Offset:") { - X = Pos.AnchorEnd (20), - Y = 2 - }); - Add (new Label ("X:") { - X = Pos.AnchorEnd (19), - Y = 3 - }); - - var effect3DOffsetX = new TextField ("") { - X = Pos.AnchorEnd (16), - Y = 3, - Width = 5 - }; - effect3DOffsetX.TextChanging += (s, e) => { - try { - smartView.Border.Effect3DOffset = new Point (int.Parse (e.NewText.ToString ()), - smartView.Border.Effect3DOffset.Y); - } catch { - if (!e.NewText.IsEmpty && e.NewText != CultureInfo.CurrentCulture.NumberFormat.NegativeSign) { - e.Cancel = true; - } - } - }; - effect3DOffsetX.Text = $"{smartView.Border.Effect3DOffset.X}"; - Add (effect3DOffsetX); - - Add (new Label ("Y:") { - X = Pos.AnchorEnd (10), - Y = 3 - }); - - var effect3DOffsetY = new TextField ("") { - X = Pos.AnchorEnd (7), - Y = 3, - Width = 5 - }; - effect3DOffsetY.TextChanging += (s, e) => { - try { - smartView.Border.Effect3DOffset = new Point (smartView.Border.Effect3DOffset.X, - int.Parse (e.NewText.ToString ())); - } catch { - if (!e.NewText.IsEmpty && e.NewText != CultureInfo.CurrentCulture.NumberFormat.NegativeSign) { - e.Cancel = true; - } - } - }; - effect3DOffsetY.Text = $"{smartView.Border.Effect3DOffset.Y}"; - Add (effect3DOffsetY); - - cbEffect3D.Toggled += (s, e) => { - try { - smartView.Border.Effect3D = effect3DOffsetX.Enabled = - effect3DOffsetY.Enabled = (bool)cbEffect3D.Checked; - } catch { } }; Add (new Label ("Background:") { @@ -354,10 +262,17 @@ namespace UICatalog.Scenarios { X = 2, Y = 6, - SelectedItem = (int)smartView.Border.BackgroundColor + //SelectedItem = (int)smartView.BorderFrame.BackgroundColor }; rbBackground.SelectedItemChanged += (s, e) => { - smartView.Border.BackgroundColor = (Color)e.SelectedItem; +// smartView.Border.BackgroundColor = (Color)e.SelectedItem; + smartView.BorderFrame.ColorScheme = new ColorScheme() { + Normal = new Terminal.Gui.Attribute(Color.Red, Color.White), + HotNormal = new Terminal.Gui.Attribute (Color.Magenta, Color.White), + Disabled = new Terminal.Gui.Attribute (Color.Gray, Color.White), + Focus = new Terminal.Gui.Attribute (Color.Blue, Color.White), + HotFocus = new Terminal.Gui.Attribute (Color.BrightBlue, Color.White), + }; }; Add (rbBackground); @@ -371,10 +286,10 @@ namespace UICatalog.Scenarios { X = Pos.AnchorEnd (18), Y = 6, - SelectedItem = (int)smartView.Border.ForgroundColor + //SelectedItem = (int)smartView.Border.ForgroundColor }; rbBorderBrush.SelectedItemChanged += (s, e) => { - smartView.Border.ForgroundColor = (Color)e.SelectedItem; + //smartView.Border.ForgroundColor = (Color)e.SelectedItem; }; Add (rbBorderBrush); diff --git a/UICatalog/Scenarios/Clipping.cs b/UICatalog/Scenarios/Clipping.cs index 6ed96055d..0d9d8e526 100644 --- a/UICatalog/Scenarios/Clipping.cs +++ b/UICatalog/Scenarios/Clipping.cs @@ -32,7 +32,8 @@ namespace UICatalog.Scenarios { //scrollView.ShowVerticalScrollIndicator = true; //scrollView.ShowHorizontalScrollIndicator = true; - var embedded1 = new Window ("1") { + var embedded1 = new Window () { + Title = "1", X = 3, Y = 3, Width = Dim.Fill (3), @@ -41,7 +42,8 @@ namespace UICatalog.Scenarios { Id = "1" }; - var embedded2 = new Window ("2") { + var embedded2 = new Window () { + Title = "1", X = 3, Y = 3, Width = Dim.Fill (3), @@ -51,7 +53,8 @@ namespace UICatalog.Scenarios { }; embedded1.Add (embedded2); - var embedded3 = new Window ("3") { + var embedded3 = new Window () { + Title = "3", X = 3, Y = 3, Width = Dim.Fill (3), diff --git a/UICatalog/Scenarios/ConfigurationEditor.cs b/UICatalog/Scenarios/ConfigurationEditor.cs index 758a48a3f..d04668b06 100644 --- a/UICatalog/Scenarios/ConfigurationEditor.cs +++ b/UICatalog/Scenarios/ConfigurationEditor.cs @@ -46,7 +46,7 @@ namespace UICatalog.Scenarios { Width = Dim.Fill (), Height = Dim.Fill (1), Orientation = Orientation.Vertical, - Border = new Border () { BorderStyle = BorderStyle.Single } + LineStyle = LineStyle.Single }; Application.Top.Add (_tileView); diff --git a/UICatalog/Scenarios/CsvEditor.cs b/UICatalog/Scenarios/CsvEditor.cs index 738b57515..2caab1e60 100644 --- a/UICatalog/Scenarios/CsvEditor.cs +++ b/UICatalog/Scenarios/CsvEditor.cs @@ -388,7 +388,7 @@ namespace UICatalog.Scenarios { } } - + private void Open () { var ofd = new FileDialog () { @@ -436,7 +436,7 @@ namespace UICatalog.Scenarios { // Only set the current filename if we successfully loaded the entire file currentFile = filename; - Win.Title = $"{this.GetName ()} - {Path.GetFileName(currentFile)}"; + Win.Title = $"{this.GetName ()} - {Path.GetFileName (currentFile)}"; } catch (Exception ex) { MessageBox.ErrorQuery ("Open Failed", $"Error on line {lineNumber}{Environment.NewLine}{ex.Message}", "Ok"); @@ -446,7 +446,7 @@ namespace UICatalog.Scenarios { { var _scrollBar = new ScrollBarView (tableView, true); - _scrollBar.ChangedPosition += (s,e) => { + _scrollBar.ChangedPosition += (s, e) => { tableView.RowOffset = _scrollBar.Position; if (tableView.RowOffset != _scrollBar.Position) { _scrollBar.Position = tableView.RowOffset; @@ -462,7 +462,7 @@ namespace UICatalog.Scenarios { _listView.SetNeedsDisplay (); };*/ - tableView.DrawContent += (s,e) => { + tableView.DrawContent += (s, e) => { _scrollBar.Size = tableView.Table?.Rows?.Count ?? 0; _scrollBar.Position = tableView.RowOffset; // _scrollBar.OtherScrollBarView.Size = _listView.Maxlength - 1; @@ -514,10 +514,10 @@ 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 (); }; - var d = new Dialog (title, 60, 20, ok, cancel); + cancel.Clicked += (s, e) => { Application.RequestStop (); }; + var d = new Dialog (ok, cancel) { Title = title }; var lbl = new Label () { X = 0, diff --git a/UICatalog/Scenarios/Dialogs.cs b/UICatalog/Scenarios/Dialogs.cs index 0d7124eac..85a86f153 100644 --- a/UICatalog/Scenarios/Dialogs.cs +++ b/UICatalog/Scenarios/Dialogs.cs @@ -197,10 +197,14 @@ namespace UICatalog.Scenarios { // This tests dynamically adding buttons; ensuring the dialog resizes if needed and // the buttons are laid out correctly - dialog = new Dialog (titleEdit.Text, width, height, - buttons.ToArray ()) { + dialog = new Dialog (buttons.ToArray ()) { + Title = titleEdit.Text, ButtonAlignment = (Dialog.ButtonAlignments)styleRadioGroup.SelectedItem }; + if (height != 0 || width != 0) { + dialog.Height = height; + dialog.Width = width; + } var add = new Button ("Add a button") { X = Pos.Center (), diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs index 3390d7e69..cc10009fc 100644 --- a/UICatalog/Scenarios/DynamicMenuBar.cs +++ b/UICatalog/Scenarios/DynamicMenuBar.cs @@ -16,7 +16,7 @@ namespace UICatalog.Scenarios { public override void Init () { Application.Init (); - Application.Top.Add (new DynamicMenuBarSample ($"{Application.QuitKey} to Quit - Scenario: {GetName ()}")); + Application.Top.Add (new DynamicMenuBarSample () { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}" }); } public class DynamicMenuItemList { @@ -74,7 +74,7 @@ namespace UICatalog.Scenarios { public DynamicMenuItemModel DataContext { get; set; } - public DynamicMenuBarSample (ustring title) : base (title) + public DynamicMenuBarSample () : base () { DataContext = new DynamicMenuItemModel (); @@ -881,7 +881,7 @@ namespace UICatalog.Scenarios { _txtTitle.Text = ustring.Empty; Application.RequestStop (); }; - var _dialog = new Dialog ("Please enter the menu details.", _btnOk, _btnCancel); + var _dialog = new Dialog (_btnOk, _btnCancel) { Title = "Enter the menu details." }; Width = Dim.Fill (); Height = Dim.Fill () - 1; diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs index 2d586da11..b0635966b 100644 --- a/UICatalog/Scenarios/DynamicStatusBar.cs +++ b/UICatalog/Scenarios/DynamicStatusBar.cs @@ -15,7 +15,7 @@ namespace UICatalog.Scenarios { public override void Init () { Application.Init (); - Application.Top.Add (new DynamicStatusBarSample ($"{Application.QuitKey} to Quit - Scenario: {GetName ()}")); + Application.Top.Add (new DynamicStatusBarSample () { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}" }); } public class DynamicStatusItemList { @@ -62,7 +62,7 @@ namespace UICatalog.Scenarios { public DynamicStatusItemModel DataContext { get; set; } - public DynamicStatusBarSample (ustring title) : base (title) + public DynamicStatusBarSample () : base () { DataContext = new DynamicStatusItemModel (); @@ -496,7 +496,7 @@ namespace UICatalog.Scenarios { _txtTitle.Text = ustring.Empty; Application.RequestStop (); }; - var _dialog = new Dialog ("Please enter the item details.", _btnOk, _btnCancel); + var _dialog = new Dialog (_btnOk, _btnCancel) { Title = "Enter the menu details." }; Width = Dim.Fill (); Height = Dim.Fill () - 1; diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 9ef1b27d4..3a4908073 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -39,7 +39,8 @@ namespace UICatalog.Scenarios { ConfigurationManager.Themes.Theme = Theme; ConfigurationManager.Apply (); - Win = new Window (_fileName ?? "Untitled") { + Win = new Window () { + Title = _fileName ?? "Untitled", X = 0, Y = 1, Width = Dim.Fill (), @@ -736,12 +737,12 @@ namespace UICatalog.Scenarios { return; } - _winDialog = new Window (isFind ? "Find" : "Replace") { + _winDialog = new Window () { + Title = isFind ? "Find" : "Replace", X = Win.Bounds.Width / 2 - 30, Y = Win.Bounds.Height / 2 - 10, ColorScheme = Colors.TopLevel }; - _winDialog.Border.Effect3D = true; _tabView = new TabView () { X = 0, diff --git a/UICatalog/Scenarios/Frames.cs b/UICatalog/Scenarios/Frames.cs index 39ad35977..f06e7723f 100644 --- a/UICatalog/Scenarios/Frames.cs +++ b/UICatalog/Scenarios/Frames.cs @@ -170,7 +170,7 @@ namespace UICatalog.Scenarios { Add (new Label ("BorderStyle:")); - var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast ().ToList (); + var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast ().ToList (); var rbBorderStyle = new RadioGroup (borderStyleEnum.Select ( e => NStack.ustring.Make (e.ToString ())).ToArray ()) { @@ -181,7 +181,7 @@ namespace UICatalog.Scenarios { Add (rbBorderStyle); rbBorderStyle.SelectedItemChanged += (s, e) => { - viewToEdit.BorderFrame.BorderStyle = (BorderStyle)e.SelectedItem; + viewToEdit.BorderFrame.BorderStyle = (LineStyle)e.SelectedItem; viewToEdit.SetNeedsDisplay (); }; diff --git a/UICatalog/Scenarios/InteractiveTree.cs b/UICatalog/Scenarios/InteractiveTree.cs index e6b576f20..96b9569b0 100644 --- a/UICatalog/Scenarios/InteractiveTree.cs +++ b/UICatalog/Scenarios/InteractiveTree.cs @@ -114,7 +114,7 @@ namespace UICatalog.Scenarios { ok.Clicked += (s,e) => { okPressed = true; Application.RequestStop (); }; var cancel = new Button ("Cancel"); cancel.Clicked += (s,e) => { Application.RequestStop (); }; - var d = new Dialog (title, 60, 20, ok, cancel); + var d = new Dialog (ok, cancel) { Title = title }; var lbl = new Label () { X = 0, diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index 2354fb60c..7f9a6a19a 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -12,22 +12,6 @@ namespace UICatalog.Scenarios { public List _processHotKeyList = new List (); public List _processColdKeyList = new List (); - public TestWindow (ustring title = null) : base (title) - { - } - - public TestWindow (Rect frame, ustring title = null) : base (frame, title) - { - } - - public TestWindow (ustring title = null, int padding = 0) : base (title, padding) - { - } - - public TestWindow (Rect frame, ustring title = null, int padding = 0) : base (frame, title, padding) - { - } - public override bool ProcessKey (KeyEvent keyEvent) { _processKeyList.Add (keyEvent.ToString ()); @@ -54,7 +38,8 @@ namespace UICatalog.Scenarios { ConfigurationManager.Themes.Theme = Theme; ConfigurationManager.Apply (); - Win = new TestWindow ($"{Application.QuitKey} to Quit - Scenario: {GetName ()}") { + Win = new TestWindow () { + Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", X = 0, Y = 0, Width = Dim.Fill (), diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index c31ec65d0..9bb21c614 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -39,7 +39,7 @@ namespace UICatalog.Scenarios { LineCanvas grid; public event Action ColorChanged; - public event Action SetStyle; + public event Action SetStyle; Dictionary swatches = new Dictionary { { new Point(1,1),Color.Red}, @@ -53,17 +53,17 @@ namespace UICatalog.Scenarios { { grid = new LineCanvas (); - grid.AddLine (new Point (0, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single); - grid.AddLine (new Point (0, 0), width, Orientation.Horizontal, BorderStyle.Single); - grid.AddLine (new Point (width, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single); + grid.AddLine (new Point (0, 0), int.MaxValue, Orientation.Vertical, LineStyle.Single); + grid.AddLine (new Point (0, 0), width, Orientation.Horizontal, LineStyle.Single); + grid.AddLine (new Point (width, 0), int.MaxValue, Orientation.Vertical, LineStyle.Single); - grid.AddLine (new Point (0, 2), width, Orientation.Horizontal, BorderStyle.Single); + grid.AddLine (new Point (0, 2), width, Orientation.Horizontal, LineStyle.Single); - grid.AddLine (new Point (2, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single); - grid.AddLine (new Point (4, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single); - grid.AddLine (new Point (6, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single); + grid.AddLine (new Point (2, 0), int.MaxValue, Orientation.Vertical, LineStyle.Single); + grid.AddLine (new Point (4, 0), int.MaxValue, Orientation.Vertical, LineStyle.Single); + grid.AddLine (new Point (6, 0), int.MaxValue, Orientation.Vertical, LineStyle.Single); - grid.AddLine (new Point (0, 4), width, Orientation.Horizontal, BorderStyle.Single); + grid.AddLine (new Point (0, 4), width, Orientation.Horizontal, LineStyle.Single); } public override void Redraw (Rect bounds) { @@ -101,17 +101,17 @@ namespace UICatalog.Scenarios { if (mouseEvent.X == 3 && mouseEvent.Y == 3) { - SetStyle?.Invoke (BorderStyle.Double); + SetStyle?.Invoke (LineStyle.Double); return true; } if (mouseEvent.X == 5 && mouseEvent.Y == 3) { - SetStyle?.Invoke (BorderStyle.Single); + SetStyle?.Invoke (LineStyle.Single); return true; } if (mouseEvent.X == 7 && mouseEvent.Y == 3) { - SetStyle?.Invoke (BorderStyle.Rounded); + SetStyle?.Invoke (LineStyle.Rounded); return true; } } @@ -130,8 +130,6 @@ namespace UICatalog.Scenarios { Point? currentLineStart = null; - public BorderStyle BorderStyle { get; internal set; } - public DrawingArea () { AddCanvas (Color.White); diff --git a/UICatalog/Scenarios/MultiColouredTable.cs b/UICatalog/Scenarios/MultiColouredTable.cs index 86377256c..85fb25b43 100644 --- a/UICatalog/Scenarios/MultiColouredTable.cs +++ b/UICatalog/Scenarios/MultiColouredTable.cs @@ -75,7 +75,7 @@ namespace UICatalog.Scenarios { ok.Clicked += (s,e) => { okPressed = true; Application.RequestStop (); }; var cancel = new Button ("Cancel"); cancel.Clicked += (s,e) => { Application.RequestStop (); }; - var d = new Dialog (title, 60, 20, ok, cancel); + var d = new Dialog (ok, cancel) { Title = title }; var lbl = new Label () { X = 0, diff --git a/UICatalog/Scenarios/Notepad.cs b/UICatalog/Scenarios/Notepad.cs index 620ab4dd5..f28117b42 100644 --- a/UICatalog/Scenarios/Notepad.cs +++ b/UICatalog/Scenarios/Notepad.cs @@ -48,7 +48,7 @@ namespace UICatalog.Scenarios { Height = Dim.Fill (1), }; split.Tiles.ElementAt(0).ContentView.Add (tabView); - split.BorderStyle = BorderStyle.None; + split.LineStyle = LineStyle.None; Application.Top.Add (split); diff --git a/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs b/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs index e57d15f2c..98ebe35f2 100644 --- a/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs +++ b/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs @@ -21,13 +21,13 @@ namespace UICatalog.Scenarios { Application.Init (); var menu = new MenuBar (new MenuBarItem [] { - new MenuBarItem ("Margin", new MenuItem [] { - new MenuItem ("With margin", "", WithMargin), - new MenuItem ("Without margin", "", WithoutMargin) + new MenuBarItem ("Padding", new MenuItem [] { + new MenuItem ("With Padding", "", () => _win.Padding.Thickness = new Thickness (1)), + new MenuItem ("Without Padding", "", () =>_win.Padding.Thickness = new Thickness (0)) }), - new MenuBarItem ("Draw Margin Frame", new MenuItem [] { - new MenuItem ("With draw", "", WithDrawMargin), - new MenuItem ("Without draw", "", WithoutDrawMargin) + new MenuBarItem ("BorderStyle", new MenuItem [] { + new MenuItem ("Single", "", () => _win.BorderStyle = LineStyle.Single), + new MenuItem ("None", "", () => _win.BorderStyle = LineStyle.None) }), new MenuBarItem ("Runes length", new MenuItem [] { new MenuItem ("Wide", "", WideRunes), @@ -160,34 +160,6 @@ namespace UICatalog.Scenarios { Application.Refresh (); } - private void WithoutDrawMargin () - { - _win.Border.BorderStyle = BorderStyle.None; - _win.Border.DrawMarginFrame = false; - } - - private void WithDrawMargin () - { - _win.Border.DrawMarginFrame = true; - _win.Border.BorderStyle = BorderStyle.Single; - } - - private void WithoutMargin () - { - _win.X = 0; - _win.Y = 0; - _win.Width = Dim.Fill (); - _win.Height = Dim.Fill (); - } - - private void WithMargin () - { - _win.X = 5; - _win.Y = 5; - _win.Width = Dim.Fill (22); - _win.Height = Dim.Fill (5); - } - public override void Run () { } diff --git a/UICatalog/Scenarios/SingleBackgroundWorker.cs b/UICatalog/Scenarios/SingleBackgroundWorker.cs index 4a52dbdec..3318f2ea6 100644 --- a/UICatalog/Scenarios/SingleBackgroundWorker.cs +++ b/UICatalog/Scenarios/SingleBackgroundWorker.cs @@ -79,7 +79,7 @@ namespace UICatalog.Scenarios { log.Add ($"Worker is started at {startStaging}.{startStaging:fff}"); listLog.SetNeedsDisplay (); - var md = new Dialog ($"Running Worker started at {startStaging}.{startStaging:fff}", cancel); + var md = new Dialog (cancel) { Title = $"Running Worker started at {startStaging}.{startStaging:fff}" }; md.Add (new Label ("Wait for worker to finish...") { X = Pos.Center (), Y = Pos.Center () diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index d609dee7d..f652e329d 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -88,10 +88,10 @@ namespace UICatalog.Scenarios { var canvas = new LineCanvas (); - canvas.AddLine (new Point (0, 0), State.Width - 1, Orientation.Horizontal, BorderStyle.Double); - canvas.AddLine (new Point (0, 0), State.Height - 1, Orientation.Vertical, BorderStyle.Double); - canvas.AddLine (new Point (0, State.Height - 1), State.Width - 1, Orientation.Horizontal, BorderStyle.Double); - canvas.AddLine (new Point (State.Width - 1, 0), State.Height - 1, Orientation.Vertical, BorderStyle.Double); + canvas.AddLine (new Point (0, 0), State.Width - 1, Orientation.Horizontal, LineStyle.Double); + canvas.AddLine (new Point (0, 0), State.Height - 1, Orientation.Vertical, LineStyle.Double); + canvas.AddLine (new Point (0, State.Height - 1), State.Width - 1, Orientation.Horizontal, LineStyle.Double); + canvas.AddLine (new Point (State.Width - 1, 0), State.Height - 1, Orientation.Vertical, LineStyle.Double); for (int i = 1; i < State.Snake.Count; i++) { @@ -107,7 +107,7 @@ namespace UICatalog.Scenarios { pt2, length, orientation, - BorderStyle.Single); + LineStyle.Single); } diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index 34f700989..e1dd9c730 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -281,7 +281,7 @@ namespace UICatalog.Scenarios { ok.Clicked += (s,e) => { accepted = true; Application.RequestStop (); }; var cancel = new Button ("Cancel"); cancel.Clicked += (s,e) => { Application.RequestStop (); }; - var d = new Dialog (prompt, 60, 20, ok, cancel); + var d = new Dialog (ok, cancel) { Title = prompt }; var style = tableView.Style.GetOrCreateColumnStyle (col); @@ -763,7 +763,7 @@ namespace UICatalog.Scenarios { ok.Clicked += (s,e) => { okPressed = true; Application.RequestStop (); }; var cancel = new Button ("Cancel"); cancel.Clicked += (s,e) => { Application.RequestStop (); }; - var d = new Dialog (title, 60, 20, ok, cancel); + var d = new Dialog (ok, cancel) { Title = title }; var lbl = new Label () { X = 0, diff --git a/UICatalog/Scenarios/TileViewExperiment.cs b/UICatalog/Scenarios/TileViewExperiment.cs index 47ff81e8b..11d9b0f2f 100644 --- a/UICatalog/Scenarios/TileViewExperiment.cs +++ b/UICatalog/Scenarios/TileViewExperiment.cs @@ -35,7 +35,7 @@ namespace UICatalog.Scenarios { //IgnoreBorderPropertyOnRedraw = true }; - frame1.Border.BorderStyle = BorderStyle.Double; + frame1.BorderStyle = LineStyle.Double; //var frame2 = new FrameView () { // Title = "frame2", @@ -62,14 +62,9 @@ namespace UICatalog.Scenarios { Width = 30, //Dim.Percent (30) - 5, Height = 10, //Dim.Percent (50) - 5, ColorScheme = Colors.ColorSchemes ["Dialog"], - Border = new Border () { - BorderStyle = BorderStyle.Single, - BorderThickness = new Thickness (1), - DrawMarginFrame = true, - PaddingThickness = new Thickness(1), - ForgroundColor = Color.BrightMagenta, - } + BorderStyle = LineStyle.Single, }; + view1.Padding.Thickness = new Thickness (1); frame1.Add (view1); @@ -82,8 +77,7 @@ namespace UICatalog.Scenarios { Y = 0, Width = Dim.Percent (30), Height = Dim.Percent (70), - ColorScheme = Colors.ColorSchemes ["Error"], - Border = new Border () { BorderStyle = BorderStyle.Single } + ColorScheme = Colors.ColorSchemes ["Error"] }; frame1.Add (view2); diff --git a/UICatalog/Scenarios/TileViewNesting.cs b/UICatalog/Scenarios/TileViewNesting.cs index a6b0d1d8f..4fd2b4980 100644 --- a/UICatalog/Scenarios/TileViewNesting.cs +++ b/UICatalog/Scenarios/TileViewNesting.cs @@ -112,7 +112,7 @@ namespace UICatalog.Scenarios { root.Tiles.ElementAt (1).Title = (bool)cbTitles.Checked ? $"View 2" : string.Empty; - root.BorderStyle = (bool)border ? BorderStyle.Rounded : BorderStyle.None; + root.LineStyle = (bool)border ? LineStyle.Rounded : LineStyle.None; workArea.Add (root); diff --git a/UICatalog/Scenarios/ViewExperiments.cs b/UICatalog/Scenarios/ViewExperiments.cs index 7b9d73429..bf8eb4a6b 100644 --- a/UICatalog/Scenarios/ViewExperiments.cs +++ b/UICatalog/Scenarios/ViewExperiments.cs @@ -161,7 +161,7 @@ namespace UICatalog.Scenarios { }; Add (styleLabel); - var borderStyleEnum = Enum.GetValues (typeof (BorderStyle)).Cast ().ToList (); + var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast ().ToList (); var rbBorderStyle = new RadioGroup (borderStyleEnum.Select ( e => NStack.ustring.Make (e.ToString ())).ToArray ()) { X = Pos.Left (styleLabel), @@ -170,7 +170,7 @@ namespace UICatalog.Scenarios { }; rbBorderStyle.SelectedItemChanged += (s, e) => { - viewToEdit.BorderFrame.BorderStyle = (BorderStyle)e.SelectedItem; + viewToEdit.BorderFrame.BorderStyle = (LineStyle)e.SelectedItem; viewToEdit.SetNeedsDisplay (); }; Add (rbBorderStyle); @@ -276,7 +276,7 @@ namespace UICatalog.Scenarios { view.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"]; view.Margin.Data = "Margin"; view.BorderFrame.Thickness = new Thickness (2); - view.BorderFrame.BorderStyle = BorderStyle.Single; + view.BorderFrame.BorderStyle = LineStyle.Single; view.BorderFrame.ColorScheme = view.ColorScheme; view.BorderFrame.Data = "BorderFrame"; view.Padding.Thickness = new Thickness (2); @@ -298,7 +298,7 @@ namespace UICatalog.Scenarios { view2.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"]; view2.Margin.Data = "Margin"; view2.BorderFrame.Thickness = new Thickness (1); - view2.BorderFrame.BorderStyle = BorderStyle.Single; + view2.BorderFrame.BorderStyle = LineStyle.Single; view2.BorderFrame.ColorScheme = view.ColorScheme; view2.BorderFrame.Data = "BorderFrame"; view2.Padding.Thickness = new Thickness (1); @@ -322,7 +322,7 @@ namespace UICatalog.Scenarios { view3.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"]; view3.Margin.Data = "Margin"; view3.BorderFrame.Thickness = new Thickness (1, 1, 1, 1); - view3.BorderFrame.BorderStyle = BorderStyle.Single; + view3.BorderFrame.BorderStyle = LineStyle.Single; view3.BorderFrame.ColorScheme = view.ColorScheme; view3.BorderFrame.Data = "BorderFrame"; view3.Padding.Thickness = new Thickness (1, 1, 0, 0); @@ -346,7 +346,7 @@ namespace UICatalog.Scenarios { view4.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"]; view4.Margin.Data = "Margin"; view4.BorderFrame.Thickness = new Thickness (1, 1, 1, 1); - view4.BorderFrame.BorderStyle = BorderStyle.Single; + view4.BorderFrame.BorderStyle = LineStyle.Single; view4.BorderFrame.ColorScheme = view.ColorScheme; view4.BorderFrame.Data = "BorderFrame"; view4.Padding.Thickness = new Thickness (0, 0, 1, 1); @@ -369,7 +369,7 @@ namespace UICatalog.Scenarios { view5.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"]; view5.Margin.Data = "Margin"; view5.BorderFrame.Thickness = new Thickness (1, 1, 1, 1); - view5.BorderFrame.BorderStyle = BorderStyle.Single; + view5.BorderFrame.BorderStyle = LineStyle.Single; view5.BorderFrame.ColorScheme = view.ColorScheme; view5.BorderFrame.Data = "BorderFrame"; view5.Padding.Thickness = new Thickness (0, 0, 0, 0); diff --git a/UICatalog/Scenarios/WindowsAndFrameViews.cs b/UICatalog/Scenarios/WindowsAndFrameViews.cs index 54ca84b9e..b7273ab02 100644 --- a/UICatalog/Scenarios/WindowsAndFrameViews.cs +++ b/UICatalog/Scenarios/WindowsAndFrameViews.cs @@ -25,14 +25,17 @@ namespace UICatalog.Scenarios { Application.Top.Remove (Win); Win?.Dispose (); - Win = new Window ($"{listWin.Count} - Scenario: {GetName ()}", padding) { + Win = new Window () { + Title = $"{listWin.Count} - Scenario: {GetName ()}", X = Pos.Center (), Y = 1, Width = Dim.Fill (15), - Height = 10 + Height = 10, + ColorScheme = Colors.Dialog }; + Win.Padding.Thickness = new Thickness (padding); + Win.Margin.Thickness = new Thickness (margin); - Win.ColorScheme = Colors.Dialog; var paddingButton = new Button ($"Padding of container is {padding}") { X = Pos.Center (), Y = 0, @@ -57,14 +60,17 @@ namespace UICatalog.Scenarios { // TextField // sub FrameView with // - for (var i = 0; i < 3; i++) { + for (var pad = 0; pad < 3; pad++) { Window win = null; - win = new Window ($"{listWin.Count} - Window Loop - padding = {i}", i) { + win = new Window () { + Title = $"{listWin.Count} - Window Loop - padding = {pad}", X = margin, Y = Pos.Bottom (listWin.Last ()) + (margin), Width = Dim.Fill (margin), - Height = contentHeight + (i * 2) + 2, + Height = contentHeight + (pad * 2) + 2, }; + win.Padding.Thickness = new Thickness (pad); + win.ColorScheme = Colors.Dialog; var pressMeButton = new Button ("Press me! (Y = 0)") { X = Pos.Center (), @@ -74,7 +80,8 @@ namespace UICatalog.Scenarios { pressMeButton.Clicked += (s,e) => MessageBox.ErrorQuery (win.Title.ToString (), "Neat?", "Yes", "No"); win.Add (pressMeButton); - var subWin = new Window ("Sub Window") { + var subWin = new Window () { + Title = "Sub Window", X = Pos.Percent (0), Y = 1, Width = Dim.Percent (50), @@ -131,7 +138,8 @@ namespace UICatalog.Scenarios { ColorScheme = Colors.Error, //Clicked = () => MessageBox.ErrorQuery (frame.Title.ToString (), "Neat?", "Yes", "No") }); - var subWinofFV = new Window ("this is a Sub-Window") { + var subWinofFV = new Window () { + Title = "This is a Sub-Window", X = Pos.Percent (0), Y = 1, Width = Dim.Percent (50), diff --git a/UICatalog/Scenarios/Wizards.cs b/UICatalog/Scenarios/Wizards.cs index ef2f87836..b69572c3b 100644 --- a/UICatalog/Scenarios/Wizards.cs +++ b/UICatalog/Scenarios/Wizards.cs @@ -111,7 +111,8 @@ namespace UICatalog.Scenarios { actionLabel.Text = ustring.Empty; - var wizard = new Wizard (titleEdit.Text) { + var wizard = new Wizard () { + Title = titleEdit.Text, Width = width, Height = height }; diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 32ab01163..b63a54671 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -317,7 +317,7 @@ namespace UICatalog { CanFocus = true, Shortcut = Key.CtrlMask | Key.C, }; - ContentPane.BorderStyle = BorderStyle.Single; + ContentPane.LineStyle = LineStyle.Single; ContentPane.SetSplitterPos (0, 25); ContentPane.ShortcutAction = () => ContentPane.SetFocus (); @@ -655,7 +655,7 @@ namespace UICatalog { ColorScheme = Colors.ColorSchemes [_topLevelColorScheme]; - ContentPane.BorderStyle = FrameView.DefaultBorderStyle; + ContentPane.LineStyle = FrameView.DefaultBorderStyle; MenuBar.Menus [0].Children [0].Shortcut = Application.QuitKey; StatusBar.Items [0].Shortcut = Application.QuitKey; diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index 12736d9d8..558110429 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -772,10 +772,10 @@ namespace Terminal.Gui.ApplicationTests { public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_And_Mouse () { var top = Application.Top; - var win = new Window ("win") { X = 0, Y = 0, Width = 20, Height = 10 }; + var win = new Window () { Title = "win", X = 0, Y = 0, Width = 20, Height = 10 }; var tf = new TextField () { Width = 10 }; win.Add (tf); - var win2 = new Window ("win2") { X = 22, Y = 0, Width = 20, Height = 10 }; + var win2 = new Window () { Title = "win2", X = 22, Y = 0, Width = 20, Height = 10 }; var tf2 = new TextField () { Width = 10 }; win2.Add (tf2); top.Add (win, win2); @@ -817,10 +817,10 @@ namespace Terminal.Gui.ApplicationTests { public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () { var top = Application.Top; - var win = new Window ("win") { X = 0, Y = 0, Width = 20, Height = 10 }; + var win = new Window () { Title = "win", X = 0, Y = 0, Width = 20, Height = 10 }; var tf = new TextField () { Width = 10 }; win.Add (tf); - var win2 = new Window ("win2") { X = 22, Y = 0, Width = 20, Height = 10 }; + var win2 = new Window () { Title = "win2", X = 22, Y = 0, Width = 20, Height = 10 }; var tf2 = new TextField () { Width = 10 }; win2.Add (tf2); top.Add (win, win2); diff --git a/UnitTests/Configuration/ThemeTests.cs b/UnitTests/Configuration/ThemeTests.cs index f8679324a..15adb14c4 100644 --- a/UnitTests/Configuration/ThemeTests.cs +++ b/UnitTests/Configuration/ThemeTests.cs @@ -55,20 +55,19 @@ namespace Terminal.Gui.ConfigurationTests { public void TestApply () { ConfigurationManager.Reset (); - + var theme = new ThemeScope (); Assert.NotEmpty (theme); - + Themes.Add ("testTheme", theme); - Assert.True (Dialog.DefaultBorder.Effect3D); - Assert.Equal (typeof (Border), theme ["Dialog.DefaultBorder"].PropertyInfo.PropertyType); - theme ["Dialog.DefaultBorder"].PropertyValue = new Border () { Effect3D = false }; // default is true + Assert.Equal (LineStyle.Single, FrameView.DefaultBorderStyle); + theme ["FrameView.DefaultBorderStyle"].PropertyValue = LineStyle.Double; // default is Single Themes.Theme = "testTheme"; Themes! [ThemeManager.SelectedTheme]!.Apply (); - Assert.False (Dialog.DefaultBorder.Effect3D); + Assert.Equal (LineStyle.Double, FrameView.DefaultBorderStyle); } [Fact] diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index 30757e981..020c568b8 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -252,13 +252,13 @@ namespace Terminal.Gui.DriverTests { System.Threading.Tasks.Task.Delay (500).Wait (); Application.MainLoop.Invoke (() => { var lbl = new Label ("Hello World") { X = Pos.Center () }; - var dlg = new Dialog ("Test", new Button ("Ok")); + var dlg = new Dialog (new Button ("Ok")); dlg.Add (lbl); Application.Begin (dlg); var expected = @" ┌──────────────────┐ -│┌┤Test├─────────┐ │ +│┌───────────────┐ │ ││ Hello World │ │ ││ │ │ ││ │ │ @@ -275,7 +275,7 @@ namespace Terminal.Gui.DriverTests { expected = @" ┌──────────────────┐ -│┌┤Test├─────────┐ │ +│┌───────────────┐ │ ││ Hello World │ │ ││ │ │ ││ │ │ diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index 73dc3f546..8e9d120ea 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -44,7 +44,12 @@ namespace Terminal.Gui.DialogTests { private (Application.RunState, Dialog) RunButtonTestDialog (string title, int width, Dialog.ButtonAlignments align, params Button [] btns) { - var dlg = new Dialog (title, width, 1, btns) { + var dlg = new Dialog (btns) { + Title = title, + X = 0, + Y = 0, + Width = width, + Height = 1, ButtonAlignment = align, }; // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..) @@ -52,6 +57,155 @@ namespace Terminal.Gui.DialogTests { return (Application.Begin (dlg), dlg); } + [Fact] + [AutoInitShutdown] + public void Size_Default () + { + var d = new Dialog () { + }; + Application.Begin (d); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + // Default size is Percent(85) + Assert.Equal (new Size ((int)(100 * .85), (int)(100 * .85)), d.Frame.Size); + } + + [Fact] + [AutoInitShutdown] + public void Location_Default () + { + var d = new Dialog () { + }; + Application.Begin (d); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + // Default location is centered, so 100 / 2 - 85 / 2 = 7 + var expected = 7; + Assert.Equal (new Point (expected, expected), d.Frame.Location); + } + + + [Fact] + [AutoInitShutdown] + public void Size_Not_Default () + { + var d = new Dialog () { + Width = 50, + Height = 50, + }; + + Application.Begin (d); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + // Default size is Percent(85) + Assert.Equal (new Size (50, 50), d.Frame.Size); + } + + [Fact] + [AutoInitShutdown] + public void Location_Not_Default () + { + var d = new Dialog () { + X = 1, + Y = 1, + }; + Application.Begin (d); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + // Default location is centered, so 100 / 2 - 85 / 2 = 7 + var expected = 1; + Assert.Equal (new Point (expected, expected), d.Frame.Location); + } + + + [Fact] + [AutoInitShutdown] + public void Location_When_Application_Top_Not_Default () + { + var expected = 5; + var d = new Dialog () { + X = expected, + Y = expected, + Height = 5, + Width = 5 + }; + Application.Begin (d); + ((FakeDriver)Application.Driver).SetBufferSize (20, 10); + + // Default location is centered, so 100 / 2 - 85 / 2 = 7 + Assert.Equal (new Point (expected, expected), d.Frame.Location); + + TestHelpers.AssertDriverContentsWithFrameAre (@" + ┌───┐ + │ │ + │ │ + │ │ + └───┘", output); + } + + [Fact] + [AutoInitShutdown] + public void Location_When_Not_Application_Top_Not_Default () + { + Application.Top.BorderStyle = LineStyle.Double; + + var iterations = -1; + Application.Iteration += () => { + iterations++; + + if (iterations == 0) { + var d = new Dialog () { + X = 5, + Y = 5, + Height = 3, + Width = 5 + }; + Application.Begin (d); + + Assert.Equal (new Point (5, 5), d.Frame.Location); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔══════════════════╗ +║ ║ +║ ║ +║ ║ +║ ║ +║ ┌───┐ ║ +║ │ │ ║ +║ └───┘ ║ +║ ║ +╚══════════════════╝", output); + + d = new Dialog () { + X = 5, + Y = 5, + }; + Application.Begin (d); + + // This is because of PostionTopLevels and EnsureVisibleBounds + Assert.Equal (new Point (3, 2), d.Frame.Location); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔══════════════════╗ +║ ║ +║ ┌───────────────┐ +║ │ │ +║ │ │ +║ │ │ +║ │ │ +║ │ │ +║ │ │ +╚══└───────────────┘", output); + + + } else if (iterations > 0) { + Application.RequestStop (); + } + }; + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (20, 10); + Application.Run (); + } + [Fact] [AutoInitShutdown] public void ButtonAlignment_One () @@ -68,10 +222,11 @@ namespace Terminal.Gui.DialogTests { d.SetBufferSize (width, 1); (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Center, new Button (btnText)); + // Center TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); - // Justify + // Justify buttonRow = $"{d.VLine} {d.LeftBracket} {btnText} {d.RightBracket}{d.VLine}"; Assert.Equal (width, buttonRow.Length); (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Justify, new Button (btnText)); @@ -338,7 +493,7 @@ namespace Terminal.Gui.DialogTests { [Fact] [AutoInitShutdown] - public void ButtonAlignment_Four_On_Smaller_Width () + public void ButtonAlignment_Four_On_Too_Small_Width () { Application.RunState runstate = null; @@ -355,33 +510,30 @@ namespace Terminal.Gui.DialogTests { var btn3 = $"{d.LeftBracket} {btn3Text} {d.RightBracket}"; var btn4Text = "never"; var btn4 = $"{d.LeftBracket} {btn4Text} {d.RightBracket}"; - - var buttonRow = $"{d.VLine} {btn1} {btn2} {btn3} {btn4} {d.VLine}"; - var width = buttonRow.Length; - d.SetBufferSize (30, 1); - + var buttonRow = string.Empty; + + var width = 30; + d.SetBufferSize (width, 1); + // Default - Center - buttonRow = $"yes ] {btn2} {btn3} [ never"; - Assert.NotEqual (width, buttonRow.Length); - (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Center, new Button (btn1Text), new Button (btn2Text), new Button (btn3Text), new Button (btn4Text)); + buttonRow = $"{d.VLine}es ] {btn2} {btn3} [ neve{d.VLine}"; + (runstate, var dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Center, new Button (btn1Text), new Button (btn2Text), new Button (btn3Text), new Button (btn4Text)); + Assert.Equal (new Size (width, 1), dlg.Frame.Size); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); // Justify - buttonRow = $"es ] {btn2} {btn3} [ neve"; - Assert.NotEqual (width, buttonRow.Length); + buttonRow = $"{d.VLine}[ yes [ no [ maybe [ never ]{d.VLine}"; (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 = $" yes ] {btn2} {btn3} [ neve"; - Assert.NotEqual (width, buttonRow.Length); + buttonRow = $"{d.VLine}] {btn2} {btn3} {btn4}{d.VLine}"; (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 = $"es ] {btn2} {btn3} [ never"; - Assert.NotEqual (width, buttonRow.Length); + buttonRow = $"{d.VLine}{btn1} {btn2} {btn3} [ n{d.VLine}"; (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); } @@ -468,7 +620,7 @@ namespace Terminal.Gui.DialogTests { // Default - Center (runstate, var _) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Center, new Button (btn1Text), new Button (btn2Text), new Button (btn3Text), new Button (btn4Text)); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); + TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); // Justify @@ -552,7 +704,7 @@ namespace Terminal.Gui.DialogTests { d.SetBufferSize (width, 1); // Default (center) - var dlg = new Dialog (title, width, 1, new Button (btn1Text)) { ButtonAlignment = Dialog.ButtonAlignments.Center }; + var dlg = new Dialog (new Button (btn1Text)) { Title = title, Width = width, Height = 1, ButtonAlignment = Dialog.ButtonAlignments.Center }; // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..) dlg.BorderFrame.Thickness = new Thickness (1, 0, 1, 0); runstate = Application.Begin (dlg); @@ -568,7 +720,7 @@ namespace Terminal.Gui.DialogTests { Application.End (runstate); // Justify - dlg = new Dialog (title, width, 1, new Button (btn1Text)) { ButtonAlignment = Dialog.ButtonAlignments.Justify }; + dlg = new Dialog (new Button (btn1Text)) { Title = title, Width = width, Height = 1, ButtonAlignment = Dialog.ButtonAlignments.Justify }; // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..) dlg.BorderFrame.Thickness = new Thickness (1, 0, 1, 0); runstate = Application.Begin (dlg); @@ -584,7 +736,7 @@ namespace Terminal.Gui.DialogTests { Application.End (runstate); // Right - dlg = new Dialog (title, width, 1, new Button (btn1Text)) { ButtonAlignment = Dialog.ButtonAlignments.Right }; + dlg = new Dialog (new Button (btn1Text)) { Title = title, Width = width, Height = 1, ButtonAlignment = Dialog.ButtonAlignments.Right }; // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..) dlg.BorderFrame.Thickness = new Thickness (1, 0, 1, 0); runstate = Application.Begin (dlg); @@ -600,7 +752,7 @@ namespace Terminal.Gui.DialogTests { Application.End (runstate); // Left - dlg = new Dialog (title, width, 1, new Button (btn1Text)) { ButtonAlignment = Dialog.ButtonAlignments.Left }; + dlg = new Dialog (new Button (btn1Text)) { Title = title, Width = width, Height = 1, ButtonAlignment = Dialog.ButtonAlignments.Left }; // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..) dlg.BorderFrame.Thickness = new Thickness (1, 0, 1, 0); runstate = Application.Begin (dlg); @@ -638,8 +790,8 @@ namespace Terminal.Gui.DialogTests { btn2 = new Button ("Show Sub"); btn3 = new Button ("Close"); btn3.Clicked += (s, e) => Application.RequestStop (); - btn2.Clicked += (s, e) => { MessageBox.Query ("hey", "ya", "ok"); }; - var dlg = new Dialog ("Hey", btn2, btn3); + btn2.Clicked += (s, e) => { MessageBox.Query (string.Empty, "ya", "ok"); }; + var dlg = new Dialog (btn2, btn3); Application.Run (dlg); }; @@ -651,7 +803,7 @@ namespace Terminal.Gui.DialogTests { Assert.True (btn1.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); } else if (iterations == 1) { expected = @" - ┌┤Hey├─────────────────────────────────────────────────────────────┐ + ┌──────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ @@ -677,7 +829,7 @@ namespace Terminal.Gui.DialogTests { Assert.True (btn2.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); } else if (iterations == 2) { TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤Hey├─────────────────────────────────────────────────────────────┐ + ┌──────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ @@ -685,7 +837,7 @@ namespace Terminal.Gui.DialogTests { │ │ │ │ │ │ - │ ┌┤hey├─────────────────────────────────────────┐ │ + │ ┌──────────────────────────────────────────────┐ │ │ │ ya │ │ │ │ │ │ │ │ [◦ ok ◦] │ │ @@ -730,15 +882,15 @@ namespace Terminal.Gui.DialogTests { Application.RequestStop (); } }; - + win.Loaded += (s, a) => { - var dlg = new Dialog ("Test", 18, 3, new Button ("Ok")); + var dlg = new Dialog (new Button ("Ok")) { Width = 18, Height = 3 }; dlg.Loaded += (s, a) => { Application.Refresh (); var expected = @" ┌──────────────────┐ -│┌┤Test├──────────┐│ +│┌────────────────┐│ ││ [ Ok ] ││ │└────────────────┘│ └──────────────────┘"; @@ -749,42 +901,42 @@ namespace Terminal.Gui.DialogTests { }; Application.Run (win); } - -// [Theory, AutoInitShutdown] -// [InlineData (5)] -// //[InlineData (6)] -// //[InlineData (7)] -// //[InlineData (8)] -// //[InlineData (9)] -// public void Dialog_In_Window_Without_Size_One_Button_Aligns (int height) -// { -// ((FakeDriver)Application.Driver).SetBufferSize (20, height); -// var win = new Window (); -// Application.Iteration += () => { -// var dlg = new Dialog ("Test", new Button ("Ok")); + // [Theory, AutoInitShutdown] + // [InlineData (5)] + // //[InlineData (6)] + // //[InlineData (7)] + // //[InlineData (8)] + // //[InlineData (9)] + // public void Dialog_In_Window_Without_Size_One_Button_Aligns (int height) + // { + // ((FakeDriver)Application.Driver).SetBufferSize (20, height); + // var win = new Window (); -// dlg.LayoutComplete += (s, a) => { -// Application.Refresh (); -// // BUGBUG: This seems wrong; is it a bug in Dim.Percent(85)?? -// var expected = @" -//┌┌┤Test├─────────┐─┐ -//││ │ │ -//││ [ Ok ] │ │ -//│└───────────────┘ │ -//└──────────────────┘"; -// _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + // Application.Iteration += () => { + // var dlg = new Dialog ("Test", new Button ("Ok")); -// dlg.RequestStop (); -// win.RequestStop (); -// }; + // dlg.LayoutComplete += (s, a) => { + // Application.Refresh (); + // // BUGBUG: This seems wrong; is it a bug in Dim.Percent(85)?? + // var expected = @" + //┌┌┤Test├─────────┐─┐ + //││ │ │ + //││ [ Ok ] │ │ + //│└───────────────┘ │ + //└──────────────────┘"; + // _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Application.Run (dlg); -// }; + // dlg.RequestStop (); + // win.RequestStop (); + // }; -// Application.Run (win); -// Application.Shutdown (); -// } + // Application.Run (dlg); + // }; + + // Application.Run (win); + // Application.Shutdown (); + // } } } \ No newline at end of file diff --git a/UnitTests/Dialogs/MessageBoxTests.cs b/UnitTests/Dialogs/MessageBoxTests.cs index 22ad82fdb..d9dbd25ff 100644 --- a/UnitTests/Dialogs/MessageBoxTests.cs +++ b/UnitTests/Dialogs/MessageBoxTests.cs @@ -3,6 +3,7 @@ using Xunit; using Xunit.Abstractions; using System.Text; using Terminal.Gui; +using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; namespace Terminal.Gui.DialogTests { @@ -14,8 +15,166 @@ namespace Terminal.Gui.DialogTests { this.output = output; } + [Fact] + [AutoInitShutdown] + public void Size_Default () + { + var iterations = -1; + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + Application.Iteration += () => { + iterations++; + + if (iterations == 0) { + MessageBox.Query (string.Empty, string.Empty, null); + + Application.RequestStop (); + } else if (iterations == 1) { + Application.Refresh (); + + Assert.IsType (Application.Current); + // Default size is Percent(60) + Assert.Equal (new Size ((int)(100 * .60), 5), Application.Current.Frame.Size); + + Application.RequestStop (); + } + }; + + Application.Run (); + } + + [Fact] + [AutoInitShutdown] + public void Location_Default () + { + var iterations = -1; + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + Application.Iteration += () => { + iterations++; + + if (iterations == 0) { + MessageBox.Query (string.Empty, string.Empty, null); + + Application.RequestStop (); + } else if (iterations == 1) { + Application.Refresh (); + + Assert.IsType (Application.Current); + // Default location is centered, so + // X = (100 / 2) - (60 / 2) = 20 + // Y = (100 / 2) - (5 / 2) = 47 + Assert.Equal (new Point (20, 47), Application.Current.Frame.Location); + + Application.RequestStop (); + } + }; + + Application.Run (); + } + + [Theory] + [InlineData (0, 0)] + [InlineData (1, 1)] + [InlineData (7, 5)] + [InlineData (50, 50)] + [AutoInitShutdown] + public void Size_Not_Default_No_Message (int height, int width) + { + var iterations = -1; + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + Application.Iteration += () => { + iterations++; + + if (iterations == 0) { + MessageBox.Query (height, width, string.Empty, string.Empty, null); + + Application.RequestStop (); + } else if (iterations == 1) { + Application.Refresh (); + + Assert.IsType (Application.Current); + Assert.Equal (new Size (height, width), Application.Current.Frame.Size); + + Application.RequestStop (); + } + }; + } + + [Theory] + [InlineData (0, 0, "1")] + [InlineData (1, 1, "1")] + [InlineData (7, 5, "1")] + [InlineData (50, 50, "1")] + [InlineData (0, 0, "message")] + [InlineData (1, 1, "message")] + [InlineData (7, 5, "message")] + [InlineData (50, 50, "message")] + [AutoInitShutdown] + public void Size_Not_Default_Message (int height, int width, string message) + { + var iterations = -1; + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + Application.Iteration += () => { + iterations++; + + if (iterations == 0) { + MessageBox.Query (height, width, string.Empty, message, null); + + Application.RequestStop (); + } else if (iterations == 1) { + Application.Refresh (); + + Assert.IsType (Application.Current); + Assert.Equal (new Size (height, width), Application.Current.Frame.Size); + + Application.RequestStop (); + } + }; + } + + [Theory] + [InlineData (0, 0, "1")] + [InlineData (1, 1, "1")] + [InlineData (7, 5, "1")] + [InlineData (50, 50, "1")] + [InlineData (0, 0, "message")] + [InlineData (1, 1, "message")] + [InlineData (7, 5, "message")] + [InlineData (50, 50, "message")] + [AutoInitShutdown] + public void Size_Not_Default_Message_Button (int height, int width, string message) + { + var iterations = -1; + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (100, 100); + + Application.Iteration += () => { + iterations++; + + if (iterations == 0) { + MessageBox.Query (height, width, string.Empty, message, "_Ok"); + + Application.RequestStop (); + } else if (iterations == 1) { + Application.Refresh (); + + Assert.IsType (Application.Current); + Assert.Equal (new Size (height, width), Application.Current.Frame.Size); + + Application.RequestStop (); + } + }; + } + [Fact, AutoInitShutdown] - public void MessageBox_With_Empty_Size_Without_Buttons () + public void Size_None_No_Buttons () { var iterations = -1; Application.Begin (Application.Top); @@ -46,47 +205,39 @@ namespace Terminal.Gui.DialogTests { } [Fact, AutoInitShutdown] - public void MessageBox_With_Empty_Size_With_Button () + public void Size_No_With_Button () { + Application.Top.BorderStyle = LineStyle.Double; var iterations = -1; Application.Begin (Application.Top); + var aboutMessage = new StringBuilder (); + aboutMessage.AppendLine (@"0123456789012345678901234567890123456789"); + aboutMessage.AppendLine (@"https://github.com/gui-cs/Terminal.Gui"); + var message = aboutMessage.ToString (); + + ((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8); + Application.Iteration += () => { iterations++; if (iterations == 0) { - var aboutMessage = new StringBuilder (); - aboutMessage.AppendLine (@"A comprehensive sample library for"); - aboutMessage.AppendLine (@""); - aboutMessage.AppendLine (@" _______ _ _ _____ _ "); - aboutMessage.AppendLine (@" |__ __| (_) | | / ____| (_) "); - aboutMessage.AppendLine (@" | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _ "); - aboutMessage.AppendLine (@" | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | | "); - aboutMessage.AppendLine (@" | | __/ | | | | | | | | | | | (_| | || |__| | |_| | | "); - aboutMessage.AppendLine (@" |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_| "); - aboutMessage.AppendLine (@""); - aboutMessage.AppendLine (@"https://github.com/gui-cs/Terminal.Gui"); - MessageBox.Query ("About UI Catalog", aboutMessage.ToString (), "_Ok"); + + MessageBox.Query (string.Empty, message, "_Ok"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤About UI Catalog├──────────────────────────────────────────┐ - │ A comprehensive sample library for │ - │ │ - │ _______ _ _ _____ _ │ - │ |__ __| (_) | | / ____| (_) │ - │ | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _ │ - │ | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | | │ - │ | | __/ | | | | | | | | | | | (_| | || |__| | |_| | | │ - │ |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_| │ - │ │ - │ https://github.com/gui-cs/Terminal.Gui │ - │ │ - │ [◦ Ok ◦] │ - └────────────────────────────────────────────────────────────┘ +╔══════════════════════════════════════════╗ +║┌────────────────────────────────────────┐║ +║│0123456789012345678901234567890123456789│║ +║│ https://github.com/gui-cs/Terminal.Gui │║ +║│ │║ +║│ [◦ Ok ◦] │║ +║└────────────────────────────────────────┘║ +╚══════════════════════════════════════════╝ ", output); Application.RequestStop (); @@ -97,7 +248,7 @@ namespace Terminal.Gui.DialogTests { } [Fact, AutoInitShutdown] - public void MessageBox_With_A_Smaller_Fixed_Size () + public void Size_Tiny_Fixed_Size () { var iterations = -1; Application.Begin (Application.Top); @@ -106,13 +257,16 @@ namespace Terminal.Gui.DialogTests { iterations++; if (iterations == 0) { - MessageBox.Query (7, 5, "Title", "Message", "_Ok"); + MessageBox.Query (7, 5, string.Empty, "Message", "_Ok"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); + + Assert.Equal (new Size (7, 5), Application.Current.Frame.Size); + TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤Tit├┐ + ┌─────┐ │Messa│ │ ge │ │ Ok ◦│ @@ -127,7 +281,7 @@ namespace Terminal.Gui.DialogTests { } [Fact, AutoInitShutdown] - public void MessageBox_With_A_Enough_Fixed_Size () + public void Size_JustBigEnough_Fixed_Size () { var iterations = -1; Application.Begin (Application.Top); @@ -136,13 +290,13 @@ namespace Terminal.Gui.DialogTests { iterations++; if (iterations == 0) { - MessageBox.Query (11, 5, "Title", "Message", "_Ok"); + MessageBox.Query (11, 5, string.Empty, "Message", "_Ok"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤Title├──┐ + ┌─────────┐ │ Message │ │ │ │[◦ Ok ◦] │ @@ -157,47 +311,53 @@ namespace Terminal.Gui.DialogTests { } [Fact, AutoInitShutdown] - public void MessageBox_With_A_Label_Without_Spaces_WrapMessagge_True () + public void Message_Long_Without_Spaces_WrapMessage_True () { var iterations = -1; Application.Begin (Application.Top); + Application.Top.BorderStyle = LineStyle.Double; + ((FakeDriver)Application.Driver).SetBufferSize (20, 10); Application.Iteration += () => { iterations++; if (iterations == 0) { - MessageBox.Query ("mywindow", new string ('f', 2000), "ok"); + // 50 characters should make the height of the wrapped text 7 + MessageBox.Query (string.Empty, new string ('f', 50), defaultButton: 0, wrapMessage: true, "btn"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" -┌┤mywindow├────────────────────────────────────────────────────────────────────┐ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│ -│ [◦ ok ◦] │ -└──────────────────────────────────────────────────────────────────────────────┘", output); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔══════════════════╗ +║┌────────────────┐║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ ff │║ +║│ │║ +║│ [◦ btn ◦] │║ +║└────────────────┘║ +╚══════════════════╝", output); + Assert.Equal (new Size (20 - 2, 10 - 2), Application.Current.Frame.Size); + Application.RequestStop (); + + // Really long text + MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: true, "btn"); + } else if (iterations == 2) { + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔┌────────────────┐╗ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ [◦ btn ◦] │║ +╚└────────────────┘╝", output); Application.RequestStop (); } }; @@ -206,51 +366,54 @@ namespace Terminal.Gui.DialogTests { } [Fact, AutoInitShutdown] - public void MessageBox_With_A_Label_With_Spaces_WrapMessagge_True () + public void Message_With_Spaces_WrapMessage_True () { var iterations = -1; Application.Begin (Application.Top); + Application.Top.BorderStyle = LineStyle.Double; + ((FakeDriver)Application.Driver).SetBufferSize (20, 10); Application.Iteration += () => { iterations++; if (iterations == 0) { var sb = new StringBuilder (); - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 17; i++) sb.Append ("ff "); - MessageBox.Query ("mywindow", sb.ToString (), "ok"); + MessageBox.Query (string.Empty, sb.ToString (), defaultButton: 0, wrapMessage: true, "btn"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" -┌┤mywindow├────────────────────────────────────────────────────────────────────┐ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │ -│ [◦ ok ◦] │ -└──────────────────────────────────────────────────────────────────────────────┘", output); +╔══════════════════╗ +║ ┌──────────────┐ ║ +║ │ff ff ff ff ff│ ║ +║ │ff ff ff ff ff│ ║ +║ │ff ff ff ff ff│ ║ +║ │ ff ff │ ║ +║ │ │ ║ +║ │ [◦ btn ◦] │ ║ +║ └──────────────┘ ║ +╚══════════════════╝", output); + Application.RequestStop (); + // Really long text + MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: true, "btn"); + } else if (iterations == 2) { + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔┌────────────────┐╗ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ [◦ btn ◦] │║ +╚└────────────────┘╝", output); Application.RequestStop (); } }; @@ -259,26 +422,51 @@ namespace Terminal.Gui.DialogTests { } [Fact, AutoInitShutdown] - public void MessageBox_With_A_Label_Without_Spaces_WrapMessagge_False () + public void Message_Without_Spaces_WrapMessage_False () { var iterations = -1; Application.Begin (Application.Top); + Application.Top.BorderStyle = LineStyle.Double; + ((FakeDriver)Application.Driver).SetBufferSize (20, 10); Application.Iteration += () => { iterations++; if (iterations == 0) { - MessageBox.Query ("mywindow", new string ('f', 2000), 0, false, "ok"); + MessageBox.Query (string.Empty, new string ('f', 50), defaultButton: 0, wrapMessage: true, "btn"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" -──────────────────────────────────────────────────────────────────────────────── -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - - [◦ ok ◦] -────────────────────────────────────────────────────────────────────────────────", output); +╔══════════════════╗ +║┌────────────────┐║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ ff │║ +║│ │║ +║│ [◦ btn ◦] │║ +║└────────────────┘║ +╚══════════════════╝", output); + + Application.RequestStop (); + + // Really long text + MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: true, "btn"); + } else if (iterations == 2) { + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔┌────────────────┐╗ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ [◦ btn ◦] │║ +╚└────────────────┘╝", output); Application.RequestStop (); } @@ -288,31 +476,54 @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff } [Fact, AutoInitShutdown] - public void MessageBox_With_A_Label_With_Spaces_WrapMessagge_False () + public void Message_With_Spaces_WrapMessage_False () { var iterations = -1; Application.Begin (Application.Top); + Application.Top.BorderStyle = LineStyle.Double; + ((FakeDriver)Application.Driver).SetBufferSize (20, 10); Application.Iteration += () => { iterations++; if (iterations == 0) { var sb = new StringBuilder (); - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 17; i++) sb.Append ("ff "); - MessageBox.Query ("mywindow", sb.ToString (), 0, false, "ok"); + MessageBox.Query (string.Empty, sb.ToString (), defaultButton: 0, wrapMessage: false, "btn"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" -──────────────────────────────────────────────────────────────────────────────── - ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff f - - [◦ ok ◦] -────────────────────────────────────────────────────────────────────────────────", output); +╔══════════════════╗ +║ ┌──────────────┐ ║ +║ │ff ff ff ff ff│ ║ +║ │ff ff ff ff ff│ ║ +║ │ff ff ff ff ff│ ║ +║ │ ff ff │ ║ +║ │ │ ║ +║ │ [◦ btn ◦] │ ║ +║ └──────────────┘ ║ +╚══════════════════╝", output); + Application.RequestStop (); + // Really long text + MessageBox.Query (string.Empty, new string ('f', 500), defaultButton: 0, wrapMessage: false, "btn"); + } else if (iterations == 2) { + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" +╔┌────────────────┐╗ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ffffffffffffffff│║ +║│ [◦ btn ◦] │║ +╚└────────────────┘╝", output); Application.RequestStop (); } }; @@ -321,11 +532,15 @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff } [Theory, AutoInitShutdown] + [InlineData (" ", true)] + [InlineData (" ", false)] [InlineData ("", true)] [InlineData ("", false)] [InlineData ("\n", true)] [InlineData ("\n", false)] - public void MessageBox_With_A_Empty_Message_Or_A_NewLline_WrapMessagge_True_Or_False (string message, bool wrapMessage) + [InlineData (" \n", true)] + [InlineData (" \n", false)] + public void Message_Empty_Or_A_NewLline_WrapMessagge_True_Or_False (string message, bool wrapMessage) { var iterations = -1; Application.Begin (Application.Top); @@ -334,13 +549,13 @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff iterations++; if (iterations == 0) { - MessageBox.Query ("mywindow", message, 0, wrapMessage, "ok"); + MessageBox.Query (string.Empty, message, 0, wrapMessage, "ok"); Application.RequestStop (); } else if (iterations == 1) { Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤mywindow├────────────────────────────────────┐ + ┌──────────────────────────────────────────────┐ │ │ │ │ │ [◦ ok ◦] │ diff --git a/UnitTests/Dialogs/WizardTests.cs b/UnitTests/Dialogs/WizardTests.cs index e9e052efd..e8052655f 100644 --- a/UnitTests/Dialogs/WizardTests.cs +++ b/UnitTests/Dialogs/WizardTests.cs @@ -22,7 +22,7 @@ namespace Terminal.Gui.DialogTests { private void RunButtonTestWizard (string title, int width, int height) { - var wizard = new Wizard (title) { Width = width, Height = height }; + var wizard = new Wizard () { Title = title, Width = width, Height = height }; Application.End (Application.Begin (wizard)); } @@ -126,7 +126,7 @@ namespace Terminal.Gui.DialogTests { var buttonRow = $"{d.VDLine}{btnBack}{new string (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{d.VDLine}"; var bottomRow = $"{d.LLDCorner}{new string (d.HDLine.ToString () [0], width - 2)}{d.LRDCorner}"; - var wizard = new Wizard (title) { Width = width, Height = height }; + var wizard = new Wizard () { Title = title, Width = width, Height = height }; var runstate = Application.Begin (wizard); TestHelpers.AssertDriverContentsWithFrameAre ($"{topRow}\n{row2}\n{row3}\n{separatorRow}\n{buttonRow}\n{bottomRow}", output); Application.End (runstate); @@ -159,7 +159,7 @@ namespace Terminal.Gui.DialogTests { var buttonRow = $"{d.VDLine}{btnBack}{new string (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{d.VDLine}"; var bottomRow = $"{d.LLDCorner}{new string (d.HDLine.ToString () [0], width - 2)}{d.LRDCorner}"; - var wizard = new Wizard (title) { Width = width, Height = height }; + var wizard = new Wizard () { Title = title, Width = width, Height = height }; wizard.AddStep (new Wizard.WizardStep (stepTitle)); //wizard.LayoutSubviews (); var firstIteration = false; @@ -229,7 +229,7 @@ namespace Terminal.Gui.DialogTests { //var buttonRow = $"{d.VDLine}{new String (' ', width - btnNext.Length - 2)}{btnNext}{d.VDLine}"; var bottomRow = $"{d.LLDCorner}{new string (d.HDLine.ToString () [0], width - 2)}{d.LRDCorner}"; - var wizard = new Wizard (title) { Width = width, Height = height }; + var wizard = new Wizard () { Title = title, Width = width, Height = height }; wizard.AddStep (new Wizard.WizardStep ("ABCD")); Application.End (Application.Begin (wizard)); diff --git a/UnitTests/Drawing/LineCanvasTests.cs b/UnitTests/Drawing/LineCanvasTests.cs index 5b5500766..eba5341ba 100644 --- a/UnitTests/Drawing/LineCanvasTests.cs +++ b/UnitTests/Drawing/LineCanvasTests.cs @@ -14,10 +14,10 @@ namespace Terminal.Gui.DrawingTests { this.output = output; } - [InlineData (BorderStyle.Single)] - [InlineData (BorderStyle.Rounded)] + [InlineData (LineStyle.Single)] + [InlineData (LineStyle.Rounded)] [Theory, AutoInitShutdown] - public void TestLineCanvas_Horizontal (BorderStyle style) + public void TestLineCanvas_Horizontal (LineStyle style) { var v = GetCanvas (out var canvas); canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, style); @@ -34,7 +34,7 @@ namespace Terminal.Gui.DrawingTests { public void TestLineCanvas_Horizontal_Double () { var v = GetCanvas (out var canvas); - canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, BorderStyle.Double); + canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, LineStyle.Double); v.Redraw (v.Bounds); @@ -44,10 +44,10 @@ namespace Terminal.Gui.DrawingTests { TestHelpers.AssertDriverContentsAre (looksLike, output); } - [InlineData (BorderStyle.Single)] - [InlineData (BorderStyle.Rounded)] + [InlineData (LineStyle.Single)] + [InlineData (LineStyle.Rounded)] [Theory, AutoInitShutdown] - public void TestLineCanvas_Vertical (BorderStyle style) + public void TestLineCanvas_Vertical (LineStyle style) { var v = GetCanvas (out var canvas); canvas.AddLine (new Point (0, 0), 1, Orientation.Vertical, style); @@ -65,7 +65,7 @@ namespace Terminal.Gui.DrawingTests { public void TestLineCanvas_Vertical_Double () { var v = GetCanvas (out var canvas); - canvas.AddLine (new Point (0, 0), 1, Orientation.Vertical, BorderStyle.Double); + canvas.AddLine (new Point (0, 0), 1, Orientation.Vertical, LineStyle.Double); v.Redraw (v.Bounds); @@ -84,8 +84,8 @@ namespace Terminal.Gui.DrawingTests { public void TestLineCanvas_Corner_NoOverlap () { var v = GetCanvas (out var canvas); - canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, BorderStyle.Single); - canvas.AddLine (new Point (0, 1), 1, Orientation.Vertical, BorderStyle.Single); + canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, LineStyle.Single); + canvas.AddLine (new Point (0, 1), 1, Orientation.Vertical, LineStyle.Single); v.Redraw (v.Bounds); @@ -104,8 +104,8 @@ namespace Terminal.Gui.DrawingTests { public void TestLineCanvas_Corner_Correct () { var v = GetCanvas (out var canvas); - canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, BorderStyle.Single); - canvas.AddLine (new Point (0, 0), 2, Orientation.Vertical, BorderStyle.Single); + canvas.AddLine (new Point (0, 0), 1, Orientation.Horizontal, LineStyle.Single); + canvas.AddLine (new Point (0, 0), 2, Orientation.Vertical, LineStyle.Single); v.Redraw (v.Bounds); @@ -124,14 +124,14 @@ namespace Terminal.Gui.DrawingTests { var v = GetCanvas (out var canvas); // outer box - canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, BorderStyle.Single); - canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, BorderStyle.Single); - canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, BorderStyle.Single); - canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, BorderStyle.Single); + canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, LineStyle.Single); + canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, LineStyle.Single); + canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, LineStyle.Single); + canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, LineStyle.Single); - canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, BorderStyle.Single); - canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, BorderStyle.Single); + canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, LineStyle.Single); + canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, LineStyle.Single); v.Redraw (v.Bounds); @@ -146,7 +146,7 @@ namespace Terminal.Gui.DrawingTests { } /// - /// Demonstrates when corners are used. Notice how + /// Demonstrates when corners are used. Notice how /// not all lines declare rounded. If there are 1+ lines intersecting and a corner is /// to be used then if any of them are rounded a rounded corner is used. /// @@ -156,17 +156,17 @@ namespace Terminal.Gui.DrawingTests { var v = GetCanvas (out var canvas); // outer box - canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, BorderStyle.Rounded); + canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, LineStyle.Rounded); // BorderStyle.Single is ignored because corner overlaps with the above line which is Rounded // this results in a rounded corner being used. - canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, BorderStyle.Single); - canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, BorderStyle.Rounded); - canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, BorderStyle.Single); + canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, LineStyle.Single); + canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, LineStyle.Rounded); + canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, LineStyle.Single); // These lines say rounded but they will result in the T sections which are never rounded. - canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, BorderStyle.Rounded); - canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, BorderStyle.Rounded); + canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, LineStyle.Rounded); + canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, LineStyle.Rounded); v.Redraw (v.Bounds); @@ -186,14 +186,14 @@ namespace Terminal.Gui.DrawingTests { var v = GetCanvas (out var canvas); // outer box - canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, BorderStyle.Double); - canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, BorderStyle.Double); - canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, BorderStyle.Double); - canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, BorderStyle.Double); + canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, LineStyle.Double); + canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, LineStyle.Double); + canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, LineStyle.Double); + canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, LineStyle.Double); - canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, BorderStyle.Double); - canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, BorderStyle.Double); + canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, LineStyle.Double); + canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, LineStyle.Double); v.Redraw (v.Bounds); @@ -209,21 +209,21 @@ namespace Terminal.Gui.DrawingTests { [Theory, AutoInitShutdown] - [InlineData (BorderStyle.Single)] - [InlineData (BorderStyle.Rounded)] - public void TestLineCanvas_Window_DoubleTop_SingleSides (BorderStyle thinStyle) + [InlineData (LineStyle.Single)] + [InlineData (LineStyle.Rounded)] + public void TestLineCanvas_Window_DoubleTop_SingleSides (LineStyle thinStyle) { var v = GetCanvas (out var canvas); // outer box - canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, BorderStyle.Double); + canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, LineStyle.Double); canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, thinStyle); - canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, BorderStyle.Double); + canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, LineStyle.Double); canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, thinStyle); canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, thinStyle); - canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, BorderStyle.Double); + canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, LineStyle.Double); v.Redraw (v.Bounds); @@ -239,20 +239,20 @@ namespace Terminal.Gui.DrawingTests { } [Theory, AutoInitShutdown] - [InlineData (BorderStyle.Single)] - [InlineData (BorderStyle.Rounded)] - public void TestLineCanvas_Window_SingleTop_DoubleSides (BorderStyle thinStyle) + [InlineData (LineStyle.Single)] + [InlineData (LineStyle.Rounded)] + public void TestLineCanvas_Window_SingleTop_DoubleSides (LineStyle thinStyle) { var v = GetCanvas (out var canvas); // outer box canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, thinStyle); - canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, BorderStyle.Double); + canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, LineStyle.Double); canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, thinStyle); - canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, BorderStyle.Double); + canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, LineStyle.Double); - canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, BorderStyle.Double); + canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, LineStyle.Double); canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, thinStyle); v.Redraw (v.Bounds); @@ -276,14 +276,14 @@ namespace Terminal.Gui.DrawingTests { var v = GetCanvas (out var canvas, 1, 1); // outer box - canvas.AddLine (new Point (0, 0), 8, Orientation.Horizontal, BorderStyle.Single); - canvas.AddLine (new Point (8, 0), 3, Orientation.Vertical, BorderStyle.Single); - canvas.AddLine (new Point (8, 3), -8, Orientation.Horizontal, BorderStyle.Single); - canvas.AddLine (new Point (0, 3), -3, Orientation.Vertical, BorderStyle.Single); + canvas.AddLine (new Point (0, 0), 8, Orientation.Horizontal, LineStyle.Single); + canvas.AddLine (new Point (8, 0), 3, Orientation.Vertical, LineStyle.Single); + canvas.AddLine (new Point (8, 3), -8, Orientation.Horizontal, LineStyle.Single); + canvas.AddLine (new Point (0, 3), -3, Orientation.Vertical, LineStyle.Single); - canvas.AddLine (new Point (5, 0), 3, Orientation.Vertical, BorderStyle.Single); - canvas.AddLine (new Point (0, 2), 8, Orientation.Horizontal, BorderStyle.Single); + canvas.AddLine (new Point (5, 0), 3, Orientation.Vertical, LineStyle.Single); + canvas.AddLine (new Point (0, 2), 8, Orientation.Horizontal, LineStyle.Single); v.Redraw (v.Bounds); @@ -307,19 +307,19 @@ namespace Terminal.Gui.DrawingTests { // ╔╡ Title ╞═════╗ // Add a short horiz line for ╔╡ - lc.AddLine (new Point (0, 0), 1, Orientation.Horizontal, BorderStyle.Double); + lc.AddLine (new Point (0, 0), 1, Orientation.Horizontal, LineStyle.Double); //LHS line down - lc.AddLine (new Point (0, 0), 5, Orientation.Vertical, BorderStyle.Double); + lc.AddLine (new Point (0, 0), 5, Orientation.Vertical, LineStyle.Double); //Vertical line before Title, results in a ╡ - lc.AddLine (new Point (1, 0), 0, Orientation.Vertical, BorderStyle.Single); + lc.AddLine (new Point (1, 0), 0, Orientation.Vertical, LineStyle.Single); //Vertical line after Title, results in a ╞ - lc.AddLine (new Point (6, 0), 0, Orientation.Vertical, BorderStyle.Single); + lc.AddLine (new Point (6, 0), 0, Orientation.Vertical, LineStyle.Single); // remainder of title - lc.AddLine (new Point (6, 0), 3, Orientation.Horizontal, BorderStyle.Double); + lc.AddLine (new Point (6, 0), 3, Orientation.Horizontal, LineStyle.Double); //RHS line down - lc.AddLine (new Point (9, 0), 5, Orientation.Vertical, BorderStyle.Double); + lc.AddLine (new Point (9, 0), 5, Orientation.Vertical, LineStyle.Double); v.Redraw (v.Bounds); @@ -330,13 +330,13 @@ namespace Terminal.Gui.DrawingTests { TestHelpers.AssertDriverContentsAre (looksLike, output); } - [InlineData(0,0,0, Orientation.Horizontal,BorderStyle.Double,"═")] - [InlineData(0,0,0, Orientation.Vertical,BorderStyle.Double,"║")] - [InlineData(0,0,0, Orientation.Horizontal,BorderStyle.Single,"─")] - [InlineData(0,0,0, Orientation.Vertical,BorderStyle.Single,"│")] + [InlineData(0,0,0, Orientation.Horizontal,LineStyle.Double,"═")] + [InlineData(0,0,0, Orientation.Vertical,LineStyle.Double,"║")] + [InlineData(0,0,0, Orientation.Horizontal,LineStyle.Single,"─")] + [InlineData(0,0,0, Orientation.Vertical,LineStyle.Single,"│")] [AutoInitShutdown, Theory] public void TestLineCanvas_1LineTests( - int x1, int y1,int l1, Orientation o1, BorderStyle s1, + int x1, int y1,int l1, Orientation o1, LineStyle s1, string expected ) { @@ -355,44 +355,44 @@ namespace Terminal.Gui.DrawingTests { [Theory, AutoInitShutdown] [InlineData( - 0,0,1,Orientation.Horizontal,BorderStyle.Double, - 1,0,0, Orientation.Vertical,BorderStyle.Single, "═╡" + 0,0,1,Orientation.Horizontal,LineStyle.Double, + 1,0,0, Orientation.Vertical,LineStyle.Single, "═╡" )] [InlineData( - 0,0,0, Orientation.Vertical,BorderStyle.Single, - 0,0,1,Orientation.Horizontal,BorderStyle.Double, + 0,0,0, Orientation.Vertical,LineStyle.Single, + 0,0,1,Orientation.Horizontal,LineStyle.Double, "╞═" )] [InlineData( - 0,0,1, Orientation.Vertical,BorderStyle.Single, - 0,0,0,Orientation.Horizontal,BorderStyle.Double, + 0,0,1, Orientation.Vertical,LineStyle.Single, + 0,0,0,Orientation.Horizontal,LineStyle.Double, @" ╤ │" )] [InlineData( - 0,0,1, Orientation.Vertical,BorderStyle.Single, - 0,1,0,Orientation.Horizontal,BorderStyle.Double, + 0,0,1, Orientation.Vertical,LineStyle.Single, + 0,1,0,Orientation.Horizontal,LineStyle.Double, @" │ ╧ " )] [InlineData( - 0,0,0, Orientation.Vertical,BorderStyle.Single, - 0,0,0,Orientation.Horizontal,BorderStyle.Single, + 0,0,0, Orientation.Vertical,LineStyle.Single, + 0,0,0,Orientation.Horizontal,LineStyle.Single, @"┼ " )] [InlineData( - 0,0,0, Orientation.Vertical,BorderStyle.Double, - 0,0,0,Orientation.Horizontal,BorderStyle.Double, + 0,0,0, Orientation.Vertical,LineStyle.Double, + 0,0,0,Orientation.Horizontal,LineStyle.Double, @"╬ " )] public void TestLineCanvas_2LineTests( - int x1, int y1,int l1, Orientation o1, BorderStyle s1, - int x2, int y2, int l2, Orientation o2, BorderStyle s2, + int x1, int y1,int l1, Orientation o1, LineStyle s1, + int x2, int y2, int l2, Orientation o2, LineStyle s2, string expected ) { diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs index 15c56ecd0..9b9ec9ea8 100644 --- a/UnitTests/Text/TextFormatterTests.cs +++ b/UnitTests/Text/TextFormatterTests.cs @@ -1540,12 +1540,23 @@ namespace Terminal.Gui.TextTests { var text = ustring.Empty; int width = 0; - Assert.Empty (TextFormatter.WordWrap (null, width)); - Assert.Empty (TextFormatter.WordWrap (text, width)); - Assert.Throws (() => TextFormatter.WordWrap (text, -1)); + Assert.Empty (TextFormatter.WordWrapText (null, width)); + Assert.Empty (TextFormatter.WordWrapText (text, width)); + Assert.Throws (() => TextFormatter.WordWrapText (text, -1)); } [Fact] + public void WordWrap_BigWidth () + { + List wrappedLines; + + var text = "Constantinople"; + wrappedLines = TextFormatter.WordWrapText (text, 100); + Assert.True (wrappedLines.Count == 1); + Assert.Equal ("Constantinople", wrappedLines [0].ToString ()); + } + + [Fact] public void WordWrap_SingleWordLine () { var text = ustring.Empty; @@ -1554,43 +1565,43 @@ namespace Terminal.Gui.TextTests { text = "Constantinople"; width = text.RuneCount; - wrappedLines = TextFormatter.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.True (wrappedLines.Count == 1); width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrap (text, width); + 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.WordWrap (text, width); + 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.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (2, wrappedLines.Count); width = (int)Math.Ceiling ((double)(text.RuneCount / 2F)); - wrappedLines = TextFormatter.WordWrap (text, width); + 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.WordWrap (text, width); + 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.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (4, wrappedLines.Count); width = (int)Math.Ceiling ((double)text.RuneCount / text.RuneCount); - wrappedLines = TextFormatter.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (text.RuneCount, wrappedLines.Count); Assert.Equal (text.ConsoleWidth, wrappedLines.Count); Assert.Equal ("C", wrappedLines [0].ToString ()); @@ -1618,45 +1629,45 @@ namespace Terminal.Gui.TextTests { text = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ"; width = text.RuneCount; - wrappedLines = TextFormatter.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.True (wrappedLines.Count == 1); width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrap (text, width); + 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.WordWrap (text, width); + 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.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (2, wrappedLines.Count); width = (int)Math.Ceiling ((double)(text.RuneCount / 2F)); - wrappedLines = TextFormatter.WordWrap (text, width); + 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.WordWrap (text, width); + 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.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (4, wrappedLines.Count); width = (int)Math.Ceiling ((double)text.RuneCount / text.RuneCount); - wrappedLines = TextFormatter.WordWrap (text, width); + 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 ()); @@ -1674,45 +1685,45 @@ namespace Terminal.Gui.TextTests { text = "This\u00A0is\u00A0a\u00A0sentence."; width = text.RuneCount; - wrappedLines = TextFormatter.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.True (wrappedLines.Count == 1); width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrap (text, width); + 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.WordWrap (text, width); + 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.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (2, wrappedLines.Count); width = (int)Math.Ceiling ((double)(text.RuneCount / 2F)); - wrappedLines = TextFormatter.WordWrap (text, width); + 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.WordWrap (text, width); + 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.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (4, wrappedLines.Count); width = (int)Math.Ceiling ((double)text.RuneCount / text.RuneCount); - wrappedLines = TextFormatter.WordWrap (text, width); + 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 ()); @@ -1730,11 +1741,11 @@ namespace Terminal.Gui.TextTests { text = "This\u00A0is\n\u00A0a\u00A0sentence."; width = text.RuneCount; - wrappedLines = TextFormatter.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.True (wrappedLines.Count == 1); width = text.RuneCount - 1; - wrappedLines = TextFormatter.WordWrap (text, width); + 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. @@ -1742,13 +1753,14 @@ namespace Terminal.Gui.TextTests { text = "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence."; width = text.RuneCount; - wrappedLines = TextFormatter.WordWrap (text, width); + wrappedLines = TextFormatter.WordWrapText (text, width); Assert.True (wrappedLines.Count == 1); } [Fact] - public void WordWrap_NoNewLines () + public void WordWrap_NoNewLines_Default () { + // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false var text = ustring.Empty; int maxWidth = 0; int expectedClippedWidth = 0; @@ -1758,7 +1770,7 @@ namespace Terminal.Gui.TextTests { text = "A sentence has words."; maxWidth = text.RuneCount; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1766,7 +1778,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - 1; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1775,7 +1787,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1784,7 +1796,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - " words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1793,7 +1805,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "s words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1804,7 +1816,7 @@ namespace Terminal.Gui.TextTests { text = "A Unicode sentence (пÑивеÑ) has words."; maxWidth = text.RuneCount; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1812,7 +1824,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - 1; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1821,7 +1833,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1830,7 +1842,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - " words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1839,7 +1851,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "s words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1848,7 +1860,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "веÑ) has words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1871,7 +1883,7 @@ namespace Terminal.Gui.TextTests { text = "A sentence has words.\nA paragraph has lines."; maxWidth = text.RuneCount; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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. @@ -1880,7 +1892,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - 1; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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. @@ -1890,7 +1902,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1901,7 +1913,7 @@ namespace Terminal.Gui.TextTests { text = "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии."; maxWidth = text.RuneCount; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1909,7 +1921,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - 1; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1918,7 +1930,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1927,7 +1939,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "s words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1936,7 +1948,7 @@ namespace Terminal.Gui.TextTests { maxWidth = text.RuneCount - "веÑ) has words.".Length; expectedClippedWidth = Math.Min (text.RuneCount, maxWidth); - wrappedLines = TextFormatter.WordWrap (text, 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)); @@ -1945,8 +1957,9 @@ namespace Terminal.Gui.TextTests { } [Fact] - public void WordWrap_Narrow () + public void WordWrap_Narrow_Default () { + // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false var text = ustring.Empty; int maxWidth = 1; int expectedClippedWidth = 1; @@ -1956,7 +1969,7 @@ namespace Terminal.Gui.TextTests { text = "A sentence has words."; maxWidth = 3; expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrap (text, 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 ()); @@ -1969,7 +1982,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 2; expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrap (text, 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 ()); @@ -1980,7 +1993,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 1; expectedClippedWidth = 1; - wrappedLines = TextFormatter.WordWrap (text, 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 ()); @@ -1991,7 +2004,7 @@ namespace Terminal.Gui.TextTests { } [Fact] - public void WordWrap_preserveTrailingSpaces () + public void WordWrap_PreserveTrailingSpaces_True () { var text = ustring.Empty; int maxWidth = 1; @@ -2002,7 +2015,7 @@ namespace Terminal.Gui.TextTests { text = "A sentence has words."; maxWidth = 14; expectedClippedWidth = 14; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2011,7 +2024,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 8; expectedClippedWidth = 8; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2022,7 +2035,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 6; expectedClippedWidth = 6; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2034,7 +2047,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 3; expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2049,7 +2062,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 2; expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2067,7 +2080,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 1; expectedClippedWidth = 1; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2086,7 +2099,7 @@ namespace Terminal.Gui.TextTests { } [Fact] - public void WordWrap_preserveTrailingSpaces_Wide_Runes () + public void WordWrap_PreserveTrailingSpaces_True_Wide_Runes () { var text = ustring.Empty; int maxWidth = 1; @@ -2097,7 +2110,7 @@ namespace Terminal.Gui.TextTests { text = "文に は言葉 があり ます。"; maxWidth = 14; expectedClippedWidth = 14; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2106,7 +2119,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 3; expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2124,7 +2137,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 2; expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + 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 ()); @@ -2145,7 +2158,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 1; expectedClippedWidth = 0; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true); + wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true); Assert.Empty (wrappedLines); Assert.False (wrappedLines.Count == text.Length); Assert.False (wrappedLines.Count == text.RuneCount); @@ -2154,160 +2167,874 @@ namespace Terminal.Gui.TextTests { Assert.Equal (25, TextFormatter.GetTextWidth (text)); } - [Fact, AutoInitShutdown] - public void WordWrap_preserveTrailingSpaces_Horizontal_With_Simple_Runes () + [Fact] + public void WordWrap_PreserveTrailingSpaces_False_Wide_Runes () { - var text = "A sentence has words."; - var width = 3; - var height = 8; - var wrappedLines = TextFormatter.WordWrap (text, width, true); - var breakLines = ""; - foreach (var line in wrappedLines) breakLines += $"{line}{Environment.NewLine}"; - var label = new Label (breakLines) { Width = Dim.Fill (), Height = Dim.Fill () }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + var text = ustring.Empty; + int maxWidth = 1; + int expectedClippedWidth = 1; - frame.Add (label); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); + List wrappedLines; - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, width, height + 1), label.Frame); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); + 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); - var expected = @" -┌───┐ -│A │ -│sen│ -│ten│ -│ce │ -│has│ -│ │ -│wor│ -│ds.│ -└───┘ -"; + 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); - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); - } + 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); - [Fact, AutoInitShutdown] - public void WordWrap_preserveTrailingSpaces_Vertical_With_Simple_Runes () - { - var text = "A sentence has words."; - var width = 8; - var height = 3; - var wrappedLines = TextFormatter.WordWrap (text, height, true); - var breakLines = ""; - for (int i = 0; i < wrappedLines.Count; i++) breakLines += $"{wrappedLines [i]}{(i < wrappedLines.Count - 1 ? Environment.NewLine : string.Empty)}"; - var label = new Label (breakLines) { - TextDirection = TextDirection.TopBottom_LeftRight, - Width = Dim.Fill (), - Height = Dim.Fill () - }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + 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; - frame.Add (label); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); + //List wrappedLines; - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, width, height), label.Frame); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); + //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); - var expected = @" -┌────────┐ -│Astch wd│ -│ eeea os│ -│ nn s r.│ -└────────┘ -"; + //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); - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); - } + //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); - [Fact, AutoInitShutdown] - public void WordWrap_preserveTrailingSpaces_Horizontal_With_Wide_Runes () - { - var text = "文に は言葉 があり ます。"; - var width = 6; - var height = 8; - var wrappedLines = TextFormatter.WordWrap (text, width, true); - var breakLines = ""; - foreach (var line in wrappedLines) breakLines += $"{line}{Environment.NewLine}"; - var label = new Label (breakLines) { Width = Dim.Fill (), Height = Dim.Fill () }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; - - frame.Add (label); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); - - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, width, height), label.Frame); - Assert.Equal (new Size (width, height), label.TextFormatter.Size); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); - - var expected = @" -┌──────┐ -│文に │ -│は言葉│ -│ があ │ -│り ま │ -│す。 │ -│ │ -│ │ -│ │ -└──────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); - } - - [Fact, AutoInitShutdown] - public void WordWrap_preserveTrailingSpaces_Vertical_With_Wide_Runes () - { - var text = "文に は言葉 があり ます。"; - var width = 8; - var height = 4; - var wrappedLines = TextFormatter.WordWrap (text, width, true); - var breakLines = ""; - for (int i = 0; i < wrappedLines.Count; i++) breakLines += $"{wrappedLines [i]}{(i < wrappedLines.Count - 1 ? Environment.NewLine : string.Empty)}"; - var label = new Label (breakLines) { - TextDirection = TextDirection.TopBottom_LeftRight, - Width = Dim.Fill (), - Height = Dim.Fill () - }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; - - frame.Add (label); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); - - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, width, height), label.Frame); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); - - var expected = @" -┌────────┐ -│文言あす│ -│に葉り。│ -│ │ -│はがま │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); + //maxWidth = 1; + //expectedClippedWidth = 0; + //wrappedLines = TextFormatter.WordWrapText (text, maxWidth, false); + //Assert.Empty (wrappedLines); } [Fact] - public void WordWrap_preserveTrailingSpaces_With_Tab () + 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); + 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; + Assert.Equal (expected, breakLines); + + // Double space Complex example - this is how VS 2022 does it + //text = "A sentence has words. "; + //breakLines = ""; + //wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: true); + //foreach (var line in wrappedLines) { + // breakLines += $"{line}{Environment.NewLine}"; + //} + //expected = "A " + Environment.NewLine + + // " se" + Environment.NewLine + + // " nt" + Environment.NewLine + + // " en" + Environment.NewLine + + // " ce" + Environment.NewLine + + // " " + Environment.NewLine + + // " " + Environment.NewLine + + // " " + Environment.NewLine + + // " ha" + Environment.NewLine + + // " s " + Environment.NewLine + + // " wo" + Environment.NewLine + + // " rd" + Environment.NewLine + + // " s." + Environment.NewLine; + //Assert.Equal (expected, breakLines); + } + + [Fact] + public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_1 () + { + // 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; + 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}"; + } + 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 () + { + // Empty input + string text = null; + var width = 50; + 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}"; + } + 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 () { var text = ustring.Empty; int maxWidth = 1; @@ -2319,7 +3046,7 @@ namespace Terminal.Gui.TextTests { var tabWidth = 4; maxWidth = 14; expectedClippedWidth = 11; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true, tabWidth); + 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 ()); @@ -2328,7 +3055,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 8; expectedClippedWidth = 8; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true, tabWidth); + 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 ()); @@ -2340,7 +3067,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 3; expectedClippedWidth = 3; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true, tabWidth); + 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 ()); @@ -2358,7 +3085,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 2; expectedClippedWidth = 2; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true, tabWidth); + 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 ()); @@ -2378,7 +3105,7 @@ namespace Terminal.Gui.TextTests { maxWidth = 1; expectedClippedWidth = 1; - wrappedLines = TextFormatter.WordWrap (text, maxWidth, true, tabWidth); + 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 ()); @@ -2403,7 +3130,7 @@ namespace Terminal.Gui.TextTests { { ustring text = "これが最初の行です。 こんにちは世界。 これが2行目です。"; var width = text.RuneCount; - var wrappedLines = TextFormatter.WordWrap (text, width); + var wrappedLines = TextFormatter.WordWrapText (text, width); Assert.Equal (3, wrappedLines.Count); Assert.Equal ("これが最初の行です。", wrappedLines [0].ToString ()); Assert.Equal ("こんにちは世界。", wrappedLines [1].ToString ()); @@ -2868,7 +3595,7 @@ namespace Terminal.Gui.TextTests { } [Fact] - public void Format_WordWrap_preserveTrailingSpaces () + public void Format_WordWrap_PreserveTrailingSpaces () { ustring text = " A sentence has words. \n This is the second Line - 2. "; @@ -2889,7 +3616,7 @@ namespace Terminal.Gui.TextTests { 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); + Assert.Equal (" Asentencehaswords. This isthesecondLine- 2.", wrappedText1.ToString ()); // With preserveTrailingSpaces = true. var list2 = TextFormatter.Format (text, 4, TextAlignment.Left, true, true); @@ -2911,7 +3638,7 @@ namespace Terminal.Gui.TextTests { 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); + Assert.Equal (" A sentence has words. This is the second Line - 2. ", wrappedText2.ToString ()); } [Fact] @@ -2923,7 +3650,7 @@ namespace Terminal.Gui.TextTests { - [Fact, AutoInitShutdown] + [Fact] public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Horizontal () { ustring text = "Hello world, how are you today? Pretty neat!"; @@ -2938,7 +3665,7 @@ namespace Terminal.Gui.TextTests { } } - [Fact, AutoInitShutdown] + [Fact] public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Vertical () { ustring text = "Hello world, how are you today? Pretty neat!"; @@ -2953,33 +3680,6 @@ namespace Terminal.Gui.TextTests { } } - [Fact] - public void Draw_Horizontal_Throws_IndexOutOfRangeException_With_Negative_Bounds () - { - Application.Init (new FakeDriver ()); - - var top = Application.Top; - - var view = new View ("view") { X = -2 }; - top.Add (view); - - Application.Iteration += () => { - Assert.Equal (-2, view.X); - - Application.RequestStop (); - }; - - try { - Application.Run (); - } catch (IndexOutOfRangeException ex) { - // After the fix this exception will not be caught. - Assert.IsType (ex); - } - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - } - [Fact] public void TestClipOrPad_ShortWord () { @@ -2993,36 +3693,6 @@ namespace Terminal.Gui.TextTests { // word is long but we want it to fill 3 space only Assert.Equal ("123", TextFormatter.ClipOrPad ("123456789", 3)); } - [Fact] - public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds () - { - Application.Init (new FakeDriver ()); - - var top = Application.Top; - - var view = new View ("view") { - Y = -2, - Height = 10, - TextDirection = TextDirection.TopBottom_LeftRight - }; - top.Add (view); - - Application.Iteration += () => { - Assert.Equal (-2, view.Y); - - Application.RequestStop (); - }; - - try { - Application.Run (); - } catch (IndexOutOfRangeException ex) { - // After the fix this exception will not be caught. - Assert.IsType (ex); - } - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - } [Fact] public void Internal_Tests () @@ -3033,363 +3703,6 @@ namespace Terminal.Gui.TextTests { Assert.Equal (Key.CtrlMask | Key.Q, tf.HotKey); } - [Fact, AutoInitShutdown] - public void Draw_Horizontal_Simple_Runes () - { - var label = new Label ("Demo Simple Rune"); - Application.Top.Add (label); - Application.Begin (Application.Top); - - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, 16, 1), label.Frame); - - var expected = @" -Demo Simple Rune -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 16, 1), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Vertical_Simple_Runes () - { - var label = new Label ("Demo Simple Rune") { - TextDirection = TextDirection.TopBottom_LeftRight - }; - Application.Top.Add (label); - Application.Begin (Application.Top); - - Assert.NotNull (label.Width); - Assert.NotNull (label.Height); - - var expected = @" -D -e -m -o - -S -i -m -p -l -e - -R -u -n -e -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 1, 16), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Horizontal_Wide_Runes () - { - var label = new Label ("デモエムポンズ"); - Application.Top.Add (label); - Application.Begin (Application.Top); - - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, 14, 1), label.Frame); - - var expected = @" -デモエムポンズ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 14, 1), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Vertical_Wide_Runes () - { - var label = new Label ("デモエムポンズ") { - TextDirection = TextDirection.TopBottom_LeftRight - }; - Application.Top.Add (label); - Application.Begin (Application.Top); - - var expected = @" -デ -モ -エ -ム -ポ -ン -ズ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 2, 7), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Vertical_Wide_Runes_With_ForceValidatePosDim () - { - var label = new Label ("デモエムポンズ") { - Width = Dim.Fill (), - Height = Dim.Percent (50f), - TextDirection = TextDirection.TopBottom_LeftRight, - ForceValidatePosDim = true - }; - Application.Top.Add (label); - Application.Begin (Application.Top); - - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, 80, 12), label.Frame); - - var expected = @" -デ -モ -エ -ム -ポ -ン -ズ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 2, 7), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Horizontal_Simple_TextAlignments () - { - var text = "Hello World"; - var width = 20; - var lblLeft = new Label (text) { Width = width }; - var lblCenter = new Label (text) { Y = 1, Width = width, TextAlignment = TextAlignment.Centered }; - var lblRight = new Label (text) { Y = 2, Width = width, TextAlignment = TextAlignment.Right }; - var lblJust = new Label (text) { Y = 3, Width = width, TextAlignment = TextAlignment.Justified }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; - - frame.Add (lblLeft, lblCenter, lblRight, lblJust); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 6); - - Assert.True (lblLeft.AutoSize); - Assert.True (lblCenter.AutoSize); - Assert.True (lblRight.AutoSize); - Assert.True (lblJust.AutoSize); - Assert.Equal (new Rect (0, 0, width, 1), lblLeft.Frame); - Assert.Equal (new Rect (0, 1, width, 1), lblCenter.Frame); - Assert.Equal (new Rect (0, 2, width, 1), lblRight.Frame); - Assert.Equal (new Rect (0, 3, width, 1), lblJust.Frame); - Assert.Equal (new Rect (0, 0, width + 2, 6), frame.Frame); - - var expected = @" -┌────────────────────┐ -│Hello World │ -│ Hello World │ -│ Hello World│ -│Hello World│ -└────────────────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, width + 2, 6), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Vertical_Simple_TextAlignments () - { - var text = "Hello World"; - var height = 20; - var lblLeft = new Label (text, direction: TextDirection.TopBottom_LeftRight) { Height = height }; - var lblCenter = new Label (text, direction: TextDirection.TopBottom_LeftRight) { X = 2, Height = height, VerticalTextAlignment = VerticalTextAlignment.Middle }; - var lblRight = new Label (text, direction: TextDirection.TopBottom_LeftRight) { X = 4, Height = height, VerticalTextAlignment = VerticalTextAlignment.Bottom }; - var lblJust = new Label (text, direction: TextDirection.TopBottom_LeftRight) { X = 6, Height = height, VerticalTextAlignment = VerticalTextAlignment.Justified }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; - - frame.Add (lblLeft, lblCenter, lblRight, lblJust); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (9, height + 2); - - Assert.True (lblLeft.AutoSize); - Assert.True (lblCenter.AutoSize); - Assert.True (lblRight.AutoSize); - Assert.True (lblJust.AutoSize); - Assert.Equal (new Rect (0, 0, 1, height), lblLeft.Frame); - Assert.Equal (new Rect (2, 0, 1, height), lblCenter.Frame); - Assert.Equal (new Rect (4, 0, 1, height), lblRight.Frame); - Assert.Equal (new Rect (6, 0, 1, height), lblJust.Frame); - Assert.Equal (new Rect (0, 0, 9, height + 2), frame.Frame); - - var expected = @" -┌───────┐ -│H H│ -│e e│ -│l l│ -│l l│ -│o H o│ -│ e │ -│W l │ -│o l │ -│r o │ -│l H │ -│d W e │ -│ o l │ -│ r l │ -│ l o │ -│ d │ -│ W W│ -│ o o│ -│ r r│ -│ l l│ -│ d d│ -└───────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 9, height + 2), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Horizontal_Wide_TextAlignments () - { - var text = "こんにちは 世界"; - var width = 25; - var lblLeft = new Label (text) { Width = width }; - var lblCenter = new Label (text) { Y = 1, Width = width, TextAlignment = TextAlignment.Centered }; - var lblRight = new Label (text) { Y = 2, Width = width, TextAlignment = TextAlignment.Right }; - var lblJust = new Label (text) { Y = 3, Width = width, TextAlignment = TextAlignment.Justified }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; - - frame.Add (lblLeft, lblCenter, lblRight, lblJust); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 6); - - Assert.True (lblLeft.AutoSize); - Assert.True (lblCenter.AutoSize); - Assert.True (lblRight.AutoSize); - Assert.True (lblJust.AutoSize); - Assert.Equal (new Rect (0, 0, width, 1), lblLeft.Frame); - Assert.Equal (new Rect (0, 1, width, 1), lblCenter.Frame); - Assert.Equal (new Rect (0, 2, width, 1), lblRight.Frame); - Assert.Equal (new Rect (0, 3, width, 1), lblJust.Frame); - Assert.Equal (new Rect (0, 0, width + 2, 6), frame.Frame); - - var expected = @" -┌─────────────────────────┐ -│こんにちは 世界 │ -│ こんにちは 世界 │ -│ こんにちは 世界│ -│こんにちは 世界│ -└─────────────────────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, width + 2, 6), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Vertical_Wide_TextAlignments () - { - var text = "こんにちは 世界"; - var height = 23; - var lblLeft = new Label (text) { Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight }; - var lblCenter = new Label (text) { X = 3, Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight, VerticalTextAlignment = VerticalTextAlignment.Middle }; - var lblRight = new Label (text) { X = 6, Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight, VerticalTextAlignment = VerticalTextAlignment.Bottom }; - var lblJust = new Label (text) { X = 9, Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight, VerticalTextAlignment = VerticalTextAlignment.Justified }; - var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; - - frame.Add (lblLeft, lblCenter, lblRight, lblJust); - Application.Top.Add (frame); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (13, height + 2); - - // All AutoSize are false because the Frame.Height != TextFormatter.Size.Height - Assert.True (lblLeft.AutoSize); - Assert.True (lblCenter.AutoSize); - Assert.True (lblRight.AutoSize); - Assert.True (lblJust.AutoSize); - Assert.Equal (new Rect (0, 0, 2, height), lblLeft.Frame); - Assert.Equal (new Rect (3, 0, 2, height), lblCenter.Frame); - Assert.Equal (new Rect (6, 0, 2, height), lblRight.Frame); - Assert.Equal (new Rect (9, 0, 2, height), lblJust.Frame); - Assert.Equal (new Rect (0, 0, 13, height + 2), frame.Frame); - - var expected = @" -┌───────────┐ -│こ こ│ -│ん ん│ -│に に│ -│ち ち│ -│は は│ -│ │ -│世 │ -│界 こ │ -│ ん │ -│ に │ -│ ち │ -│ は │ -│ │ -│ 世 │ -│ 界 │ -│ こ │ -│ ん │ -│ に │ -│ ち │ -│ は │ -│ │ -│ 世 世│ -│ 界 界│ -└───────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 13, height + 2), pos); - } - - [Fact, AutoInitShutdown] - public void Draw_Fill_Remaining () - { - var view = new View ("This view needs to be cleared before rewritten."); - - var tf1 = new TextFormatter (); - tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten."; - var tf1Size = tf1.Size; - - var tf2 = new TextFormatter (); - tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten."; - var tf2Size = tf2.Size; - - Application.Top.Add (view); - Application.Begin (Application.Top); - - tf1.Draw (new Rect (new Point (0, 1), tf1Size), view.GetNormalColor (), view.ColorScheme.HotNormal, default, false); - - tf2.Draw (new Rect (new Point (0, 2), tf2Size), view.GetNormalColor (), view.ColorScheme.HotNormal); - - TestHelpers.AssertDriverContentsWithFrameAre (@" -This view needs to be cleared before rewritten. -This TextFormatter (tf1) without fill will not be cleared on rewritten. -This TextFormatter (tf2) with fill will be cleared on rewritten. -", output); - - view.Text = "This view is rewritten."; - view.Redraw (view.Bounds); - - tf1.Text = "This TextFormatter (tf1) is rewritten."; - tf1.Draw (new Rect (new Point (0, 1), tf1Size), view.GetNormalColor (), view.ColorScheme.HotNormal, default, false); - - tf2.Text = "This TextFormatter (tf2) is rewritten."; - tf2.Draw (new Rect (new Point (0, 2), tf2Size), view.GetNormalColor (), view.ColorScheme.HotNormal); - - TestHelpers.AssertDriverContentsWithFrameAre (@" -This view is rewritten. -This TextFormatter (tf1) is rewritten.will not be cleared on rewritten. -This TextFormatter (tf2) is rewritten. -", output); - } - [Fact] public void GetTextWidth_Simple_And_Wide_Runes () { @@ -3422,23 +3735,70 @@ This TextFormatter (tf2) is rewritten. } [Fact] - public void GetMaxLengthForWidth_Simple_And_Wide_Runes () + public void GetLengthThatFits_runelist () { - ustring text = "Hello World"; - Assert.Equal (6, TextFormatter.GetMaxLengthForWidth (text, 6)); - text = "こんにちは 世界"; - Assert.Equal (3, TextFormatter.GetMaxLengthForWidth (text, 6)); + 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)); } [Fact] - public void GetMaxLengthForWidth_List_Simple_And_Wide_Runes () + public void GetLengthThatFits_ustring () + { + 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)); + } + + + [Fact] + public void GetLengthThatFits_Simple_And_Wide_Runes () + { + ustring text = "Hello World"; + Assert.Equal (6, TextFormatter.GetLengthThatFits (text, 6)); + text = "こんにちは 世界"; + Assert.Equal (3, TextFormatter.GetLengthThatFits (text, 6)); + } + + [Fact] + public void GetLengthThatFits_List_Simple_And_Wide_Runes () { var runes = ustring.Make ("Hello World").ToRuneList (); - Assert.Equal (6, TextFormatter.GetMaxLengthForWidth (runes, 6)); + Assert.Equal (6, TextFormatter.GetLengthThatFits (runes, 6)); runes = ustring.Make ("こんにちは 世界").ToRuneList (); - Assert.Equal (3, TextFormatter.GetMaxLengthForWidth (runes, 6)); + Assert.Equal (3, TextFormatter.GetLengthThatFits (runes, 6)); runes = ustring.Make ("[ Say Hello 你 ]").ToRuneList (); - Assert.Equal (15, TextFormatter.GetMaxLengthForWidth (runes, 16)); + Assert.Equal (15, TextFormatter.GetLengthThatFits (runes, 16)); } [Fact] @@ -3453,603 +3813,7 @@ This TextFormatter (tf2) is rewritten. Assert.Equal ("デ", list [^1].ToString ()); } - [Fact, AutoInitShutdown] - public void AutoSize_False_View_IsEmpty_False_Return_Null_Lines () - { - var text = "Views"; - var view = new View () { - Width = Dim.Fill () - text.Length, - Height = 1, - Text = text - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (view); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - Assert.Equal (5, text.Length); - 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 Rect (0, 0, 10, 4), win.Frame); - Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); - var expected = @" -┌────────┐ -│Vie │ -│ │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - view.Width = Dim.Fill () - text.Length; - Application.Refresh (); - - 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); - expected = @" -┌────────┐ -│ │ -│ │ -└────────┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_False_View_IsEmpty_True_Minimum_Height () - { - var text = "Views"; - var view = new View () { - Width = Dim.Fill () - text.Length, - Text = text - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (view); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - Assert.Equal (5, text.Length); - Assert.False (view.AutoSize); - Assert.Equal (new Rect (0, 0, 3, 1), view.Frame); - Assert.Equal (new Size (3, 1), view.TextFormatter.Size); - Assert.Single (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 = @" -┌────────┐ -│Vie │ -│ │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - view.Width = Dim.Fill () - text.Length; - Application.Refresh (); - - 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)); - Assert.Null (exception); - expected = @" -┌────────┐ -│ │ -│ │ -└────────┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_True_Label_IsEmpty_False_Never_Return_Null_Lines () - { - var text = "Label"; - var label = new Label () { - Width = Dim.Fill () - text.Length, - Height = 1, - Text = text - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (label); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - Assert.Equal (5, text.Length); - 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 Rect (0, 0, 10, 4), win.Frame); - Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); - var expected = @" -┌────────┐ -│Label │ -│ │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - label.Width = Dim.Fill () - text.Length; - Application.Refresh (); - - Assert.True (label.AutoSize); - Assert.Equal (new Rect (0, 0, 5, 1), label.Frame); - Assert.Equal (new Size (5, 1), label.TextFormatter.Size); - Assert.Single (label.TextFormatter.Lines); - expected = @" -┌────────┐ -│Label │ -│ │ -└────────┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_False_Label_IsEmpty_True_Return_Null_Lines () - { - var text = "Label"; - var label = new Label () { - Width = Dim.Fill () - text.Length, - Height = 1, - Text = text, - AutoSize = false - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (label); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - Assert.Equal (5, text.Length); - 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 Rect (0, 0, 10, 4), win.Frame); - Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); - var expected = @" -┌────────┐ -│Lab │ -│ │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - label.Width = Dim.Fill () - text.Length; - Application.Refresh (); - - 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); - expected = @" -┌────────┐ -│ │ -│ │ -└────────┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_True_Label_IsEmpty_False_Minimum_Height () - { - var text = "Label"; - var label = new Label () { - Width = Dim.Fill () - text.Length, - Text = text - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (label); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - Assert.Equal (5, text.Length); - 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 Rect (0, 0, 10, 4), win.Frame); - Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); - var expected = @" -┌────────┐ -│Label │ -│ │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - label.Width = Dim.Fill () - text.Length; - Application.Refresh (); - - Assert.Equal (new Rect (0, 0, 5, 1), label.Frame); - Assert.Equal (new Size (5, 1), label.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Single (label.TextFormatter.Lines)); - Assert.Null (exception); - expected = @" -┌────────┐ -│Label │ -│ │ -└────────┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_False_Label_Height_Zero_Returns_Minimum_Height () - { - var text = "Label"; - var label = new Label () { - Width = Dim.Fill () - text.Length, - Text = text, - AutoSize = false - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (label); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - Assert.Equal (5, text.Length); - Assert.False (label.AutoSize); - Assert.Equal (new Rect (0, 0, 3, 1), label.Frame); - Assert.Equal (new Size (3, 1), label.TextFormatter.Size); - Assert.Single (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 = @" -┌────────┐ -│Lab │ -│ │ -└────────┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - label.Width = Dim.Fill () - text.Length; - Application.Refresh (); - - 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)); - Assert.Null (exception); - expected = @" -┌────────┐ -│ │ -│ │ -└────────┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 10, 4), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_True_View_IsEmpty_False_Minimum_Width () - { - var text = "Views"; - var view = new View () { - TextDirection = TextDirection.TopBottom_LeftRight, - Height = Dim.Fill () - text.Length, - Text = text, - AutoSize = true - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (view); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (4, 10); - - Assert.Equal (5, text.Length); - 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 Rect (0, 0, 4, 10), win.Frame); - Assert.Equal (new Rect (0, 0, 4, 10), Application.Top.Frame); - var expected = @" -┌──┐ -│V │ -│i │ -│e │ -│w │ -│s │ -│ │ -│ │ -│ │ -└──┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - view.Height = Dim.Fill () - text.Length; - Application.Refresh (); - - Assert.Equal (new Rect (0, 0, 1, 5), view.Frame); - Assert.Equal (new Size (1, 5), view.TextFormatter.Size); - var exception = Record.Exception (() => Assert.Single (view.TextFormatter.Lines)); - Assert.Null (exception); - expected = @" -┌──┐ -│V │ -│i │ -│e │ -│w │ -│s │ -│ │ -│ │ -│ │ -└──┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_False_View_Width_Null_Returns_Host_Frame_Width () - { - var text = "Views"; - var view = new View () { - TextDirection = TextDirection.TopBottom_LeftRight, - Height = Dim.Fill () - text.Length, - Text = text - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (view); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (4, 10); - - Assert.Equal (5, text.Length); - Assert.False (view.AutoSize); - Assert.Equal (new Rect (0, 0, 1, 3), view.Frame); - Assert.Equal (new Size (1, 3), view.TextFormatter.Size); - Assert.Single (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 = @" -┌──┐ -│V │ -│i │ -│e │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - view.Height = Dim.Fill () - text.Length; - Application.Refresh (); - - 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)); - Assert.Null (exception); - expected = @" -┌──┐ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_True_View_IsEmpty_False_Minimum_Width_Wide_Rune () - { - var text = "界View"; - var view = new View () { - TextDirection = TextDirection.TopBottom_LeftRight, - Height = Dim.Fill () - text.Length, - Text = text, - AutoSize = true - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (view); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (4, 10); - - Assert.Equal (5, text.Length); - 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 Rect (0, 0, 4, 10), win.Frame); - Assert.Equal (new Rect (0, 0, 4, 10), Application.Top.Frame); - var expected = @" -┌──┐ -│界│ -│V │ -│i │ -│e │ -│w │ -│ │ -│ │ -│ │ -└──┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - view.Height = Dim.Fill () - text.Length; - Application.Refresh (); - - 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)); - Assert.Null (exception); - expected = @" -┌──┐ -│界│ -│V │ -│i │ -│e │ -│w │ -│ │ -│ │ -│ │ -└──┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - } - - [Fact, AutoInitShutdown] - public void AutoSize_False_View_Width_Zero_Returns_Minimum_Width_With_Wide_Rune () - { - var text = "界View"; - var view = new View () { - TextDirection = TextDirection.TopBottom_LeftRight, - Height = Dim.Fill () - text.Length, - Text = text - }; - var win = new Window () { - Width = Dim.Fill (), - Height = Dim.Fill () - }; - win.Add (view); - Application.Top.Add (win); - Application.Begin (Application.Top); - ((FakeDriver)Application.Driver).SetBufferSize (4, 10); - - Assert.Equal (5, text.Length); - Assert.False (view.AutoSize); - Assert.Equal (new Rect (0, 0, 2, 3), view.Frame); - Assert.Equal (new Size (2, 3), view.TextFormatter.Size); - Assert.Single (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 = @" -┌──┐ -│界│ -│V │ -│i │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──┘ -"; - - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - view.Height = Dim.Fill () - text.Length; - Application.Refresh (); - - 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)); - Assert.Null (exception); - expected = @" -┌──┐ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──┘ -"; - - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (0, 0, 4, 10), pos); - } [Fact] public void Format_With_PreserveTrailingSpaces_And_Without_PreserveTrailingSpaces () @@ -4058,15 +3822,15 @@ This TextFormatter (tf2) is rewritten. var width = 60; var preserveTrailingSpaces = false; var formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces); - Assert.Equal ("Line1", formated [0]); - Assert.Equal ("Line2", formated [1]); - Assert.Equal ("Line3", formated [^1]); + Assert.Equal ("Line1", formated [0].ToString ()); + Assert.Equal ("Line2", formated [1].ToString ()); + Assert.Equal ("Line3", formated [^1].ToString ()); preserveTrailingSpaces = true; formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces); - Assert.Equal ("Line1", formated [0]); - Assert.Equal ("Line2", formated [1]); - Assert.Equal ("Line3", formated [^1]); + Assert.Equal ("Line1", formated [0].ToString ()); + Assert.Equal ("Line2", formated [1].ToString ()); + Assert.Equal ("Line3", formated [^1].ToString ()); } [Fact] @@ -4146,328 +3910,5 @@ This TextFormatter (tf2) is rewritten. Assert.Equal ("你", ((Rune)usToRunes [9]).ToString ()); Assert.Equal ("你", s [9].ToString ()); } - - [Fact, AutoInitShutdown] - public void Non_Bmp_ConsoleWidth_ColumnWidth_Equal_Two () - { - ustring us = "\U0001d539"; - Rune r = 0x1d539; - - Assert.Equal ("𝔹", us); - Assert.Equal ("𝔹", r.ToString ()); - Assert.Equal (us, r.ToString ()); - - Assert.Equal (2, us.ConsoleWidth); - Assert.Equal (2, Rune.ColumnWidth (r)); - - var win = new Window (us); - var label = new Label (ustring.Make (r)); - var tf = new TextField (us) { Y = 1, Width = 3 }; - win.Add (label, tf); - var top = Application.Top; - top.Add (win); - - Application.Begin (top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - var expected = @" -┌┤𝔹├────┐ -│𝔹 │ -│𝔹 │ -└────────┘"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - - TestHelpers.AssertDriverContentsAre (expected, output); - - var expectedColors = new Attribute [] { - // 0 - Colors.Base.Normal, - // 1 - Colors.Base.Focus, - // 2 - Colors.Base.HotNormal - }; - - TestHelpers.AssertDriverColorsAre (@" -0022000000 -0000000000 -0111000000 -0000000000", expectedColors); - } - - [Fact, AutoInitShutdown] - public void CJK_Compatibility_Ideographs_ConsoleWidth_ColumnWidth_Equal_Two () - { - ustring us = "\U0000f900"; - Rune r = 0xf900; - - Assert.Equal ("豈", us); - Assert.Equal ("豈", r.ToString ()); - Assert.Equal (us, r.ToString ()); - - Assert.Equal (2, us.ConsoleWidth); - Assert.Equal (2, Rune.ColumnWidth (r)); - - var win = new Window (us); - var label = new Label (ustring.Make (r)); - var tf = new TextField (us) { Y = 1, Width = 3 }; - win.Add (label, tf); - var top = Application.Top; - top.Add (win); - - Application.Begin (top); - ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - - var expected = @" -┌┤豈├────┐ -│豈 │ -│豈 │ -└────────┘"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - - TestHelpers.AssertDriverContentsAre (expected, output); - - var expectedColors = new Attribute [] { - // 0 - Colors.Base.Normal, - // 1 - Colors.Base.Focus, - // 2 - Colors.Base.HotNormal - }; - - TestHelpers.AssertDriverColorsAre (@" -0022000000 -0000000000 -0111000000 -0000000000", expectedColors); - } - - [Fact, AutoInitShutdown] - public void Colors_On_TextAlignment_Right_And_Bottom () - { - var labelRight = new Label ("Test") { - Width = 6, - Height = 1, - TextAlignment = TextAlignment.Right, - ColorScheme = Colors.Base - }; - var labelBottom = new Label ("Test", TextDirection.TopBottom_LeftRight) { - Y = 1, - Width = 1, - Height = 6, - VerticalTextAlignment = VerticalTextAlignment.Bottom, - ColorScheme = Colors.Base - }; - var top = Application.Top; - top.Add (labelRight, labelBottom); - - Application.Begin (top); - ((FakeDriver)Application.Driver).SetBufferSize (7, 7); - - TestHelpers.AssertDriverContentsWithFrameAre (@" - Test - - -T -e -s -t ", output); - - TestHelpers.AssertDriverColorsAre (@" -000000 -0 -0 -0 -0 -0 -0", new Attribute [] { Colors.Base.Normal }); - } - - [Fact, AutoInitShutdown] - public void Draw_Negative_Bounds_Horizontal_Without_New_Lines () - { - // BUGBUG: This previously assumed the default height of a View was 1. - var subView = new View () { Id = "subView", Y = 1, Width = 7, Height = 1, Text = "subView" }; - var view = new View () { Id = "view", Width = 20, Height = 2, Text = "01234567890123456789" }; - view.Add (subView); - var content = new View () { Id = "content", Width = 20, Height = 20 }; - content.Add (view); - var container = new View () { Id = "container", X = 1, Y = 1, Width = 5, Height = 5 }; - container.Add (content); - var top = Application.Top; - top.Add (container); - // BUGBUG: v2 - it's bogus to reference .Frame before BeginInit. And why is the clip being set anyway??? - - void Top_LayoutComplete (object sender, LayoutEventArgs e) - { - Application.Driver.Clip = container.Frame; - } - top.LayoutComplete += Top_LayoutComplete; - Application.Begin (top); - - TestHelpers.AssertDriverContentsWithFrameAre (@" - 01234 - subVi", output); - - content.X = -1; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 12345 - ubVie", output); - - content.Y = -1; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - ubVie", output); - - content.Y = -2; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); - - content.X = -20; - content.Y = 0; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); - } - - - [Fact, AutoInitShutdown] - public void Draw_Negative_Bounds_Horizontal_With_New_Lines () - { - var subView = new View () { Id = "subView", X = 1, Width = 1, Height = 7, Text = "s\nu\nb\nV\ni\ne\nw" }; - var view = new View () { Id = "view", Width = 2, Height = 20, Text = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n6\n7\n8\n9" }; - view.Add (subView); - var content = new View () { Id = "content", Width = 20, Height = 20 }; - content.Add (view); - var container = new View () { Id = "container", X = 1, Y = 1, Width = 5, Height = 5 }; - container.Add (content); - var top = Application.Top; - top.Add (container); - Application.Driver.Clip = container.Frame; - Application.Begin (top); - - TestHelpers.AssertDriverContentsWithFrameAre (@" - 0s - 1u - 2b - 3V - 4i", output); - - content.X = -1; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - s - u - b - V - i", output); - - content.X = -2; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@"", output); - - content.X = 0; - content.Y = -1; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 1u - 2b - 3V - 4i - 5e", output); - - content.Y = -6; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 6w - 7 - 8 - 9 - 0 ", output); - - content.Y = -19; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 9", output); - - content.Y = -20; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); - - content.X = -2; - content.Y = 0; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); - } - - [Fact, AutoInitShutdown] - public void Draw_Negative_Bounds_Vertical () - { - var subView = new View () { Id = "subView", X = 1, Width = 1, Height = 7, Text = "subView", TextDirection = TextDirection.TopBottom_LeftRight }; - var view = new View () { Id = "view", Width = 2, Height = 20, Text = "01234567890123456789", TextDirection = TextDirection.TopBottom_LeftRight }; - view.Add (subView); - var content = new View () { Id = "content", Width = 20, Height = 20 }; - content.Add (view); - var container = new View () { Id = "container", X = 1, Y = 1, Width = 5, Height = 5 }; - container.Add (content); - var top = Application.Top; - top.Add (container); - Application.Driver.Clip = container.Frame; - Application.Begin (top); - - TestHelpers.AssertDriverContentsWithFrameAre (@" - 0s - 1u - 2b - 3V - 4i", output); - - content.X = -1; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - s - u - b - V - i", output); - - content.X = -2; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@"", output); - - content.X = 0; - content.Y = -1; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 1u - 2b - 3V - 4i - 5e", output); - - content.Y = -6; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 6w - 7 - 8 - 9 - 0 ", output); - - content.Y = -19; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre (@" - 9", output); - - content.Y = -20; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); - - content.X = -2; - content.Y = 0; - Application.Refresh (); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); - } } } \ No newline at end of file diff --git a/UnitTests/Text/UnicodeTests.cs b/UnitTests/Text/UnicodeTests.cs index 61041a47a..5292875d0 100644 --- a/UnitTests/Text/UnicodeTests.cs +++ b/UnitTests/Text/UnicodeTests.cs @@ -57,21 +57,21 @@ namespace Terminal.Gui.TextTests { これは広いルーンラインです。 これは広いルーンラインです。" }; - var win = new Window ("ワイドルーン") { Width = Dim.Fill (), Height = Dim.Fill () }; + 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 ("テスト", 14, 4, new Button ("選ぶ")); + 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 = @" -┌┤ワイドルーン├──────────────┐ +┌────────────────────────────┐ │これは広いルーンラインです。│ │これは広いルーンラインです。│ -│これは ┌┤テスト├────┐ です。│ +│これは ┌────────────┐ です。│ │これは │ワイドルーン│ です。│ │これは │ [ 選ぶ ] │ です。│ │これは └────────────┘ です。│ diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 069215d37..27708422b 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -222,7 +222,8 @@ namespace UICatalog.Tests { .Select (t => new KeyValuePair (t.Name, t)) .ToDictionary (t => t.Key, t => t.Value); - _leftPane = new Window ("Classes") { + _leftPane = new Window () { + Title = "Classes", X = 0, Y = 0, Width = 15, @@ -327,7 +328,14 @@ namespace UICatalog.Tests { _settingsPane.SetFocus (); }; _classListView.SelectedItemChanged += (s, args) => { - ClearClass (_curView); + // Remove existing class, if any + if (_curView != null) { + _curView.LayoutComplete -= LayoutCompleteHandler; + _hostPane.Remove (_curView); + _curView.Dispose (); + _curView = null; + _hostPane.Clear (); + } _curView = CreateClass (_viewClasses.Values.ToArray () [_classListView.SelectedItem]); }; @@ -513,17 +521,6 @@ namespace UICatalog.Tests { return types; } - void ClearClass (View view) - { - // Remove existing class, if any - if (view != null) { - view.LayoutComplete -= LayoutCompleteHandler; - _hostPane.Remove (view); - view.Dispose (); - _hostPane.Clear (); - } - } - View CreateClass (Type type) { // If we are to create a generic Type diff --git a/UnitTests/View/BorderTests.cs b/UnitTests/View/BorderTests.cs index 61a607cba..2e959ff7f 100644 --- a/UnitTests/View/BorderTests.cs +++ b/UnitTests/View/BorderTests.cs @@ -1,8 +1,5 @@ -using System; -using System.Reflection.Emit; -using Xunit; +using Xunit; using Xunit.Abstractions; -using Rune = System.Rune; namespace Terminal.Gui.ViewTests { public class BorderTests { @@ -13,623 +10,34 @@ namespace Terminal.Gui.ViewTests { this.output = output; } - [Fact, AutoInitShutdown] - public void Constructor_Defaults () + [Fact] + public void View_BorderStyle_Defaults () { - var b = new Border (); - Assert.Equal (BorderStyle.None, b.BorderStyle); - Assert.False (b.DrawMarginFrame); - Assert.Equal (Thickness.Empty, b.BorderThickness); - Assert.Equal (Color.Black, b.ForgroundColor); - Assert.Equal (Color.Black, b.BackgroundColor); - Assert.Equal (Thickness.Empty, b.PaddingThickness); - Assert.False (b.Effect3D); - Assert.Equal (new Point (1, 1), b.Effect3DOffset); - Assert.Null (b.Effect3DBrush); + var view = new View (); + Assert.Equal (LineStyle.None, view.BorderStyle); + Assert.Equal (Thickness.Empty, view.BorderFrame.Thickness); + } + + [Fact] + public void View_SetBorderStyle () + { + var view = new View (); + view.BorderStyle = LineStyle.Single; + Assert.Equal (LineStyle.Single, view.BorderStyle); + Assert.Equal (new Thickness(1), view.BorderFrame.Thickness); + + view.BorderStyle = LineStyle.Double; + Assert.Equal (LineStyle.Double, view.BorderStyle); + Assert.Equal (new Thickness (1), view.BorderFrame.Thickness); + + view.BorderStyle = LineStyle.None; + Assert.Equal (LineStyle.None, view.BorderStyle); + Assert.Equal (Thickness.Empty, view.BorderFrame.Thickness); } //[Fact] - //public void BorderStyle_Different_None_Ensures_DrawMarginFrame_To_True () + //public void View_BorderStyleChanged () //{ - // var b = new Border () { - // BorderStyle = BorderStyle.Single, - // DrawMarginFrame = false - // }; - - // Assert.True (b.DrawMarginFrame); - - // b.BorderStyle = BorderStyle.None; - // Assert.True (b.DrawMarginFrame); - // b.DrawMarginFrame = false; - // Assert.False (b.DrawMarginFrame); - //} - - //[Fact, AutoInitShutdown] - // public void ActualWidth_ActualHeight () - // { - // var v = new View (new Rect (5, 10, 60, 20), "", new Border ()); - - //[Fact] - //public void ToplevelContainer_LayoutStyle_Computed_Constuctor_ () - //{ - // var tc = new Border.ToplevelContainer (new Border ()); - - // Assert.Equal (LayoutStyle.Computed, tc.LayoutStyle); - //} - - //[Fact] - //public void ToplevelContainer_LayoutStyle_Absolute_Constuctor_ () - //{ - // var tc = new Border.ToplevelContainer (new Rect (1, 2, 3, 4), new Border ()); - - // Assert.Equal (LayoutStyle.Absolute, tc.LayoutStyle); - //} - - //[Fact] - //public void GetSumThickness_Test () - //{ - // var b = new Border () { - // BorderThickness = new Thickness (1, 2, 3, 4), - // Padding = new Thickness (4, 3, 2, 1) - // }; - // Assert.Equal (new Thickness (5, 5, 5, 5), b.GetSumThickness ()); - //} - - //[Fact] - //[AutoInitShutdown] - //public void DrawContent_With_Child_Border () - //{ - // var top = Application.Top; - // var driver = (FakeDriver)Application.Driver; - - // [Fact] - // [AutoInitShutdown] - // public void DrawContent_With_Child_Border () - // { - // var top = Application.Top; - // var driver = (FakeDriver)Application.Driver; - - // top.LayoutSubviews (); - // label.Redraw (label.Bounds); - - // var frame = label.Frame; - // var drawMarginFrame = label.Border.DrawMarginFrame ? 1 : 0; - // var sumThickness = label.Border.GetSumThickness (); - // var padding = label.Border.Padding; - // var effect3DOffset = label.Border.Effect3DOffset; - // var borderStyle = label.Border.BorderStyle; - - // // Check the upper BorderThickness - // for (int r = frame.Y - drawMarginFrame - sumThickness.Top; - // r < frame.Y - drawMarginFrame - padding.Top; r++) { - // for (int c = frame.X - drawMarginFrame - sumThickness.Left; - // c < frame.Right + drawMarginFrame + sumThickness.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the left BorderThickness - // for (int r = frame.Y - drawMarginFrame - padding.Top; - // r < frame.Bottom + drawMarginFrame + padding.Bottom; r++) { - // for (int c = frame.X - drawMarginFrame - sumThickness.Left; - // c < frame.X - drawMarginFrame - padding.Left; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the right BorderThickness - // for (int r = frame.Y - drawMarginFrame - padding.Top; - // r < frame.Bottom + drawMarginFrame + padding.Bottom; r++) { - // for (int c = frame.Right + drawMarginFrame + padding.Right; - // c < frame.Right + drawMarginFrame - sumThickness.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the lower BorderThickness - // for (int r = frame.Bottom + drawMarginFrame + padding.Bottom; - // r < frame.Bottom + drawMarginFrame + sumThickness.Bottom; r++) { - // for (int c = frame.X - drawMarginFrame - sumThickness.Left; - // c < frame.Right + drawMarginFrame + sumThickness.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the upper Padding - // for (int r = frame.Y - drawMarginFrame - padding.Top; - // r < frame.Y - drawMarginFrame; r++) { - // for (int c = frame.X - drawMarginFrame - padding.Left; - // c < frame.Right + drawMarginFrame + padding.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.BrightGreen, color.Background); - // } - // } - - // // Check the left Padding - // for (int r = frame.Y - drawMarginFrame; - // r < frame.Bottom + drawMarginFrame; r++) { - // for (int c = frame.X - drawMarginFrame - padding.Left; - // c < frame.X - drawMarginFrame; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.BrightGreen, color.Background); - // } - // } - - // // Check the right Padding - // for (int r = frame.Y - drawMarginFrame; - // r < frame.Bottom + drawMarginFrame; r++) { - // for (int c = frame.Right + drawMarginFrame; - // c < frame.Right + drawMarginFrame - padding.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.BrightGreen, color.Background); - // } - // } - - // // Check the lower Padding - // for (int r = frame.Bottom + drawMarginFrame; - // r < frame.Bottom + drawMarginFrame + padding.Bottom; r++) { - // for (int c = frame.X - drawMarginFrame - padding.Left; - // c < frame.Right + drawMarginFrame + padding.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.BrightGreen, color.Background); - // } - // } - - // Rune hLine = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.HLine : (borderStyle == BorderStyle.Double ? driver.HDLine : ' ')) : ' '; - // Rune vLine = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.VLine : (borderStyle == BorderStyle.Double ? driver.VDLine : ' ')) : ' '; - // Rune uRCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.URCorner : (borderStyle == BorderStyle.Double ? driver.URDCorner : ' ')) : ' '; - // Rune uLCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.ULCorner : (borderStyle == BorderStyle.Double ? driver.ULDCorner : ' ')) : ' '; - // Rune lLCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.LLCorner : (borderStyle == BorderStyle.Double ? driver.LLDCorner : ' ')) : ' '; - // Rune lRCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.LRCorner : (borderStyle == BorderStyle.Double ? driver.LRDCorner : ' ')) : ' '; - - // var text = ""; - // // Check the MarginFrame - // for (int r = frame.Y - drawMarginFrame; - // r < frame.Bottom + drawMarginFrame; r++) { - // for (int c = frame.X - drawMarginFrame; - // c <= frame.Right + drawMarginFrame - 1; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // var rune = (Rune)driver.Contents [r, c, 0]; - // Assert.Equal (Color.Black, color.Background); - // if (c == frame.X - drawMarginFrame && r == frame.Y - drawMarginFrame) { - // Assert.Equal (uLCorner, rune); - // } else if (c == frame.Right && r == frame.Y - drawMarginFrame) { - // Assert.Equal (uRCorner, rune); - // } else if (c == frame.X - drawMarginFrame && r == frame.Bottom) { - // Assert.Equal (lLCorner, rune); - // } else if (c == frame.Right && r == frame.Bottom) { - // Assert.Equal (lRCorner, rune); - // } else if (c >= frame.X && (r == frame.Y - drawMarginFrame - // || r == frame.Bottom)) { - // Assert.Equal (hLine, rune); - // } else if ((c == frame.X - drawMarginFrame || c == frame.Right) - // && r >= frame.Y && r <= frame.Bottom - drawMarginFrame) { - // Assert.Equal (vLine, rune); - // } else { - // text += rune.ToString (); - // } - // } - // } - // Assert.Equal ("This is a test", text.Trim ()); - - // var color = (Attribute)driver.Contents [r, c, 1]; - // var rune = (Rune)driver.Contents [r, c, 0]; - // if (r == frame.Y - drawMarginFrame || r == frame.Bottom + drawMarginFrame - 1 - // || c == frame.X - drawMarginFrame || c == frame.Right + drawMarginFrame - 1) { - // Assert.Equal (Color.BrightGreen, color.Background); - // } else { - // Assert.Equal (Color.Black, color.Background); - // } - // if (c == frame.X - drawMarginFrame && r == frame.Y - drawMarginFrame) { - // Assert.Equal (uLCorner, rune); - // } else if (c == frame.Right && r == frame.Y - drawMarginFrame) { - // Assert.Equal (uRCorner, rune); - // } else if (c == frame.X - drawMarginFrame && r == frame.Bottom) { - // Assert.Equal (lLCorner, rune); - // } else if (c == frame.Right && r == frame.Bottom) { - // Assert.Equal (lRCorner, rune); - // } else if (c >= frame.X && (r == frame.Y - drawMarginFrame - // || r == frame.Bottom)) { - // Assert.Equal (hLine, rune); - // } else if ((c == frame.X - drawMarginFrame || c == frame.Right) - // && r >= frame.Y && r <= frame.Bottom - drawMarginFrame) { - // Assert.Equal (vLine, rune); - // } else { - // text += rune.ToString (); - // } - // } - // } - // Assert.Equal ("This is a test", text.Trim ()); - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.DarkGray, color.Background); - // } - // } - - // // Check the left Effect3D - // for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y; - // r < frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y; r++) { - // for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X; - // c < frame.X - drawMarginFrame - sumThickness.Left; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.DarkGray, color.Background); - // } - // } - - // // Check the right Effect3D - // for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y; - // r < frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y; r++) { - // for (int c = frame.Right + drawMarginFrame + sumThickness.Right; - // c < frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.DarkGray, color.Background); - // } - // } - - // // Check the lower Effect3D - // for (int r = frame.Bottom + drawMarginFrame + sumThickness.Bottom; - // r < frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y; r++) { - // for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X; - // c < frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.DarkGray, color.Background); - // } - // } - - // // Check the Child frame - // for (int r = frame.Y; r < frame.Y + frame.Height; r++) { - // for (int c = frame.X; c < frame.X + frame.Width; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.BrightGreen, color.Foreground); - // Assert.Equal (Color.Black, color.Background); - // } - // } - //} - - //[Fact] - //[AutoInitShutdown] - //public void DrawContent_With_Parent_Border () - //{ - // var top = Application.Top; - // var driver = (FakeDriver)Application.Driver; - - // [Fact] - // [AutoInitShutdown] - // public void DrawContent_With_Parent_Border () - // { - // var top = Application.Top; - // var driver = (FakeDriver)Application.Driver; - - // top.LayoutSubviews (); - // frameView.Redraw (frameView.Bounds); - - // var frame = frameView.Frame; - // var drawMarginFrame = frameView.Border.DrawMarginFrame ? 1 : 0; - // var borderThickness = frameView.Border.BorderThickness; - // var padding = frameView.Border.Padding; - - // var effect3DOffset = frameView.Border.Effect3DOffset; - // var borderStyle = frameView.Border.BorderStyle; - - // // Check the upper BorderThickness - // for (int r = frame.Y; - // r < Math.Min (frame.Y + borderThickness.Top, frame.Bottom); r++) { - // for (int c = frame.X; - // c < frame.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the left BorderThickness - // for (int r = Math.Min (frame.Y + borderThickness.Top, frame.Bottom); - // r < frame.Bottom - borderThickness.Bottom; r++) { - // for (int c = frame.X; - // c < Math.Min (frame.X + borderThickness.Left, frame.Right); c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the right BorderThickness - // for (int r = Math.Min (frame.Y + borderThickness.Top, frame.Bottom); - // r < frame.Bottom - borderThickness.Bottom; r++) { - // for (int c = Math.Max (frame.Right - borderThickness.Right, frame.X); - // c < frame.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - // // Check the lower BorderThickness - // for (int r = Math.Max (frame.Bottom - borderThickness.Bottom, frame.Y); - // r < frame.Bottom; r++) { - // for (int c = frame.X; - // c < frame.Right; c++) { - - // var color = (Attribute)driver.Contents [r, c, 1]; - // Assert.Equal (Color.Red, color.Background); - // } - // } - - - // //TODO: Re-do padding tests - - // //// Check the upper Padding - // //for (int r = frame.Y + borderThickness.Top; - // // r < Math.Min (frame.Y + sumThickness.Top, frame.Bottom - borderThickness.Bottom); r++) { - // // for (int c = frame.X + borderThickness.Left; - // // c < frame.Right - borderThickness.Right; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.BrightGreen, color.Background); - // // } - // //} - // //// Check the left Padding - // //for (int r = frame.Y + sumThickness.Top; - // // r < frame.Bottom - sumThickness.Bottom; r++) { - // // for (int c = frame.X + borderThickness.Left; - // // c < Math.Min (frame.X + sumThickness.Left, frame.Right - borderThickness.Right); c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.BrightGreen, color.Background); - // // } - // //} - - // //// Check the right Padding - // //// Draw the right Padding - // //for (int r = frame.Y + sumThickness.Top; - // // r < frame.Bottom - sumThickness.Bottom; r++) { - // // for (int c = Math.Max (frame.Right - sumThickness.Right, frame.X + sumThickness.Left); - // // c < Math.Max (frame.Right - borderThickness.Right, frame.X + sumThickness.Left); c++) { - - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.BrightGreen, color.Background); - // // } - // //} - - // //// Check the lower Padding - // //for (int r = Math.Max (frame.Bottom - sumThickness.Bottom, frame.Y + borderThickness.Top); - // // r < frame.Bottom - borderThickness.Bottom; r++) { - // // for (int c = frame.X + borderThickness.Left; - // // c < frame.Right - borderThickness.Right; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.BrightGreen, color.Background); - // // } - // //} - - // Rune hLine = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.HLine : (borderStyle == BorderStyle.Double ? driver.HDLine : ' ')) : ' '; - // Rune vLine = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.VLine : (borderStyle == BorderStyle.Double ? driver.VDLine : ' ')) : ' '; - // Rune uRCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.URCorner : (borderStyle == BorderStyle.Double ? driver.URDCorner : ' ')) : ' '; - // Rune uLCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.ULCorner : (borderStyle == BorderStyle.Double ? driver.ULDCorner : ' ')) : ' '; - // Rune lLCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.LLCorner : (borderStyle == BorderStyle.Double ? driver.LLDCorner : ' ')) : ' '; - // Rune lRCorner = drawMarginFrame > 0 ? (borderStyle == BorderStyle.Single - // ? driver.LRCorner : (borderStyle == BorderStyle.Double ? driver.LRDCorner : ' ')) : ' '; - - // // TODO: redo margin tests - - // //var text = ""; - // //// Check the MarginFrame - // //for (int r = frame.Y + sumThickness.Top; - // // r < frame.Bottom - sumThickness.Bottom; r++) { - // // for (int c = frame.X + sumThickness.Left; - // // c <= frame.Right - sumThickness.Right - 1; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // var rune = (Rune)driver.Contents [r, c, 0]; - // // Assert.Equal (Color.Black, color.Background); - // // if (c == frame.X + sumThickness.Left && r == frame.Y + sumThickness.Top) { - // // Assert.Equal (uLCorner, rune); - // // } else if (c == frame.Right - drawMarginFrame - sumThickness.Right - // // && r == frame.Y + sumThickness.Top) { - // // Assert.Equal (uRCorner, rune); - // // } else if (c == frame.X + sumThickness.Left - // // && r == frame.Bottom - drawMarginFrame - sumThickness.Bottom) { - // // Assert.Equal (lLCorner, rune); - // // } else if (c == frame.Right - drawMarginFrame - sumThickness.Right - // // && r == frame.Bottom - drawMarginFrame - sumThickness.Bottom) { - // // Assert.Equal (lRCorner, rune); - // // } else if (c > frame.X + sumThickness.Left - // // && (r == frame.Y + sumThickness.Top - // // || r == frame.Bottom - drawMarginFrame - sumThickness.Bottom)) { - // // Assert.Equal (hLine, rune); - // // } else if ((c == frame.X + sumThickness.Left - // // || c == frame.Right - drawMarginFrame - sumThickness.Right) - // // && r >= frame.Y + drawMarginFrame + sumThickness.Top) { - // // Assert.Equal (vLine, rune); - // // } else { - // // text += rune.ToString (); - // // } - // // } - // //} - // //Assert.Equal ("This is a test", text.Trim ()); - - // var color = (Attribute)driver.Contents [r, c, 1]; - // var rune = (Rune)driver.Contents [r, c, 0]; - // Assert.Equal (Color.Black, color.Background); - // if (c == frame.X + sumThickness.Left && r == frame.Y + sumThickness.Top) { - // Assert.Equal (uLCorner, rune); - // } else if (c == frame.Right - drawMarginFrame - sumThickness.Right - // && r == frame.Y + sumThickness.Top) { - // Assert.Equal (uRCorner, rune); - // } else if (c == frame.X + sumThickness.Left - // && r == frame.Bottom - drawMarginFrame - sumThickness.Bottom) { - // Assert.Equal (lLCorner, rune); - // } else if (c == frame.Right - drawMarginFrame - sumThickness.Right - // && r == frame.Bottom - drawMarginFrame - sumThickness.Bottom) { - // Assert.Equal (lRCorner, rune); - // } else if (c > frame.X + sumThickness.Left - // && (r == frame.Y + sumThickness.Top - // || r == frame.Bottom - drawMarginFrame - sumThickness.Bottom)) { - // Assert.Equal (hLine, rune); - // } else if ((c == frame.X + sumThickness.Left - // || c == frame.Right - drawMarginFrame - sumThickness.Right) - // && r >= frame.Y + drawMarginFrame + sumThickness.Top) { - // Assert.Equal (vLine, rune); - // } else { - // text += rune.ToString (); - // } - // } - // } - // Assert.Equal ("This is a test", text.Trim ()); - - // // Check the upper Effect3D - // for (int r = frame.Y + effect3DOffset.Y; - // r < frame.Y; r++) { - // for (int c = frame.X + effect3DOffset.X; - // c < frame.Right + effect3DOffset.X; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.DarkGray, color.Background); - // // } - // //} - - // //// Check the left Effect3D - // //for (int r = frame.Y + effect3DOffset.Y; - // // r < frame.Bottom + effect3DOffset.Y; r++) { - // // for (int c = frame.X + effect3DOffset.X; - // // c < frame.X; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.DarkGray, color.Background); - // // } - // //} - - // //// Check the right Effect3D - // //for (int r = frame.Y + effect3DOffset.Y; - // // r < frame.Bottom + effect3DOffset.Y; r++) { - // // for (int c = frame.Right; - // // c < frame.Right + effect3DOffset.X; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.DarkGray, color.Background); - // // } - // //} - - // //// Check the lower Effect3D - // //for (int r = frame.Bottom; - // // r < frame.Bottom + effect3DOffset.Y; r++) { - // // for (int c = frame.X + effect3DOffset.X; - // // c < frame.Right + effect3DOffset.X; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.DarkGray, color.Background); - // // } - // //} - - // //// Check the Child frame - // //for (int r = frame.Y + drawMarginFrame + sumThickness.Top; - // // r < frame.Bottom - drawMarginFrame - sumThickness.Bottom; r++) { - // // for (int c = frame.X + drawMarginFrame + sumThickness.Left; - // // c < frame.Right - drawMarginFrame - sumThickness.Right; c++) { - - // // var color = (Attribute)driver.Contents [r, c, 1]; - // // Assert.Equal (Color.BrightGreen, color.Foreground); - // // Assert.Equal (Color.Black, color.Background); - // // } - // //} - //} - - [Fact, AutoInitShutdown] - public void BorderOnControlWithNoChildren () - { - var label = new TextField ("Loading...") { - Border = new Border () { - BorderStyle = BorderStyle.Single, - DrawMarginFrame = true, - PaddingThickness = new Thickness (1), - ForgroundColor = Color.White - } - }; - - Application.Top.Add (label); - - Assert.Null (Record.Exception (() => label.Redraw (label.Bounds))); - } - -// [Fact, AutoInitShutdown] -// public void BorderStyle_And_DrawMarginFrame_Gets_Sets () -// { -// var lblTop = new Label ("At 0,0"); -// var lblFrame = new Label ("Centered") { X = Pos.Center (), Y = Pos.Center () }; -// var frame = new FrameView () { Y = 1, Width = 20, Height = 3 }; -// var lblFill = new Label () { Width = Dim.Fill(),Height = Dim.Fill(), Visible = false }; -// var fillText = new System.Text.StringBuilder (); -// for (int i = 0; i < frame.Bounds.Height; i++) { -// if (i > 0) { -// fillText.AppendLine (""); -// } -// for (int j = 0; j < frame.Bounds.Width; j++) { -// fillText.Append ("█"); -// } -// } -// lblFill.Text = fillText.ToString (); -// frame.Add (lblFill, lblFrame); -// var lblBottom = new Label ("At 0,4") { Y = 4 }; -// Application.Top.Add (lblTop, frame, lblBottom); -// Application.Begin (Application.Top); - -// Assert.Equal (BorderStyle.Single, frame.Border.BorderStyle); -// Assert.True (frame.Border.DrawMarginFrame); -// TestHelpers.AssertDriverContentsWithFrameAre (@" -//At 0,0 -//┌──────────────────┐ -//│ Centered │ -//└──────────────────┘ -//At 0,4 ", output); - -// frame.Border.BorderStyle = BorderStyle.None; -// Application.Refresh (); -// Assert.True (frame.Border.DrawMarginFrame); -// TestHelpers.AssertDriverContentsWithFrameAre (@" -//At 0,0 - -// Centered - -//At 0,4 ", output); - -//// frame.Border.DrawMarginFrame = false; -//// lblFill.Visible = true; -//// Application.Refresh (); -//// TestHelpers.AssertDriverContentsWithFrameAre (@" -////At 0,0 -////████████████████████ -////██████Centered██████ -////████████████████████ -////At 0,4 ", output); //} } } diff --git a/UnitTests/View/DrawTests.cs b/UnitTests/View/DrawTests.cs new file mode 100644 index 000000000..35443b439 --- /dev/null +++ b/UnitTests/View/DrawTests.cs @@ -0,0 +1,340 @@ +using NStack; +using System; +using Xunit; +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewsTests { + public class DrawTests { + readonly ITestOutputHelper output; + + public DrawTests (ITestOutputHelper output) + { + 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; + + Assert.Equal ("𝔹", us); + Assert.Equal ("𝔹", r.ToString ()); + Assert.Equal (us, r.ToString ()); + + Assert.Equal (2, us.ConsoleWidth); + Assert.Equal (2, Rune.ColumnWidth (r)); + + var win = new Window () { Title = us }; + var label = new Label (ustring.Make (r)); + var tf = new TextField (us) { Y = 1, Width = 3 }; + win.Add (label, tf); + var top = Application.Top; + top.Add (win); + + Application.Begin (top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var expected = @" +┌┤𝔹├────┐ +│𝔹 │ +│𝔹 │ +└────────┘"; + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + TestHelpers.AssertDriverContentsAre (expected, output); + + var expectedColors = new Attribute [] { + // 0 + Colors.Base.Normal, + // 1 + Colors.Base.Focus, + // 2 + Colors.Base.HotNormal + }; + + TestHelpers.AssertDriverColorsAre (@" +0022000000 +0000000000 +0111000000 +0000000000", expectedColors); + } + + [Fact, AutoInitShutdown] + public void CJK_Compatibility_Ideographs_ConsoleWidth_ColumnWidth_Equal_Two () + { + ustring us = "\U0000f900"; + Rune r = 0xf900; + + Assert.Equal ("豈", us); + Assert.Equal ("豈", r.ToString ()); + Assert.Equal (us, r.ToString ()); + + Assert.Equal (2, us.ConsoleWidth); + Assert.Equal (2, Rune.ColumnWidth (r)); + + var win = new Window () { Title = us }; + var label = new Label (ustring.Make (r)); + var tf = new TextField (us) { Y = 1, Width = 3 }; + win.Add (label, tf); + var top = Application.Top; + top.Add (win); + + Application.Begin (top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var expected = @" +┌┤豈├────┐ +│豈 │ +│豈 │ +└────────┘"; + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + TestHelpers.AssertDriverContentsAre (expected, output); + + var expectedColors = new Attribute [] { + // 0 + Colors.Base.Normal, + // 1 + Colors.Base.Focus, + // 2 + Colors.Base.HotNormal + }; + + TestHelpers.AssertDriverColorsAre (@" +0022000000 +0000000000 +0111000000 +0000000000", expectedColors); + } + + [Fact, AutoInitShutdown] + public void Colors_On_TextAlignment_Right_And_Bottom () + { + var labelRight = new Label ("Test") { + Width = 6, + Height = 1, + TextAlignment = TextAlignment.Right, + ColorScheme = Colors.Base + }; + var labelBottom = new Label ("Test", TextDirection.TopBottom_LeftRight) { + Y = 1, + Width = 1, + Height = 6, + VerticalTextAlignment = VerticalTextAlignment.Bottom, + ColorScheme = Colors.Base + }; + var top = Application.Top; + top.Add (labelRight, labelBottom); + + Application.Begin (top); + ((FakeDriver)Application.Driver).SetBufferSize (7, 7); + + TestHelpers.AssertDriverContentsWithFrameAre (@" + Test + + +T +e +s +t ", output); + + TestHelpers.AssertDriverColorsAre (@" +000000 +0 +0 +0 +0 +0 +0", new Attribute [] { Colors.Base.Normal }); + } + + [Fact, AutoInitShutdown] + public void Draw_Negative_Bounds_Horizontal_Without_New_Lines () + { + // BUGBUG: This previously assumed the default height of a View was 1. + var subView = new View () { Id = "subView", Y = 1, Width = 7, Height = 1, Text = "subView" }; + var view = new View () { Id = "view", Width = 20, Height = 2, Text = "01234567890123456789" }; + view.Add (subView); + var content = new View () { Id = "content", Width = 20, Height = 20 }; + content.Add (view); + var container = new View () { Id = "container", X = 1, Y = 1, Width = 5, Height = 5 }; + container.Add (content); + var top = Application.Top; + top.Add (container); + // BUGBUG: v2 - it's bogus to reference .Frame before BeginInit. And why is the clip being set anyway??? + + void Top_LayoutComplete (object sender, LayoutEventArgs e) + { + Application.Driver.Clip = container.Frame; + } + top.LayoutComplete += Top_LayoutComplete; + Application.Begin (top); + + TestHelpers.AssertDriverContentsWithFrameAre (@" + 01234 + subVi", output); + + content.X = -1; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 12345 + ubVie", output); + + content.Y = -1; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + ubVie", output); + + content.Y = -2; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre ("", output); + + content.X = -20; + content.Y = 0; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre ("", output); + } + + + [Fact, AutoInitShutdown] + public void Draw_Negative_Bounds_Horizontal_With_New_Lines () + { + var subView = new View () { Id = "subView", X = 1, Width = 1, Height = 7, Text = "s\nu\nb\nV\ni\ne\nw" }; + var view = new View () { Id = "view", Width = 2, Height = 20, Text = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n6\n7\n8\n9" }; + view.Add (subView); + var content = new View () { Id = "content", Width = 20, Height = 20 }; + content.Add (view); + var container = new View () { Id = "container", X = 1, Y = 1, Width = 5, Height = 5 }; + container.Add (content); + var top = Application.Top; + top.Add (container); + Application.Driver.Clip = container.Frame; + Application.Begin (top); + + TestHelpers.AssertDriverContentsWithFrameAre (@" + 0s + 1u + 2b + 3V + 4i", output); + + content.X = -1; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + s + u + b + V + i", output); + + content.X = -2; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@"", output); + + content.X = 0; + content.Y = -1; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 1u + 2b + 3V + 4i + 5e", output); + + content.Y = -6; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 6w + 7 + 8 + 9 + 0 ", output); + + content.Y = -19; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 9", output); + + content.Y = -20; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre ("", output); + + content.X = -2; + content.Y = 0; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre ("", output); + } + + [Fact, AutoInitShutdown] + public void Draw_Negative_Bounds_Vertical () + { + var subView = new View () { Id = "subView", X = 1, Width = 1, Height = 7, Text = "subView", TextDirection = TextDirection.TopBottom_LeftRight }; + var view = new View () { Id = "view", Width = 2, Height = 20, Text = "01234567890123456789", TextDirection = TextDirection.TopBottom_LeftRight }; + view.Add (subView); + var content = new View () { Id = "content", Width = 20, Height = 20 }; + content.Add (view); + var container = new View () { Id = "container", X = 1, Y = 1, Width = 5, Height = 5 }; + container.Add (content); + var top = Application.Top; + top.Add (container); + Application.Driver.Clip = container.Frame; + Application.Begin (top); + + TestHelpers.AssertDriverContentsWithFrameAre (@" + 0s + 1u + 2b + 3V + 4i", output); + + content.X = -1; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + s + u + b + V + i", output); + + content.X = -2; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@"", output); + + content.X = 0; + content.Y = -1; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 1u + 2b + 3V + 4i + 5e", output); + + content.Y = -6; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 6w + 7 + 8 + 9 + 0 ", output); + + content.Y = -19; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + 9", output); + + content.Y = -20; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre ("", output); + + content.X = -2; + content.Y = 0; + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre ("", output); + } + } +} + diff --git a/UnitTests/View/FrameTests.cs b/UnitTests/View/FrameTests.cs index 0a8e529e7..b9f7d6b51 100644 --- a/UnitTests/View/FrameTests.cs +++ b/UnitTests/View/FrameTests.cs @@ -18,6 +18,31 @@ namespace Terminal.Gui.ViewTests { this.output = output; } + [Fact] + public void GetFramesThickness () + { + var view = new View (); + Assert.Equal (Thickness.Empty, view.GetFramesThickness ()); + + view.Margin.Thickness = new Thickness (1); + Assert.Equal (new Thickness (1), view.GetFramesThickness ()); + + view.BorderFrame.Thickness = new Thickness (1); + Assert.Equal (new Thickness (2), view.GetFramesThickness ()); + + view.Padding.Thickness = new Thickness (1); + Assert.Equal (new Thickness (3), view.GetFramesThickness ()); + + view.Padding.Thickness = new Thickness (2); + Assert.Equal (new Thickness (4), view.GetFramesThickness ()); + + view.Padding.Thickness = new Thickness (1, 2, 3, 4); + Assert.Equal (new Thickness (3, 4, 5, 6), view.GetFramesThickness ()); + + view.Margin.Thickness = new Thickness (1, 2, 3, 4); + Assert.Equal (new Thickness (3, 5, 7, 9), view.GetFramesThickness ()); + } + [Theory, AutoInitShutdown] [InlineData (0)] [InlineData (1)] @@ -25,7 +50,8 @@ namespace Terminal.Gui.ViewTests { [InlineData (3)] public void BorderFrame_With_Title_Size_Height (int height) { - var win = new Window ("1234") { + var win = new Window () { + Title = "1234", Width = Dim.Fill (), Height = Dim.Fill () }; @@ -82,7 +108,8 @@ namespace Terminal.Gui.ViewTests { [InlineData (10)] public void BorderFrame_With_Title_Size_Width (int width) { - var win = new Window ("1234") { + var win = new Window () { + Title = "1234", Width = Dim.Fill (), Height = Dim.Fill () }; diff --git a/UnitTests/View/Layout/AutoSizeTests.cs b/UnitTests/View/Layout/AutoSizeTests.cs new file mode 100644 index 000000000..a1a463dd5 --- /dev/null +++ b/UnitTests/View/Layout/AutoSizeTests.cs @@ -0,0 +1,838 @@ +using NStack; +using System; +using System.Collections.Generic; +using Xunit; +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests { + public class AutoSizeTests { + readonly ITestOutputHelper output; + + public AutoSizeTests (ITestOutputHelper output) + { + this.output = output; + } + + [Fact, AutoInitShutdown] + public void AutoSize_GetAutoSize_Horizontal () + { + var text = "text"; + var view = new View () { + Text = text, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 1), size); + + view.Text = $"{text}\n{text}"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 2), size); + + view.Text = $"{text}\n{text}\n{text}+"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length + 1, 3), size); + + text = string.Empty; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (0, 0), size); + + text = "1"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (1, 1), size); + + text = "界"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (2, 1), size); + } + + [Fact, AutoInitShutdown] + public void AutoSize_GetAutoSize_Vertical() + { + var text = "text"; + var view = new View () { + Text = text, + TextDirection = TextDirection.TopBottom_LeftRight, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var size = view.GetAutoSize (); + Assert.Equal (new Size (1, text.Length), size); + + view.Text = $"{text}\n{text}"; + size = view.GetAutoSize (); + Assert.Equal (new Size (2, text.Length), size); + + view.Text = $"{text}\n{text}\n{text}+"; + size = view.GetAutoSize (); + Assert.Equal (new Size (3, text.Length + 1), size); + + text = string.Empty; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (0, 0), size); + + text = "1"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (1, 1), size); + + text = "界"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (2, 1), size); + } + + [Fact, AutoInitShutdown] + public void AutoSize_GetAutoSize_Left() + { + var text = "This is some text."; + var view = new View () { + Text = text, + TextAlignment = TextAlignment.Left, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 1), size); + + view.Text = $"{text}\n{text}"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 2), size); + + view.Text = $"{text}\n{text}\n{text}+"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length + 1, 3), size); + + text = string.Empty; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (0, 0), size); + + text = "1"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (1, 1), size); + + text = "界"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (2, 1), size); + } + + [Fact, AutoInitShutdown] + public void AutoSize_GetAutoSize_Right () + { + var text = "This is some text."; + var view = new View () { + Text = text, + TextAlignment = TextAlignment.Right, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 1), size); + + view.Text = $"{text}\n{text}"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 2), size); + + view.Text = $"{text}\n{text}\n{text}+"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length + 1, 3), size); + + text = string.Empty; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (0, 0), size); + + text = "1"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (1, 1), size); + + text = "界"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (2, 1), size); + } + + [Fact, AutoInitShutdown] + public void AutoSize_GetAutoSize_Centered () + { + var text = "This is some text."; + var view = new View () { + Text = text, + TextAlignment = TextAlignment.Centered, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + var size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 1), size); + + view.Text = $"{text}\n{text}"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length, 2), size); + + view.Text = $"{text}\n{text}\n{text}+"; + size = view.GetAutoSize (); + Assert.Equal (new Size (text.Length + 1, 3), size); + + text = string.Empty; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (0, 0), size); + + text = "1"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (1, 1), size); + + text = "界"; + view.Text = text; + size = view.GetAutoSize (); + Assert.Equal (new Size (2, 1), size); + } + + [Fact, AutoInitShutdown] + public void AutoSize_False_View_IsEmpty_False_Return_Null_Lines () + { + var text = "Views"; + var view = new View () { + Width = Dim.Fill () - text.Length, + Height = 1, + Text = text + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + Assert.Equal (5, text.Length); + 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 Rect (0, 0, 10, 4), win.Frame); + Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); + var expected = @" +┌────────┐ +│Vie │ +│ │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + view.Width = Dim.Fill () - text.Length; + Application.Refresh (); + + 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); + expected = @" +┌────────┐ +│ │ +│ │ +└────────┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_False_View_IsEmpty_True_Minimum_Height () + { + var text = "Views"; + var view = new View () { + Width = Dim.Fill () - text.Length, + Text = text + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + Assert.Equal (5, text.Length); + Assert.False (view.AutoSize); + Assert.Equal (new Rect (0, 0, 3, 1), view.Frame); + Assert.Equal (new Size (3, 1), view.TextFormatter.Size); + Assert.Single (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 = @" +┌────────┐ +│Vie │ +│ │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + view.Width = Dim.Fill () - text.Length; + Application.Refresh (); + + 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)); + Assert.Null (exception); + expected = @" +┌────────┐ +│ │ +│ │ +└────────┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_True_Label_IsEmpty_False_Never_Return_Null_Lines () + { + var text = "Label"; + var label = new Label () { + Width = Dim.Fill () - text.Length, + Height = 1, + Text = text + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (label); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + Assert.Equal (5, text.Length); + 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 Rect (0, 0, 10, 4), win.Frame); + Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); + var expected = @" +┌────────┐ +│Label │ +│ │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + label.Width = Dim.Fill () - text.Length; + Application.Refresh (); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, 5, 1), label.Frame); + Assert.Equal (new Size (5, 1), label.TextFormatter.Size); + Assert.Single (label.TextFormatter.Lines); + expected = @" +┌────────┐ +│Label │ +│ │ +└────────┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_False_Label_IsEmpty_True_Return_Null_Lines () + { + var text = "Label"; + var label = new Label () { + Width = Dim.Fill () - text.Length, + Height = 1, + Text = text, + AutoSize = false + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (label); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + Assert.Equal (5, text.Length); + 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 Rect (0, 0, 10, 4), win.Frame); + Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); + var expected = @" +┌────────┐ +│Lab │ +│ │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + label.Width = Dim.Fill () - text.Length; + Application.Refresh (); + + 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); + expected = @" +┌────────┐ +│ │ +│ │ +└────────┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_True_Label_IsEmpty_False_Minimum_Height () + { + var text = "Label"; + var label = new Label () { + Width = Dim.Fill () - text.Length, + Text = text + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (label); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + Assert.Equal (5, text.Length); + 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 Rect (0, 0, 10, 4), win.Frame); + Assert.Equal (new Rect (0, 0, 10, 4), Application.Top.Frame); + var expected = @" +┌────────┐ +│Label │ +│ │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + label.Width = Dim.Fill () - text.Length; + Application.Refresh (); + + Assert.Equal (new Rect (0, 0, 5, 1), label.Frame); + Assert.Equal (new Size (5, 1), label.TextFormatter.Size); + var exception = Record.Exception (() => Assert.Single (label.TextFormatter.Lines)); + Assert.Null (exception); + expected = @" +┌────────┐ +│Label │ +│ │ +└────────┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_False_Label_Height_Zero_Returns_Minimum_Height () + { + var text = "Label"; + var label = new Label () { + Width = Dim.Fill () - text.Length, + Text = text, + AutoSize = false + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (label); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (10, 4); + + Assert.Equal (5, text.Length); + Assert.False (label.AutoSize); + Assert.Equal (new Rect (0, 0, 3, 1), label.Frame); + Assert.Equal (new Size (3, 1), label.TextFormatter.Size); + Assert.Single (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 = @" +┌────────┐ +│Lab │ +│ │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + label.Width = Dim.Fill () - text.Length; + Application.Refresh (); + + 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)); + Assert.Null (exception); + expected = @" +┌────────┐ +│ │ +│ │ +└────────┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 10, 4), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_True_View_IsEmpty_False_Minimum_Width () + { + var text = "Views"; + var view = new View () { + TextDirection = TextDirection.TopBottom_LeftRight, + Height = Dim.Fill () - text.Length, + Text = text, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (4, 10); + + Assert.Equal (5, text.Length); + 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 Rect (0, 0, 4, 10), win.Frame); + Assert.Equal (new Rect (0, 0, 4, 10), Application.Top.Frame); + var expected = @" +┌──┐ +│V │ +│i │ +│e │ +│w │ +│s │ +│ │ +│ │ +│ │ +└──┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + view.Height = Dim.Fill () - text.Length; + Application.Refresh (); + + Assert.Equal (new Rect (0, 0, 1, 5), view.Frame); + Assert.Equal (new Size (1, 5), view.TextFormatter.Size); + var exception = Record.Exception (() => Assert.Single (view.TextFormatter.Lines)); + Assert.Null (exception); + expected = @" +┌──┐ +│V │ +│i │ +│e │ +│w │ +│s │ +│ │ +│ │ +│ │ +└──┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_False_View_Width_Null_Returns_Host_Frame_Width () + { + var text = "Views"; + var view = new View () { + TextDirection = TextDirection.TopBottom_LeftRight, + Height = Dim.Fill () - text.Length, + Text = text + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (4, 10); + + Assert.Equal (5, text.Length); + Assert.False (view.AutoSize); + Assert.Equal (new Rect (0, 0, 1, 3), view.Frame); + Assert.Equal (new Size (1, 3), view.TextFormatter.Size); + Assert.Single (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 = @" +┌──┐ +│V │ +│i │ +│e │ +│ │ +│ │ +│ │ +│ │ +│ │ +└──┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + view.Height = Dim.Fill () - text.Length; + Application.Refresh (); + + 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)); + Assert.Null (exception); + expected = @" +┌──┐ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +└──┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_True_View_IsEmpty_False_Minimum_Width_Wide_Rune () + { + var text = "界View"; + var view = new View () { + TextDirection = TextDirection.TopBottom_LeftRight, + Height = Dim.Fill () - text.Length, + Text = text, + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (4, 10); + + Assert.Equal (5, text.Length); + 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 Rect (0, 0, 4, 10), win.Frame); + Assert.Equal (new Rect (0, 0, 4, 10), Application.Top.Frame); + var expected = @" +┌──┐ +│界│ +│V │ +│i │ +│e │ +│w │ +│ │ +│ │ +│ │ +└──┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + view.Height = Dim.Fill () - text.Length; + Application.Refresh (); + + 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)); + Assert.Null (exception); + expected = @" +┌──┐ +│界│ +│V │ +│i │ +│e │ +│w │ +│ │ +│ │ +│ │ +└──┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_False_View_Width_Zero_Returns_Minimum_Width_With_Wide_Rune () + { + var text = "界View"; + var view = new View () { + TextDirection = TextDirection.TopBottom_LeftRight, + Height = Dim.Fill () - text.Length, + Text = text + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (view); + Application.Top.Add (win); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (4, 10); + + Assert.Equal (5, text.Length); + Assert.False (view.AutoSize); + Assert.Equal (new Rect (0, 0, 2, 3), view.Frame); + Assert.Equal (new Size (2, 3), view.TextFormatter.Size); + Assert.Single (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 = @" +┌──┐ +│界│ +│V │ +│i │ +│ │ +│ │ +│ │ +│ │ +│ │ +└──┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + + text = "0123456789"; + Assert.Equal (10, text.Length); + view.Height = Dim.Fill () - text.Length; + Application.Refresh (); + + 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)); + Assert.Null (exception); + expected = @" +┌──┐ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +└──┘ +"; + + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 4, 10), pos); + } + } +} diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index 1a1a2823d..8c0ae8cf4 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -259,7 +259,7 @@ namespace Terminal.Gui.ViewTests { { var t = Application.Top; - var w = new Window ("w") { + var w = new Window () { Width = Dim.Fill (0), Height = Dim.Sized (10) }; @@ -296,7 +296,7 @@ namespace Terminal.Gui.ViewTests { { var t = new View ("top") { Width = 80, Height = 25 }; - var w = new Window (new Rect (1, 2, 4, 5), "w"); + var w = new Window (new Rect (1, 2, 4, 5)) { Title = "w" }; t.Add (w); t.LayoutSubviews (); @@ -310,7 +310,7 @@ namespace Terminal.Gui.ViewTests { { var t = new View ("top") { Width = 80, Height = 25 }; - var w = new Window ("w") { + var w = new Window () { Width = Dim.Fill (0), Height = Dim.Sized (10) }; @@ -339,7 +339,7 @@ namespace Terminal.Gui.ViewTests { // Testing with the Button because it properly handles the Dim class. var t = Application.Top; - var w = new Window ("w") { + var w = new Window () { Width = 100, Height = 100 }; @@ -550,18 +550,18 @@ namespace Terminal.Gui.ViewTests { [Fact] public void DimCombine_ObtuseScenario_Throw_If_SuperView_Refs_SubView () { - var t = new View ("top") { Width = 80, Height = 25 }; + var t = new View () { Width = 80, Height = 25 }; - var w = new Window ("w") { + var w = new Window () { Width = Dim.Width (t) - 2, // 78 Height = Dim.Height (t) - 2 // 23 }; - var f = new FrameView ("f"); - var v1 = new View ("v1") { + var f = new FrameView (); + var v1 = new View () { Width = Dim.Width (w) - 2, // 76 Height = Dim.Height (w) - 2 // 21 }; - var v2 = new View ("v2") { + var v2 = new View () { Width = Dim.Width (v1) - 2, // 74 Height = Dim.Height (v1) - 2 // 19 }; @@ -594,16 +594,16 @@ namespace Terminal.Gui.ViewTests { { var t = new View ("top") { Width = 80, Height = 25 }; - var w = new Window ("w") { + var w = new Window () { Width = Dim.Width (t) - 2, // 78 Height = Dim.Height (t) - 2 // 23 }; - var f = new FrameView ("f"); - var v1 = new View ("v1") { + var f = new FrameView (); + var v1 = new View () { Width = Dim.Width (w) - 2, // 76 Height = Dim.Height (w) - 2 // 21 }; - var v2 = new View ("v2") { + var v2 = new View () { Width = Dim.Width (v1) - 2, // 74 Height = Dim.Height (v1) - 2 // 19 }; @@ -633,23 +633,23 @@ namespace Terminal.Gui.ViewTests { [Fact] public void PosCombine_View_Not_Added_Throws () { - var t = new View ("t") { Width = 80, Height = 50 }; + var t = new View () { Width = 80, Height = 50 }; // BUGBUG: v2 - super should not reference it's superview (t) - var super = new View ("super") { + var super = new View () { Width = Dim.Width (t) - 2, Height = Dim.Height (t) - 2 }; t.Add (super); - var sub = new View ("sub"); + var sub = new View (); super.Add (sub); - var v1 = new View ("v1") { + var v1 = new View () { Width = Dim.Width (super) - 2, Height = Dim.Height (super) - 2 }; - var v2 = new View ("v2") { + var v2 = new View () { Width = Dim.Width (v1) - 2, Height = Dim.Height (v1) - 2 }; diff --git a/UnitTests/View/Layout/LayoutTests.cs b/UnitTests/View/Layout/LayoutTests.cs index 4d80b5187..36e932b84 100644 --- a/UnitTests/View/Layout/LayoutTests.cs +++ b/UnitTests/View/Layout/LayoutTests.cs @@ -1,10 +1,6 @@ -using NStack; -using System; -using System.Collections.Generic; -using System.Xml.Linq; +using System; using Xunit; using Xunit.Abstractions; -//using GraphViewTests = Terminal.Gui.Views.GraphViewTests; // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; @@ -325,7 +321,7 @@ namespace Terminal.Gui.ViewTests { [Fact, AutoInitShutdown] public void AutoSize_False_ResizeView_With_Dim_Fill_After_IsInitialized () { - var win = new Window (new Rect (0, 0, 30, 80), ""); + var win = new Window (new Rect (0, 0, 30, 80)); var label = new Label () { AutoSize = false, Width = Dim.Fill (), Height = Dim.Fill () }; win.Add (label); Application.Top.Add (win); @@ -350,7 +346,7 @@ namespace Terminal.Gui.ViewTests { [Fact, AutoInitShutdown] public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute_After_IsAdded_And_IsInitialized () { - var win = new Window (new Rect (0, 0, 30, 80), "win"); + var win = new Window (new Rect (0, 0, 30, 80)); var label = new Label () { Width = Dim.Fill () }; win.Add (label); Application.Top.Add (win); @@ -386,7 +382,7 @@ namespace Terminal.Gui.ViewTests { [Fact, AutoInitShutdown] public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute_With_Initialization () { - var win = new Window (new Rect (0, 0, 30, 80), ""); + var win = new Window (new Rect (0, 0, 30, 80)); var label = new Label () { Width = Dim.Fill () }; win.Add (label); Application.Top.Add (win); @@ -1859,5 +1855,64 @@ Y Application.End (rs); } + + + [Fact] + public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds () + { + Application.Init (new FakeDriver ()); + + var top = Application.Top; + + var view = new View ("view") { + Y = -2, + Height = 10, + TextDirection = TextDirection.TopBottom_LeftRight + }; + top.Add (view); + + Application.Iteration += () => { + Assert.Equal (-2, view.Y); + + Application.RequestStop (); + }; + + try { + Application.Run (); + } catch (IndexOutOfRangeException ex) { + // After the fix this exception will not be caught. + Assert.IsType (ex); + } + + // Shutdown must be called to safely clean up Application if Init has been called + Application.Shutdown (); + } + + [Fact] + public void Draw_Throws_IndexOutOfRangeException_With_Negative_Bounds () + { + Application.Init (new FakeDriver ()); + + var top = Application.Top; + + var view = new View ("view") { X = -2 }; + top.Add (view); + + Application.Iteration += () => { + Assert.Equal (-2, view.X); + + Application.RequestStop (); + }; + + try { + Application.Run (); + } catch (IndexOutOfRangeException ex) { + // After the fix this exception will not be caught. + Assert.IsType (ex); + } + + // Shutdown must be called to safely clean up Application if Init has been called + Application.Shutdown (); + } } } diff --git a/UnitTests/View/Layout/PosTests.cs b/UnitTests/View/Layout/PosTests.cs index cab3227b7..de8343a71 100644 --- a/UnitTests/View/Layout/PosTests.cs +++ b/UnitTests/View/Layout/PosTests.cs @@ -531,7 +531,7 @@ namespace Terminal.Gui.ViewTests { Application.Iteration = () => { Application.RequestStop (); }; - var win = new Window ("window") { + var win = new Window () { X = 0, Y = 0, Width = Dim.Fill (), @@ -676,11 +676,11 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w") { + var w = new Window () { X = Pos.Left (t) + 2, Y = Pos.At (2) }; - var v = new View ("v") { + var v = new View () { X = Pos.Center (), Y = Pos.Percent (10), ForceValidatePosDim = true @@ -709,7 +709,7 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window (new Rect (1, 2, 4, 5), "w"); + var w = new Window (new Rect (1, 2, 4, 5)); t.Add (w); t.Ready += (s, e) => { @@ -731,11 +731,11 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w") { + var w = new Window () { X = Pos.Left (t) + 2, Y = Pos.At (2) }; - var v = new View ("v") { + var v = new View () { X = Pos.Center (), Y = Pos.Percent (10) }; @@ -763,16 +763,16 @@ namespace Terminal.Gui.ViewTests { //{ // Application.Init (new FakeDriver ()); - // var w = new Window ("w") { + // var w = new Window () { // X = Pos.Left (Application.Top) + 2, // Y = Pos.Top (Application.Top) + 2 // }; - // var f = new FrameView ("f"); - // var v1 = new View ("v1") { + // var f = new FrameView (); + // var v1 = new View () { // X = Pos.Left (w) + 2, // Y = Pos.Top (w) + 2 // }; - // var v2 = new View ("v2") { + // var v2 = new View () { // X = Pos.Left (v1) + 2, // Y = Pos.Top (v1) + 2 // }; @@ -810,16 +810,16 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w") { + var w = new Window () { X = Pos.Left (t) + 2, Y = Pos.Top (t) + 2 }; - var f = new FrameView ("f"); - var v1 = new View ("v1") { + var f = new FrameView (); + var v1 = new View () { X = Pos.Left (w) + 2, Y = Pos.Top (w) + 2 }; - var v2 = new View ("v2") { + var v2 = new View () { X = Pos.Left (v1) + 2, Y = Pos.Top (v1) + 2 }; diff --git a/UnitTests/View/NavigationTests.cs b/UnitTests/View/NavigationTests.cs index 3eb1fe4cf..f47e7c9a9 100644 --- a/UnitTests/View/NavigationTests.cs +++ b/UnitTests/View/NavigationTests.cs @@ -472,9 +472,9 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w"); - var f = new FrameView ("f"); - var v = new View ("v") { CanFocus = true }; + var w = new Window (); + var f = new FrameView (); + var v = new View () { CanFocus = true }; f.Add (v); w.Add (f); t.Add (w); @@ -509,9 +509,9 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w"); - var f = new FrameView ("f"); - var v = new View ("v") { CanFocus = true }; + var w = new Window (); + var f = new FrameView (); + var v = new View () { CanFocus = true }; f.Add (v); w.Add (f); t.Add (w); @@ -552,10 +552,10 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w"); - var f = new FrameView ("f"); - var v1 = new View ("v1") { CanFocus = true }; - var v2 = new View ("v2") { CanFocus = true }; + var w = new Window (); + var f = new FrameView (); + var v1 = new View () { CanFocus = true }; + var v2 = new View () { CanFocus = true }; f.Add (v1, v2); w.Add (f); t.Add (w); @@ -587,10 +587,10 @@ namespace Terminal.Gui.ViewTests { var t = Application.Top; - var w = new Window ("w"); - var f = new FrameView ("f"); - var v1 = new View ("v1"); - var v2 = new View ("v2") { CanFocus = true }; + var w = new Window (); + var f = new FrameView (); + var v1 = new View (); + var v2 = new View () { CanFocus = true }; f.Add (v1, v2); w.Add (f); t.Add (w); diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index f9bff4018..9626b65b8 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -567,9 +567,9 @@ namespace Terminal.Gui.ViewTests { //Assert.Equal (new Rect (new Point (0, 0), rect.Size), view._needsDisplay); Assert.True (view.LayoutNeeded); Assert.False (view._childNeedsDisplay); - Assert.False (view.addingView); - view.addingView = true; - Assert.True (view.addingView); + Assert.False (view._addingView); + view._addingView = true; + Assert.True (view._addingView); view.ViewToScreen (0, 0, out int rcol, out int rrow); Assert.Equal (1, rcol); Assert.Equal (1, rrow); @@ -937,8 +937,8 @@ namespace Terminal.Gui.ViewTests { Assert.True (horizontalView.AutoSize); Assert.Equal (new Rect (0, 0, 12, 1), horizontalView.Frame); Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ()); - Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextAndHotKey ()); - Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetSizeNeededForTextAndHotKey ()); + //Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextAndHotKey ()); + //Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetSizeNeededForTextAndHotKey ()); Assert.Equal (horizontalView.Frame.Size, horizontalView.GetSizeNeededForTextWithoutHotKey ()); Assert.True (verticalView.AutoSize); @@ -946,7 +946,7 @@ namespace Terminal.Gui.ViewTests { //Assert.Equal (new Rect (0, 0, 2, 11), verticalView.Frame); //Assert.Equal (new Size (2, 11), verticalView.GetSizeNeededForTextWithoutHotKey ()); //Assert.Equal (new Size (2, 11), verticalView.GetSizeNeededForTextAndHotKey ()); - Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetSizeNeededForTextAndHotKey ()); + //Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetSizeNeededForTextAndHotKey ()); Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ()); text = "Say He_llo 你"; @@ -956,8 +956,8 @@ namespace Terminal.Gui.ViewTests { Assert.True (horizontalView.AutoSize); Assert.Equal (new Rect (0, 0, 12, 1), horizontalView.Frame); Assert.Equal (new Size (12, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ()); - Assert.Equal (new Size (13, 1), horizontalView.GetSizeNeededForTextAndHotKey ()); - Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetSizeNeededForTextAndHotKey ()); + //Assert.Equal (new Size (13, 1), horizontalView.GetSizeNeededForTextAndHotKey ()); + //Assert.Equal (horizontalView.TextFormatter.Size, horizontalView.GetSizeNeededForTextAndHotKey ()); Assert.Equal (horizontalView.Frame.Size, horizontalView.GetSizeNeededForTextWithoutHotKey ()); Assert.True (verticalView.AutoSize); diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs index 550976da3..683ba229f 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/UnitTests/Views/ButtonTests.cs @@ -215,7 +215,7 @@ namespace Terminal.Gui.ViewsTests { X = Pos.Center (), Y = Pos.Center () }; - var win = new Window ("Test Demo 你") { + var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () }; @@ -233,7 +233,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (new Rect (0, 0, 16, 1), btn.Bounds); var expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 ] │ │ │ @@ -255,7 +255,6 @@ namespace Terminal.Gui.ViewsTests { var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill (), - Title = "Test Demo 你" }; win.Add (btn); Application.Top.Add (win); @@ -271,7 +270,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (new Rect (0, 0, 16, 1), btn.Bounds); var expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 ] │ │ │ @@ -294,7 +293,6 @@ namespace Terminal.Gui.ViewsTests { var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill (), - Title = "Test Demo 你" }; win.Add (btn); Application.Top.Add (win); @@ -308,7 +306,7 @@ namespace Terminal.Gui.ViewsTests { Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (30, 5); var expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 ] │ │ │ @@ -330,7 +328,6 @@ namespace Terminal.Gui.ViewsTests { var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill (), - Title = "Test Demo 你" }; win.Add (btn); Application.Top.Add (win); @@ -340,7 +337,7 @@ namespace Terminal.Gui.ViewsTests { Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (30, 5); var expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 ] │ │ │ @@ -354,7 +351,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (btn.AutoSize); Application.Refresh (); expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 changed ] │ │ │ @@ -377,7 +374,6 @@ namespace Terminal.Gui.ViewsTests { var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill (), - Title = "Test Demo 你" }; win.Add (btn); Application.Top.Add (win); @@ -387,7 +383,7 @@ namespace Terminal.Gui.ViewsTests { Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (30, 5); var expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 ]│ │ │ @@ -401,7 +397,7 @@ namespace Terminal.Gui.ViewsTests { Assert.True (btn.AutoSize); Application.Refresh (); expected = @" -┌┤Test Demo 你├──────────────┐ +┌────────────────────────────┐ │ │ │ [ Say Hello 你 changed ]│ │ │ @@ -483,7 +479,7 @@ namespace Terminal.Gui.ViewsTests { }; tabView.AddTab (new TabView.Tab ("Find", tab), true); - var win = new Window ("Find") { + var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () }; @@ -512,7 +508,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (new Rect (0, 3, 12, 1), ckbMatchCase.Frame); Assert.Equal (new Rect (0, 4, 18, 1), ckbMatchWholeWord.Frame); var expected = @" -┌┤Find├──────────────────────────────────────────────┐ +┌────────────────────────────────────────────────────┐ │┌────┐ │ ││Find│ │ ││ └─────────────────────────────────────────────┐│ diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index 008c07821..5e95afbee 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -637,7 +637,7 @@ namespace Terminal.Gui.ViewsTests { Width = 20 }; - var win = new Window ("Window"); + var win = new Window (); win.Add (label, tf); var statusBar = new StatusBar (new StatusItem [] { @@ -658,7 +658,7 @@ namespace Terminal.Gui.ViewsTests { Application.Top.Redraw (Application.Top.Bounds); var expected = @" File Edit -┌┤Window├──────────────────────────────────┐ +┌──────────────────────────────────────────┐ │ │ │ │ │ │ diff --git a/UnitTests/Views/FrameViewTests.cs b/UnitTests/Views/FrameViewTests.cs index 1f2e681f1..953dca640 100644 --- a/UnitTests/Views/FrameViewTests.cs +++ b/UnitTests/Views/FrameViewTests.cs @@ -22,19 +22,19 @@ namespace Terminal.Gui.ViewsTests { var fv = new FrameView (); Assert.Equal (string.Empty, fv.Title); Assert.Equal (string.Empty, fv.Text); - Assert.NotNull (fv.Border); + Assert.Equal (LineStyle.Single, fv.BorderStyle); fv = new FrameView ("Test"); Assert.Equal ("Test", fv.Title); Assert.Equal (string.Empty, fv.Text); - Assert.NotNull (fv.Border); + Assert.Equal (LineStyle.Single, fv.BorderStyle); fv = new FrameView (new Rect (1, 2, 10, 20), "Test"); Assert.Equal ("Test", fv.Title); Assert.Equal (string.Empty, fv.Text); - Assert.NotNull (fv.Border); fv.BeginInit (); fv.EndInit (); + Assert.Equal (LineStyle.Single, fv.BorderStyle); Assert.Equal (new Rect (1, 2, 10, 20), fv.Frame); } @@ -45,7 +45,6 @@ namespace Terminal.Gui.ViewsTests { var fv = new FrameView (); Assert.Equal (string.Empty, fv.Title); Assert.Equal (string.Empty, fv.Text); - Assert.NotNull (fv.Border); Application.Top.Add (fv); Application.Begin (Application.Top); Assert.Equal (new Rect (0, 0, 0, 0), fv.Frame); diff --git a/UnitTests/Views/LabelTests.cs b/UnitTests/Views/LabelTests.cs new file mode 100644 index 000000000..28c130ae2 --- /dev/null +++ b/UnitTests/Views/LabelTests.cs @@ -0,0 +1,912 @@ +using System; +using Xunit; +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewsTests { + public class LabelTests { + readonly ITestOutputHelper output; + + public LabelTests (ITestOutputHelper output) + { + this.output = output; + } + + [Fact, AutoInitShutdown] + public void Constructors_Defaults () + { + var label = new Label (); + Assert.Equal (string.Empty, label.Text); + Application.Top.Add (label); + var rs = Application.Begin (Application.Top); + + Assert.Equal (TextAlignment.Left, label.TextAlignment); + Assert.True (label.AutoSize); + Assert.False (label.CanFocus); + Assert.Equal (new Rect (0, 0, 0, 1), label.Frame); + Assert.Equal (Key.Null, label.HotKey); + var expected = @""; + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Application.End (rs); + + label = new Label ("ARGS", true) { Text = "Test" }; + Assert.True (label.AutoSize); + Assert.Equal ("Test", label.Text); + Application.Top.Add (label); + rs = Application.Begin (Application.Top); + + Assert.Equal ("Test", label.TextFormatter.Text); + Assert.Equal (new Rect (0, 0, 4, 1), label.Frame); + expected = @" +Test +"; + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Application.End (rs); + + label = new Label (3, 4, "Test", true); + Assert.Equal ("Test", label.Text); + Application.Top.Add (label); + rs = Application.Begin (Application.Top); + + Assert.Equal ("Test", label.TextFormatter.Text); + Assert.Equal (new Rect (3, 4, 4, 1), label.Frame); + expected = @" + Test +"; + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + Application.End (rs); + } + + [Fact] + public void TestAssignTextToLabel () + { + View b = new Label () { Text = "heya" }; + Assert.Equal ("heya", b.Text); + Assert.True (b.TextFormatter.Text.Contains ("heya")); + b.Text = "heyb"; + Assert.Equal ("heyb", b.Text); + Assert.True (b.TextFormatter.Text.Contains ("heyb")); + + // with cast + Assert.Equal ("heyb", ((Label)b).Text); + } + + + [Fact, AutoInitShutdown] + public void Update_Only_On_Or_After_Initialize () + { + var label = new Label ("Say Hello 你") { + X = Pos.Center (), + Y = Pos.Center () + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (label); + Application.Top.Add (win); + + Assert.False (label.IsInitialized); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + + Assert.True (label.IsInitialized); + Assert.Equal ("Say Hello 你", label.Text); + Assert.Equal ("Say Hello 你", label.TextFormatter.Text); + Assert.Equal (new Rect (0, 0, 12, 1), label.Bounds); + + var expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你 │ +│ │ +└────────────────────────────┘ +"; + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 30, 5), pos); + } + + [Fact, AutoInitShutdown] + public void Update_Parameterless_Only_On_Or_After_Initialize () + { + var label = new Label () { + X = Pos.Center (), + Y = Pos.Center (), + Text = "Say Hello 你", + AutoSize = true + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill (), + }; + win.Add (label); + Application.Top.Add (win); + + Assert.False (label.IsInitialized); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + + Assert.True (label.IsInitialized); + Assert.Equal ("Say Hello 你", label.Text); + Assert.Equal ("Say Hello 你", label.TextFormatter.Text); + Assert.Equal (new Rect (0, 0, 12, 1), label.Bounds); + + var expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你 │ +│ │ +└────────────────────────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 30, 5), pos); + } + + [Fact, AutoInitShutdown] + public void AutoSize_Stays_True_With_EmptyText () + { + var label = new Label () { + X = Pos.Center (), + Y = Pos.Center (), + AutoSize = true + }; + + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill (), + }; + win.Add (label); + Application.Top.Add (win); + + Assert.True (label.AutoSize); + + label.Text = "Say Hello 你"; + + Assert.True (label.AutoSize); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + var expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你 │ +│ │ +└────────────────────────────┘ +"; + + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void AutoSize_Stays_True_Center () + { + var label = new Label () { + X = Pos.Center (), + Y = Pos.Center (), + Text = "Say Hello 你" + }; + + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill (), + }; + win.Add (label); + Application.Top.Add (win); + + Assert.True (label.AutoSize); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + var expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你 │ +│ │ +└────────────────────────────┘ +"; + + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + Assert.True (label.AutoSize); + label.Text = "Say Hello 你 changed"; + Assert.True (label.AutoSize); + Application.Refresh (); + expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你 changed │ +│ │ +└────────────────────────────┘ +"; + + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void AutoSize_Stays_True_AnchorEnd () + { + var label = new Label () { + Y = Pos.Center (), + Text = "Say Hello 你", + AutoSize = true + }; + label.X = Pos.AnchorEnd () - Pos.Function (() => TextFormatter.GetTextWidth (label.TextFormatter.Text)); + + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill (), + }; + win.Add (label); + Application.Top.Add (win); + + Assert.True (label.AutoSize); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + var expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你│ +│ │ +└────────────────────────────┘ +"; + + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + Assert.True (label.AutoSize); + label.Text = "Say Hello 你 changed"; + Assert.True (label.AutoSize); + Application.Refresh (); + expected = @" +┌────────────────────────────┐ +│ │ +│ Say Hello 你 changed│ +│ │ +└────────────────────────────┘ +"; + + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void Pos_Center_Layout_AutoSize_True () + { + var Label = new Label ("012345678901") { + X = Pos.Center (), + Y = Pos.Center (), + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (Label); + Application.Top.Add (win); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + Assert.True (Label.AutoSize); + //Assert.Equal (new Rect (5, 1, 18, 1), Label.Frame); + var expected = @" +┌────────────────────────────┐ +│ │ +│ 012345678901 │ +│ │ +└────────────────────────────┘ +"; + + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void Pos_Center_Layout_AutoSize_False () + { + var Label = new Label ("012345678901") { + X = Pos.Center (), + Y = Pos.Center (), + AutoSize = false, + Width = 20, + TextAlignment = TextAlignment.Centered + }; + var win = new Window () { + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (Label); + Application.Top.Add (win); + + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (30, 5); + Assert.False (Label.AutoSize); + Assert.Equal (new Rect (4, 1, 20, 1), Label.Frame); + var expected = @" +┌────────────────────────────┐ +│ │ +│ 012345678901 │ +│ │ +└────────────────────────────┘ +"; + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + //[Fact, AutoInitShutdown] + //public void Label_HotKeyChanged_EventFires () + //{ + // var label = new Label ("Yar"); + + // object sender = null; + // KeyChangedEventArgs args = null; + + // label.HotKeyChanged += (s, e) =>{ + // sender = s; + // args = e; + + // }; + + // label.HotKey = Key.r; + // Assert.Same (label, sender); + // Assert.Equal (Key.Y, args.OldKey); + // Assert.Equal (Key.r, args.NewKey); + + //} + + [Fact, AutoInitShutdown] + public void Label_HotKeyChanged_EventFires_WithNone () + { + var label = new Label (); + + object sender = null; + KeyChangedEventArgs args = null; + + label.HotKeyChanged += (s, e) => { + sender = s; + args = e; + + }; + + label.HotKey = Key.r; + Assert.Same (label, sender); + Assert.Equal (Key.Null, args.OldKey); + Assert.Equal (Key.r, args.NewKey); + } + + + [Fact, AutoInitShutdown] + public void Label_WordWrap_PreserveTrailingSpaces_Horizontal_With_Simple_Runes () + { + var text = "A sentence has words."; + var width = 3; + var height = 8; + var wrappedLines = TextFormatter.WordWrapText (text, width, true); + var breakLines = ""; + foreach (var line in wrappedLines) breakLines += $"{line}{Environment.NewLine}"; + var label = new Label (breakLines) { Width = Dim.Fill (), Height = Dim.Fill () }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (label); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, width, height + 1), label.Frame); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); + + var expected = @" +┌───┐ +│A │ +│sen│ +│ten│ +│ce │ +│has│ +│ │ +│wor│ +│ds.│ +└───┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); + } + + [Fact, AutoInitShutdown] + public void Label_WordWrap_PreserveTrailingSpaces_Vertical_With_Simple_Runes () + { + var text = "A sentence has words."; + var width = 8; + var height = 3; + var wrappedLines = TextFormatter.WordWrapText (text, height, true); + var breakLines = ""; + for (int i = 0; i < wrappedLines.Count; i++) breakLines += $"{wrappedLines [i]}{(i < wrappedLines.Count - 1 ? Environment.NewLine : string.Empty)}"; + var label = new Label (breakLines) { + TextDirection = TextDirection.TopBottom_LeftRight, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (label); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, width, height), label.Frame); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); + + var expected = @" +┌────────┐ +│Astch wd│ +│ eeea os│ +│ nn s r.│ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); + } + + [Fact, AutoInitShutdown] + public void Label_WordWrap_PreserveTrailingSpaces_Horizontal_With_Wide_Runes () + { + var text = "文に は言葉 があり ます。"; + var width = 6; + var height = 8; + var wrappedLines = TextFormatter.WordWrapText (text, width, true); + var breakLines = ""; + foreach (var line in wrappedLines) breakLines += $"{line}{Environment.NewLine}"; + var label = new Label (breakLines) { Width = Dim.Fill (), Height = Dim.Fill () }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (label); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, width, height), label.Frame); + Assert.Equal (new Size (width, height), label.TextFormatter.Size); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); + + var expected = @" +┌──────┐ +│文に │ +│は言葉│ +│ があ │ +│り ま │ +│す。 │ +│ │ +│ │ +│ │ +└──────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); + } + + [Fact, AutoInitShutdown] + public void Label_WordWrap_PreserveTrailingSpaces_Vertical_With_Wide_Runes () + { + var text = "文に は言葉 があり ます。"; + var width = 8; + var height = 4; + var wrappedLines = TextFormatter.WordWrapText (text, width, true); + var breakLines = ""; + for (int i = 0; i < wrappedLines.Count; i++) breakLines += $"{wrappedLines [i]}{(i < wrappedLines.Count - 1 ? Environment.NewLine : string.Empty)}"; + var label = new Label (breakLines) { + TextDirection = TextDirection.TopBottom_LeftRight, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (label); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, height + 2); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, width, height), label.Frame); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), frame.Frame); + + var expected = @" +┌────────┐ +│文言あす│ +│に葉り。│ +│ │ +│はがま │ +└────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, height + 2), pos); + } + + + [Fact, AutoInitShutdown] + public void Label_Draw_Horizontal_Simple_TextAlignments_Justified () + { + var text = "01234 01234"; + var width = 20; + var lblJust = new Label (text) { Y = 0, Width = width, TextAlignment = TextAlignment.Justified }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (lblJust); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 3); + + var expected = @" +┌────────────────────┐ +│01234 01234│ +└────────────────────┘ +"; + Assert.Equal (new Rect (0, 0, width, 1), lblJust.Frame); + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, 3), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Horizontal_Simple_Runes () + { + var label = new Label ("Demo Simple Rune"); + Application.Top.Add (label); + Application.Begin (Application.Top); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, 16, 1), label.Frame); + + var expected = @" +Demo Simple Rune +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 16, 1), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Vertical_Simple_Runes () + { + var label = new Label ("Demo Simple Rune") { + TextDirection = TextDirection.TopBottom_LeftRight + }; + Application.Top.Add (label); + Application.Begin (Application.Top); + + Assert.NotNull (label.Width); + Assert.NotNull (label.Height); + + var expected = @" +D +e +m +o + +S +i +m +p +l +e + +R +u +n +e +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 1, 16), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Horizontal_Wide_Runes () + { + var label = new Label ("デモエムポンズ"); + Application.Top.Add (label); + Application.Begin (Application.Top); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, 14, 1), label.Frame); + + var expected = @" +デモエムポンズ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 14, 1), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Vertical_Wide_Runes () + { + var label = new Label ("デモエムポンズ") { + TextDirection = TextDirection.TopBottom_LeftRight + }; + Application.Top.Add (label); + Application.Begin (Application.Top); + + var expected = @" +デ +モ +エ +ム +ポ +ン +ズ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 2, 7), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Vertical_Wide_Runes_With_ForceValidatePosDim () + { + var label = new Label ("デモエムポンズ") { + Width = Dim.Fill (), + Height = Dim.Percent (50f), + TextDirection = TextDirection.TopBottom_LeftRight, + ForceValidatePosDim = true + }; + Application.Top.Add (label); + Application.Begin (Application.Top); + + Assert.True (label.AutoSize); + Assert.Equal (new Rect (0, 0, 80, 12), label.Frame); + + var expected = @" +デ +モ +エ +ム +ポ +ン +ズ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 2, 7), pos); + } + + + [Fact, AutoInitShutdown] + public void Label_Draw_Horizontal_Simple_TextAlignments () + { + var text = "Hello World"; + var width = 20; + var lblLeft = new Label (text) { Width = width }; + var lblCenter = new Label (text) { Y = 1, Width = width, TextAlignment = TextAlignment.Centered }; + var lblRight = new Label (text) { Y = 2, Width = width, TextAlignment = TextAlignment.Right }; + var lblJust = new Label (text) { Y = 3, Width = width, TextAlignment = TextAlignment.Justified }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (lblLeft, lblCenter, lblRight, lblJust); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 6); + + Assert.True (lblLeft.AutoSize); + Assert.True (lblCenter.AutoSize); + Assert.True (lblRight.AutoSize); + Assert.True (lblJust.AutoSize); + Assert.Equal (new Rect (0, 0, width, 1), lblLeft.Frame); + Assert.Equal (new Rect (0, 1, width, 1), lblCenter.Frame); + Assert.Equal (new Rect (0, 2, width, 1), lblRight.Frame); + Assert.Equal (new Rect (0, 3, width, 1), lblJust.Frame); + Assert.Equal (new Rect (0, 0, width + 2, 6), frame.Frame); + + var expected = @" +┌────────────────────┐ +│Hello World │ +│ Hello World │ +│ Hello World│ +│Hello World│ +└────────────────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, 6), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Vertical_Simple_TextAlignments () + { + var text = "Hello World"; + var height = 20; + var lblLeft = new Label (text, direction: TextDirection.TopBottom_LeftRight) { Height = height }; + var lblCenter = new Label (text, direction: TextDirection.TopBottom_LeftRight) { X = 2, Height = height, VerticalTextAlignment = VerticalTextAlignment.Middle }; + var lblRight = new Label (text, direction: TextDirection.TopBottom_LeftRight) { X = 4, Height = height, VerticalTextAlignment = VerticalTextAlignment.Bottom }; + var lblJust = new Label (text, direction: TextDirection.TopBottom_LeftRight) { X = 6, Height = height, VerticalTextAlignment = VerticalTextAlignment.Justified }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (lblLeft, lblCenter, lblRight, lblJust); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (9, height + 2); + + Assert.True (lblLeft.AutoSize); + Assert.True (lblCenter.AutoSize); + Assert.True (lblRight.AutoSize); + Assert.True (lblJust.AutoSize); + Assert.Equal (new Rect (0, 0, 1, height), lblLeft.Frame); + Assert.Equal (new Rect (2, 0, 1, height), lblCenter.Frame); + Assert.Equal (new Rect (4, 0, 1, height), lblRight.Frame); + Assert.Equal (new Rect (6, 0, 1, height), lblJust.Frame); + Assert.Equal (new Rect (0, 0, 9, height + 2), frame.Frame); + + var expected = @" +┌───────┐ +│H H│ +│e e│ +│l l│ +│l l│ +│o H o│ +│ e │ +│W l │ +│o l │ +│r o │ +│l H │ +│d W e │ +│ o l │ +│ r l │ +│ l o │ +│ d │ +│ W W│ +│ o o│ +│ r r│ +│ l l│ +│ d d│ +└───────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 9, height + 2), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Horizontal_Wide_TextAlignments () + { + var text = "こんにちは 世界"; + var width = 25; + var lblLeft = new Label (text) { Width = width }; + var lblCenter = new Label (text) { Y = 1, Width = width, TextAlignment = TextAlignment.Centered }; + var lblRight = new Label (text) { Y = 2, Width = width, TextAlignment = TextAlignment.Right }; + var lblJust = new Label (text) { Y = 3, Width = width, TextAlignment = TextAlignment.Justified }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (lblLeft, lblCenter, lblRight, lblJust); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 6); + + Assert.True (lblLeft.AutoSize); + Assert.True (lblCenter.AutoSize); + Assert.True (lblRight.AutoSize); + Assert.True (lblJust.AutoSize); + Assert.Equal (new Rect (0, 0, width, 1), lblLeft.Frame); + Assert.Equal (new Rect (0, 1, width, 1), lblCenter.Frame); + Assert.Equal (new Rect (0, 2, width, 1), lblRight.Frame); + Assert.Equal (new Rect (0, 3, width, 1), lblJust.Frame); + Assert.Equal (new Rect (0, 0, width + 2, 6), frame.Frame); + + var expected = @" +┌─────────────────────────┐ +│こんにちは 世界 │ +│ こんにちは 世界 │ +│ こんにちは 世界│ +│こんにちは 世界│ +└─────────────────────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, width + 2, 6), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Vertical_Wide_TextAlignments () + { + var text = "こんにちは 世界"; + var height = 23; + var lblLeft = new Label (text) { Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight }; + var lblCenter = new Label (text) { X = 3, Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight, VerticalTextAlignment = VerticalTextAlignment.Middle }; + var lblRight = new Label (text) { X = 6, Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight, VerticalTextAlignment = VerticalTextAlignment.Bottom }; + var lblJust = new Label (text) { X = 9, Width = 2, Height = height, TextDirection = TextDirection.TopBottom_LeftRight, VerticalTextAlignment = VerticalTextAlignment.Justified }; + var frame = new FrameView () { Width = Dim.Fill (), Height = Dim.Fill () }; + + frame.Add (lblLeft, lblCenter, lblRight, lblJust); + Application.Top.Add (frame); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (13, height + 2); + + // All AutoSize are false because the Frame.Height != TextFormatter.Size.Height + Assert.True (lblLeft.AutoSize); + Assert.True (lblCenter.AutoSize); + Assert.True (lblRight.AutoSize); + Assert.True (lblJust.AutoSize); + Assert.Equal (new Rect (0, 0, 2, height), lblLeft.Frame); + Assert.Equal (new Rect (3, 0, 2, height), lblCenter.Frame); + Assert.Equal (new Rect (6, 0, 2, height), lblRight.Frame); + Assert.Equal (new Rect (9, 0, 2, height), lblJust.Frame); + Assert.Equal (new Rect (0, 0, 13, height + 2), frame.Frame); + + var expected = @" +┌───────────┐ +│こ こ│ +│ん ん│ +│に に│ +│ち ち│ +│は は│ +│ │ +│世 │ +│界 こ │ +│ ん │ +│ に │ +│ ち │ +│ は │ +│ │ +│ 世 │ +│ 界 │ +│ こ │ +│ ん │ +│ に │ +│ ち │ +│ は │ +│ │ +│ 世 世│ +│ 界 界│ +└───────────┘ +"; + + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 13, height + 2), pos); + } + + [Fact, AutoInitShutdown] + public void Label_Draw_Fill_Remaining () + { + var view = new View ("This view needs to be cleared before rewritten."); + + var tf1 = new TextFormatter (); + tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten."; + var tf1Size = tf1.Size; + + var tf2 = new TextFormatter (); + tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten."; + var tf2Size = tf2.Size; + + Application.Top.Add (view); + Application.Begin (Application.Top); + + tf1.Draw (new Rect (new Point (0, 1), tf1Size), view.GetNormalColor (), view.ColorScheme.HotNormal, default, false); + + tf2.Draw (new Rect (new Point (0, 2), tf2Size), view.GetNormalColor (), view.ColorScheme.HotNormal); + + TestHelpers.AssertDriverContentsWithFrameAre (@" +This view needs to be cleared before rewritten. +This TextFormatter (tf1) without fill will not be cleared on rewritten. +This TextFormatter (tf2) with fill will be cleared on rewritten. +", output); + + view.Text = "This view is rewritten."; + view.Redraw (view.Bounds); + + tf1.Text = "This TextFormatter (tf1) is rewritten."; + tf1.Draw (new Rect (new Point (0, 1), tf1Size), view.GetNormalColor (), view.ColorScheme.HotNormal, default, false); + + tf2.Text = "This TextFormatter (tf2) is rewritten."; + tf2.Draw (new Rect (new Point (0, 2), tf2Size), view.GetNormalColor (), view.ColorScheme.HotNormal); + + TestHelpers.AssertDriverContentsWithFrameAre (@" +This view is rewritten. +This TextFormatter (tf1) is rewritten.will not be cleared on rewritten. +This TextFormatter (tf2) is rewritten. +", output); + } + + } +} diff --git a/UnitTests/Views/MenuTests.cs b/UnitTests/Views/MenuTests.cs index 567f240e4..68f1a925d 100644 --- a/UnitTests/Views/MenuTests.cs +++ b/UnitTests/Views/MenuTests.cs @@ -1691,7 +1691,7 @@ else Assert.True (mCurrent.MouseEvent (new MouseEvent () { └──────────────────────────────────────┘", output); Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); - top.Redraw (top.Bounds); + Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌──────────────────────────────────────┐ │ File Edit │ diff --git a/UnitTests/Views/ScrollBarViewTests.cs b/UnitTests/Views/ScrollBarViewTests.cs index 5b7ebe664..051f7e48c 100644 --- a/UnitTests/Views/ScrollBarViewTests.cs +++ b/UnitTests/Views/ScrollBarViewTests.cs @@ -825,7 +825,7 @@ namespace Terminal.Gui.ViewsTests { Height = Dim.Fill (), Text = "This is the help text for the Second Step.\n\nPress the button to see a message box.\n\nEnter name too." }; - var win = new Window ("Test") { + var win = new Window () { Width = Dim.Fill (), Height = Dim.Fill () }; @@ -889,7 +889,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (0, scrollBar.Position); Assert.Equal (0, scrollBar.OtherScrollBarView.Position); var expected = @" -┌┤Test├─────────────────────────────────────┐ +┌───────────────────────────────────────────┐ │This is the help text for the Second Step. │ │ │ │Press the button to see a message box. │ @@ -926,7 +926,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (0, scrollBar.Position); Assert.Equal (0, scrollBar.OtherScrollBarView.Position); expected = @" -┌┤Test├──────────────────┐ +┌────────────────────────┐ │This is the help text │ │for the Second Step. │ │ │ @@ -962,7 +962,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (0, scrollBar.Position); Assert.Equal (0, scrollBar.OtherScrollBarView.Position); expected = @" -┌┤Test├──┐ +┌────────┐ │This ▲│ │is the ┬│ │help ││ diff --git a/UnitTests/Views/ScrollViewTests.cs b/UnitTests/Views/ScrollViewTests.cs index 27037dcab..ac9182915 100644 --- a/UnitTests/Views/ScrollViewTests.cs +++ b/UnitTests/Views/ScrollViewTests.cs @@ -524,7 +524,7 @@ namespace Terminal.Gui.ViewsTests { 00000000000000000000000 00000000000000000000000", attributes); - sv.Add (new Window ("1") { X = 3, Y = 3, Width = 20, Height = 20 }); + sv.Add (new Window { X = 3, Y = 3, Width = 20, Height = 20 }); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -534,7 +534,7 @@ namespace Terminal.Gui.ViewsTests { ▲ ┬ ┴ - ┌┤1├──░ + ┌─────░ │ ░ │ ░ │ ░ @@ -617,7 +617,7 @@ namespace Terminal.Gui.ViewsTests { ShowVerticalScrollIndicator = true }; scrollView.Add (view); - var win = new Window (new Rect (1, 1, 20, 14), ""); + var win = new Window (new Rect (1, 1, 20, 14)); win.Add (scrollView); Application.Top.Add (win); Application.Begin (Application.Top); diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index e5bb9201d..3ee4d1577 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -41,7 +41,7 @@ namespace Terminal.Gui.ViewsTests { [Fact] [AutoInitShutdown] - public void Application_Top_EnsureVisibleBounds_To_Driver_Rows_And_Cols () + public void Application_Top_GetLocationThatFits_To_Driver_Rows_And_Cols () { var iterations = 0; @@ -201,7 +201,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (top, Application.Top); // Application.Top without menu and status bar. - var supView = top.EnsureVisibleBounds (top, 2, 2, out int nx, out int ny, out MenuBar mb, out StatusBar sb); + var supView = top.GetLocationThatFits (top, 2, 2, out int nx, out int ny, out MenuBar mb, out StatusBar sb); Assert.Equal (Application.Top, supView); Assert.Equal (0, nx); Assert.Equal (0, ny); @@ -212,7 +212,7 @@ namespace Terminal.Gui.ViewsTests { Assert.NotNull (top.MenuBar); // Application.Top with a menu and without status bar. - top.EnsureVisibleBounds (top, 2, 2, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); Assert.Equal (1, ny); Assert.NotNull (mb); @@ -222,7 +222,7 @@ namespace Terminal.Gui.ViewsTests { Assert.NotNull (top.StatusBar); // Application.Top with a menu and status bar. - top.EnsureVisibleBounds (top, 2, 2, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); // The available height is lower than the Application.Top height minus // the menu bar and status bar, then the top can go beyond the bottom @@ -234,7 +234,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Null (top.MenuBar); // Application.Top without a menu and with a status bar. - top.EnsureVisibleBounds (top, 2, 2, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); // The available height is lower than the Application.Top height minus // the status bar, then the top can go beyond the bottom @@ -251,13 +251,13 @@ namespace Terminal.Gui.ViewsTests { top.LayoutSubviews (); // The SuperView is always the same regardless of the caller. - supView = top.EnsureVisibleBounds (win, 0, 0, out nx, out ny, out mb, out sb); + supView = top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb); Assert.Equal (Application.Top, supView); - supView = win.EnsureVisibleBounds (win, 0, 0, out nx, out ny, out mb, out sb); + supView = win.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb); Assert.Equal (Application.Top, supView); // Application.Top without menu and status bar. - top.EnsureVisibleBounds (win, 0, 0, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); Assert.Equal (0, ny); Assert.Null (mb); @@ -267,7 +267,7 @@ namespace Terminal.Gui.ViewsTests { Assert.NotNull (top.MenuBar); // Application.Top with a menu and without status bar. - top.EnsureVisibleBounds (win, 2, 2, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); Assert.Equal (1, ny); Assert.NotNull (mb); @@ -277,7 +277,7 @@ namespace Terminal.Gui.ViewsTests { Assert.NotNull (top.StatusBar); // Application.Top with a menu and status bar. - top.EnsureVisibleBounds (win, 30, 20, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); // The available height is lower than the Application.Top height minus // the menu bar and status bar, then the top can go beyond the bottom @@ -296,7 +296,7 @@ namespace Terminal.Gui.ViewsTests { top.Add (win); // Application.Top without menu and status bar. - top.EnsureVisibleBounds (win, 0, 0, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb); Assert.Equal (0, nx); Assert.Equal (0, ny); Assert.Null (mb); @@ -306,7 +306,7 @@ namespace Terminal.Gui.ViewsTests { Assert.NotNull (top.MenuBar); // Application.Top with a menu and without status bar. - top.EnsureVisibleBounds (win, 2, 2, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb); Assert.Equal (2, nx); Assert.Equal (2, ny); Assert.NotNull (mb); @@ -316,7 +316,7 @@ namespace Terminal.Gui.ViewsTests { Assert.NotNull (top.StatusBar); // Application.Top with a menu and status bar. - top.EnsureVisibleBounds (win, 30, 20, out nx, out ny, out mb, out sb); + top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb); Assert.Equal (20, nx); // 20+60=80 Assert.Equal (9, ny); // 9+15+1(mb)=25 Assert.NotNull (mb); @@ -341,7 +341,7 @@ namespace Terminal.Gui.ViewsTests { { var isRunning = false; - var win1 = new Window ("Win1") { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () }; + var win1 = new Window () { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () }; var lblTf1W1 = new Label ("Enter text in TextField on Win1:") { Id = "lblTf1W1" }; var tf1W1 = new TextField ("Text1 on Win1") { Id = "tf1W1", X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill () }; var lblTvW1 = new Label ("Enter text in TextView on Win1:") { Id = "lblTvW1", Y = Pos.Bottom (lblTf1W1) + 1 }; @@ -350,7 +350,7 @@ namespace Terminal.Gui.ViewsTests { var tf2W1 = new TextField ("Text2 on Win1") { Id = "tf2W1", X = Pos.Left (tf1W1), Width = Dim.Fill () }; win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1); - var win2 = new Window ("Win2") { Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50f), Height = Dim.Fill () }; + var win2 = new Window () { Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50f), Height = Dim.Fill () }; var lblTf1W2 = new Label ("Enter text in TextField on Win2:") { Id = "lblTf1W2" }; var tf1W2 = new TextField ("Text1 on Win2") { Id = "tf1W2", X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill () }; var lblTvW2 = new Label ("Enter text in TextView on Win2:") { Id = "lblTvW2", Y = Pos.Bottom (lblTf1W2) + 1 }; @@ -453,7 +453,7 @@ namespace Terminal.Gui.ViewsTests { var isRunning = true; - var win1 = new Window ("Win1") { Width = Dim.Percent (50f), Height = Dim.Fill () }; + var win1 = new Window () { Id = "win1", Width = Dim.Percent (50f), Height = Dim.Fill () }; var lblTf1W1 = new Label ("Enter text in TextField on Win1:"); var tf1W1 = new TextField ("Text1 on Win1") { X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill () }; var lblTvW1 = new Label ("Enter text in TextView on Win1:") { Y = Pos.Bottom (lblTf1W1) + 1 }; @@ -462,7 +462,7 @@ namespace Terminal.Gui.ViewsTests { var tf2W1 = new TextField ("Text2 on Win1") { X = Pos.Left (tf1W1), Width = Dim.Fill () }; win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1); - var win2 = new Window ("Win2") { Width = Dim.Percent (50f), Height = Dim.Fill () }; + var win2 = new Window () { Id = "win2", Width = Dim.Percent (50f), Height = Dim.Fill () }; var lblTf1W2 = new Label ("Enter text in TextField on Win2:"); var tf1W2 = new TextField ("Text1 on Win2") { X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill () }; var lblTvW2 = new Label ("Enter text in TextView on Win2:") { Y = Pos.Bottom (lblTf1W2) + 1 }; @@ -666,16 +666,6 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); } - [Fact] - [AutoInitShutdown] - public void FileDialog_FileSystemWatcher () - { - for (int i = 0; i < 8; i++) { - var fd = new FileDialog (); - fd.Ready += (s, e) => Application.RequestStop (); - Application.Run (fd); - } - } [Fact, AutoInitShutdown] public void Mouse_Drag_On_Top_With_Superview_Null () @@ -825,8 +815,8 @@ namespace Terminal.Gui.ViewsTests { var win = new Window () { X = 3, Y = 2, - Width = Dim.Fill (10), - Height = Dim.Fill (5) + Width = 10, + Height = 5 }; var top = Application.Top; top.Add (win); @@ -841,7 +831,9 @@ namespace Terminal.Gui.ViewsTests { Application.Iteration = () => { iterations++; if (iterations == 0) { - ((FakeDriver)Application.Driver).SetBufferSize (20, 10); + ((FakeDriver)Application.Driver).SetBufferSize (30, 10); + } else if (iterations == 1) { + location = win.Frame; Assert.Null (Application.MouseGrabView); // Grab the mouse @@ -856,8 +848,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (win, Application.MouseGrabView); Assert.Equal (location, Application.MouseGrabView.Frame); - - } else if (iterations == 1) { + } else if (iterations == 2) { Assert.Equal (win, Application.MouseGrabView); // Drag to left movex = 1; @@ -873,14 +864,14 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (win, Application.MouseGrabView); - } else if (iterations == 2) { + } else if (iterations == 3) { // we should have moved +1, +0 Assert.Equal (win, Application.MouseGrabView); Assert.Equal (win, Application.MouseGrabView); location.Offset (movex, movey); Assert.Equal (location, Application.MouseGrabView.Frame); - } else if (iterations == 3) { + } else if (iterations == 4) { Assert.Equal (win, Application.MouseGrabView); // Drag up movex = 0; @@ -896,13 +887,13 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (win, Application.MouseGrabView); - } else if (iterations == 4) { + } else if (iterations == 5) { // we should have moved +0, -1 Assert.Equal (win, Application.MouseGrabView); location.Offset (movex, movey); Assert.Equal (location, Application.MouseGrabView.Frame); - } else if (iterations == 5) { + } else if (iterations == 6) { Assert.Equal (win, Application.MouseGrabView); // Ungrab the mouse movex = 0; @@ -917,7 +908,7 @@ namespace Terminal.Gui.ViewsTests { }); Assert.Null (Application.MouseGrabView); - } else if (iterations == 8) { + } else if (iterations == 7) { Application.RequestStop (); } }; @@ -926,7 +917,7 @@ namespace Terminal.Gui.ViewsTests { } [Fact, AutoInitShutdown] - public void EnsureVisibleBounds_With_Border_Null_Not_Throws () + public void GetLocationThatFits_With_Border_Null_Not_Throws () { var top = new Toplevel (); Application.Begin (top); @@ -1052,7 +1043,7 @@ namespace Terminal.Gui.ViewsTests { Height = 16, ContentSize = new Size (200, 100) }; - var win = new Window ("Window") { X = 3, Y = 3, Width = Dim.Fill (3), Height = Dim.Fill (3) }; + var win = new Window () { X = 3, Y = 3, Width = Dim.Fill (3), Height = Dim.Fill (3) }; scrollView.Add (win); var top = Application.Top; top.Add (scrollView); @@ -1066,7 +1057,7 @@ namespace Terminal.Gui.ViewsTests { ▲ ┬ │ - ┌┤Window├───────────────────────────┴ + ┌───────────────────────────────────┴ │ ░ │ ░ │ ░ @@ -1111,7 +1102,7 @@ namespace Terminal.Gui.ViewsTests { ┴ ░ ░ - ┌┤Window├────────────────────────░ + ┌────────────────────────────────░ │ ░ │ ░ │ ░ @@ -1138,7 +1129,7 @@ namespace Terminal.Gui.ViewsTests { TestHelpers.AssertDriverContentsWithFrameAre (@" ▲ ┬ - ┌┤Window├────────────────────────────│ + ┌────────────────────────────────────│ │ ┴ │ ░ │ ░ @@ -1178,7 +1169,7 @@ namespace Terminal.Gui.ViewsTests { public void Dialog_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Left_Right_And_Bottom () { var top = Application.Top; - var dialog = new Dialog ("", 20, 3, new Button ("Ok")); + var dialog = new Dialog (new Button ("Ok")) { Width = 20, Height = 3 }; Application.Begin (top); ((FakeDriver)Application.Driver).SetBufferSize (40, 10); Application.Begin (dialog); @@ -1295,7 +1286,7 @@ namespace Terminal.Gui.ViewsTests { [Fact, AutoInitShutdown] public void Single_Smaller_Top_Will_Have_Cleaning_Trails_Chunk_On_Move () { - var dialog = new Dialog ("Single smaller Dialog") { Width = 30, Height = 10 }; + var dialog = new Dialog () { Width = 30, Height = 10 }; dialog.Add (new Label ( "How should I've to react. Cleaning all chunk trails or setting the 'Cols' and 'Rows' to this dialog length?\n" + "Cleaning is more easy to fix this.") { @@ -1313,7 +1304,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Null (Application.MouseGrabView); Assert.Equal (new Rect (25, 7, 30, 10), dialog.Frame); TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤Single smaller Dialog├─────┐ + ┌────────────────────────────┐ │ How should I've to react. │ │Cleaning all chunk trails or│ │ setting the 'Cols' and │ @@ -1339,7 +1330,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (new Rect (25, 7, 30, 10), dialog.Frame); TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤Single smaller Dialog├─────┐ + ┌────────────────────────────┐ │ How should I've to react. │ │Cleaning all chunk trails or│ │ setting the 'Cols' and │ @@ -1364,7 +1355,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (dialog, Application.MouseGrabView); Assert.Equal (new Rect (20, 10, 30, 10), dialog.Frame); TestHelpers.AssertDriverContentsWithFrameAre (@" - ┌┤Single smaller Dialog├─────┐ + ┌────────────────────────────┐ │ How should I've to react. │ │Cleaning all chunk trails or│ │ setting the 'Cols' and │ @@ -1418,7 +1409,7 @@ namespace Terminal.Gui.ViewsTests { Y = viewToScreen.Y + 1, Width = 18, Height = 5, - Border = new Border () { BorderStyle = BorderStyle.Single } + BorderStyle = LineStyle.Single }; Application.Current.DrawContentComplete += Current_DrawContentComplete; top.Add (view); @@ -1441,7 +1432,7 @@ namespace Terminal.Gui.ViewsTests { Application.Current.DrawContentComplete -= Current_DrawContentComplete; } }; - var dialog = new Dialog ("", 15, 10, btnPopup); + var dialog = new Dialog (btnPopup) { Width = 15, Height = 10 }; var rs = Application.Begin (dialog); Assert.Equal (new Rect (2, 5, 15, 10), dialog.Frame); diff --git a/UnitTests/Views/WindowTests.cs b/UnitTests/Views/WindowTests.cs index 04c2f4916..271fc59ac 100644 --- a/UnitTests/Views/WindowTests.cs +++ b/UnitTests/Views/WindowTests.cs @@ -45,7 +45,7 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection); // Empty Rect - r = new Window (Rect.Empty, "title"); + r = new Window (Rect.Empty) { Title = "title" }; Assert.NotNull (r); Assert.Equal ("title", r.Title); Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle); @@ -69,14 +69,14 @@ namespace Terminal.Gui.ViewsTests { Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection); // Rect with values - r = new Window (new Rect (1, 2, 3, 4), "title"); + r = new Window (new Rect (1, 2, 3, 4)) { Title = "title" }; Assert.Equal ("title", r.Title); Assert.NotNull (r); Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle); Assert.Equal ("Window(title)({X=1,Y=2,Width=3,Height=4})", r.ToString ()); Assert.True (r.CanFocus); Assert.False (r.HasFocus); - Assert.Equal (new Rect (0, 0, 3, 4), r.Bounds); + Assert.Equal (new Rect (0, 0, 1, 2), r.Bounds); Assert.Equal (new Rect (1, 2, 3, 4), r.Frame); Assert.Null (r.Focused); Assert.NotNull (r.ColorScheme);