2
0
Эх сурвалжийг харах

All unit tests pass.
Made TextFormatter have independent Width/Height.

Tig 1 жил өмнө
parent
commit
b4e1b3ec5e

+ 38 - 23
Terminal.Gui/Text/TextFormatter.cs

@@ -17,7 +17,7 @@ public class TextFormatter
     private bool _multiLine;
     private bool _multiLine;
     private bool _preserveTrailingSpaces;
     private bool _preserveTrailingSpaces;
     private int _tabWidth = 4;
     private int _tabWidth = 4;
-    private string _text;
+    private string? _text;
     private Alignment _textAlignment = Alignment.Start;
     private Alignment _textAlignment = Alignment.Start;
     private TextDirection _textDirection;
     private TextDirection _textDirection;
     private Alignment _textVerticalAlignment = Alignment.Start;
     private Alignment _textVerticalAlignment = Alignment.Start;
@@ -49,6 +49,11 @@ public class TextFormatter
             {
             {
                 Size = GetAutoSize ();
                 Size = GetAutoSize ();
             }
             }
+            else
+            {
+                Height = null;
+                Width = null;
+            }
         }
         }
     }
     }
 
 
@@ -188,13 +193,18 @@ public class TextFormatter
             {
             {
                 return;
                 return;
             }
             }
+
+            if (value < 0)
+            {
+                throw  new ArgumentOutOfRangeException (nameof (Width), value, @"Must be greater than or equal to 0.");
+            }
+
             _width = value;
             _width = value;
             if (_width is null || _height is null)
             if (_width is null || _height is null)
             {
             {
                 return;
                 return;
             }
             }
-            Size size = EnableNeedsFormat (Size!.Value);
-            _width = size.Width;
+            _width = EnableNeedsFormat (value);
         }
         }
     }
     }
 
 
@@ -209,13 +219,18 @@ public class TextFormatter
             {
             {
                 return;
                 return;
             }
             }
+
+            if (value < 0)
+            {
+                throw new ArgumentOutOfRangeException (nameof (Width), value, @"Must be greater than or equal to 0.");
+            }
+
             _height = value;
             _height = value;
             if (_width is null || _height is null)
             if (_width is null || _height is null)
             {
             {
                 return;
                 return;
             }
             }
-            Size size = EnableNeedsFormat (Size!.Value);
-            _height = size.Height;
+            _height = EnableNeedsFormat (value);
         }
         }
     }
     }
 
 
@@ -273,7 +288,7 @@ public class TextFormatter
     /// <summary>The text to be formatted. This string is never modified.</summary>
     /// <summary>The text to be formatted. This string is never modified.</summary>
     public virtual string Text
     public virtual string Text
     {
     {
-        get => _text;
+        get => _text!;
         set
         set
         {
         {
             _text = EnableNeedsFormat (value);
             _text = EnableNeedsFormat (value);
@@ -316,7 +331,7 @@ public class TextFormatter
         Attribute normalColor,
         Attribute normalColor,
         Attribute hotColor,
         Attribute hotColor,
         Rectangle maximum = default,
         Rectangle maximum = default,
-        ConsoleDriver driver = null
+        ConsoleDriver? driver = null
     )
     )
     {
     {
         // With this check, we protect against subclasses with overrides of Text (like Button)
         // With this check, we protect against subclasses with overrides of Text (like Button)
@@ -788,7 +803,7 @@ public class TextFormatter
     public List<string> GetLines ()
     public List<string> GetLines ()
     {
     {
         // With this check, we protect against subclasses with overrides of Text
         // With this check, we protect against subclasses with overrides of Text
-        if (string.IsNullOrEmpty (Text) || Size is null || Size?.Height == 0 || Size?.Width == 0)
+        if (string.IsNullOrEmpty (Text) || Width is null || Width == 0 || Height is null || Height == 0)
         {
         {
             _lines = new List<string> { string.Empty };
             _lines = new List<string> { string.Empty };
             NeedsFormat = false;
             NeedsFormat = false;
@@ -798,9 +813,9 @@ public class TextFormatter
 
 
         if (NeedsFormat)
         if (NeedsFormat)
         {
         {
-            string text = _text;
+            string text = _text!;
 
 
-            if (FindHotKey (_text, HotKeySpecifier, out _hotKeyPos, out Key newHotKey))
+            if (FindHotKey (_text!, HotKeySpecifier, out _hotKeyPos, out Key newHotKey))
             {
             {
                 HotKey = newHotKey;
                 HotKey = newHotKey;
                 text = RemoveHotKeySpecifier (Text, _hotKeyPos, HotKeySpecifier);
                 text = RemoveHotKeySpecifier (Text, _hotKeyPos, HotKeySpecifier);
@@ -813,9 +828,9 @@ public class TextFormatter
 
 
                 _lines = Format (
                 _lines = Format (
                                  text,
                                  text,
-                                 Size!.Value.Height,
+                                 Height.Value,
                                  VerticalAlignment == Alignment.Fill,
                                  VerticalAlignment == Alignment.Fill,
-                                 Size!.Value.Width > colsWidth && WordWrap,
+                                 Width.Value > colsWidth && WordWrap,
                                  PreserveTrailingSpaces,
                                  PreserveTrailingSpaces,
                                  TabWidth,
                                  TabWidth,
                                  Direction,
                                  Direction,
@@ -825,7 +840,7 @@ public class TextFormatter
 
 
                 if (!AutoSize)
                 if (!AutoSize)
                 {
                 {
-                    colsWidth = GetMaxColsForWidth (_lines, Size!.Value.Width, TabWidth);
+                    colsWidth = GetMaxColsForWidth (_lines, Width.Value, TabWidth);
 
 
                     if (_lines.Count > colsWidth)
                     if (_lines.Count > colsWidth)
                     {
                     {
@@ -837,9 +852,9 @@ public class TextFormatter
             {
             {
                 _lines = Format (
                 _lines = Format (
                                  text,
                                  text,
-                                 Size!.Value.Width,
+                                 Width.Value,
                                  Alignment == Alignment.Fill,
                                  Alignment == Alignment.Fill,
-                                 Size!.Value.Height > 1 && WordWrap,
+                                 Height.Value > 1 && WordWrap,
                                  PreserveTrailingSpaces,
                                  PreserveTrailingSpaces,
                                  TabWidth,
                                  TabWidth,
                                  Direction,
                                  Direction,
@@ -847,9 +862,9 @@ public class TextFormatter
                                  this
                                  this
                                 );
                                 );
 
 
-                if (!AutoSize && _lines.Count > Size!.Value.Height)
+                if (!AutoSize && _lines.Count > Height.Value)
                 {
                 {
-                    _lines.RemoveRange (Size!.Value.Height, _lines.Count -  Size!.Value.Height);
+                    _lines.RemoveRange (Height.Value, _lines.Count -  Height.Value);
                 }
                 }
             }
             }
 
 
@@ -860,7 +875,7 @@ public class TextFormatter
     }
     }
 
 
     /// <summary>Event invoked when the <see cref="HotKey"/> is changed.</summary>
     /// <summary>Event invoked when the <see cref="HotKey"/> is changed.</summary>
-    public event EventHandler<KeyChangedEventArgs> HotKeyChanged;
+    public event EventHandler<KeyChangedEventArgs>? HotKeyChanged;
 
 
     /// <summary>Sets <see cref="NeedsFormat"/> to <see langword="true"/> and returns the value.</summary>
     /// <summary>Sets <see cref="NeedsFormat"/> to <see langword="true"/> and returns the value.</summary>
     /// <typeparam name="T"></typeparam>
     /// <typeparam name="T"></typeparam>
@@ -1128,7 +1143,7 @@ public class TextFormatter
         bool preserveTrailingSpaces = false,
         bool preserveTrailingSpaces = false,
         int tabWidth = 0,
         int tabWidth = 0,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
-        TextFormatter textFormatter = null
+        TextFormatter? textFormatter = null
     )
     )
     {
     {
         if (width < 0)
         if (width < 0)
@@ -1375,7 +1390,7 @@ public class TextFormatter
         Alignment textAlignment,
         Alignment textAlignment,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         int tabWidth = 0,
         int tabWidth = 0,
-        TextFormatter textFormatter = null
+        TextFormatter? textFormatter = null
     )
     )
     {
     {
         return ClipAndJustify (text, width, textAlignment == Alignment.Fill, textDirection, tabWidth, textFormatter);
         return ClipAndJustify (text, width, textAlignment == Alignment.Fill, textDirection, tabWidth, textFormatter);
@@ -1398,7 +1413,7 @@ public class TextFormatter
         bool justify,
         bool justify,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         int tabWidth = 0,
         int tabWidth = 0,
-        TextFormatter textFormatter = null
+        TextFormatter? textFormatter = null
     )
     )
     {
     {
         if (width < 0)
         if (width < 0)
@@ -1619,7 +1634,7 @@ public class TextFormatter
         int tabWidth = 0,
         int tabWidth = 0,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         bool multiLine = false,
         bool multiLine = false,
-        TextFormatter textFormatter = null
+        TextFormatter? textFormatter = null
     )
     )
     {
     {
         return Format (
         return Format (
@@ -1667,7 +1682,7 @@ public class TextFormatter
         int tabWidth = 0,
         int tabWidth = 0,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         TextDirection textDirection = TextDirection.LeftRight_TopBottom,
         bool multiLine = false,
         bool multiLine = false,
-        TextFormatter textFormatter = null
+        TextFormatter? textFormatter = null
     )
     )
     {
     {
         if (width < 0)
         if (width < 0)

+ 8 - 8
Terminal.Gui/View/Layout/DimAuto.cs

@@ -63,8 +63,8 @@ public class DimAuto () : Dim
         var maxCalculatedSize = 0;
         var maxCalculatedSize = 0;
 
 
         int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
         int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
-        int screen = dimension == Dimension.Width ? Application.Screen.Width * 4 : Application.Screen.Height * 4;
-        int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? screen;
+        int screenX4 = dimension == Dimension.Width ? Application.Screen.Width * 4 : Application.Screen.Height * 4;
+        int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? screenX4;
 
 
         Debug.Assert (autoMin <= autoMax, "MinimumContentDim must be less than or equal to MaximumContentDim.");
         Debug.Assert (autoMin <= autoMax, "MinimumContentDim must be less than or equal to MaximumContentDim.");
 
 
@@ -75,7 +75,7 @@ public class DimAuto () : Dim
             {
             {
                 if (us.TextFormatter.Width is null)
                 if (us.TextFormatter.Width is null)
                 {
                 {
-                    us.TextFormatter.Size = us.TextFormatter.FormatAndGetSize (new (int.Max (autoMax, superviewContentSize), screen));
+                    us.TextFormatter.Size = us.TextFormatter.FormatAndGetSize (new (int.Min (autoMax, screenX4), screenX4));
                 }
                 }
 //                else
 //                else
                 {
                 {
@@ -86,7 +86,7 @@ public class DimAuto () : Dim
             {
             {
                 if (us.TextFormatter.Height is null)
                 if (us.TextFormatter.Height is null)
                 {
                 {
-                    textSize = us.TextFormatter.FormatAndGetSize (new (us.TextFormatter.Width ?? screen, int.Max (autoMax, superviewContentSize))).Height;
+                    textSize = us.TextFormatter.FormatAndGetSize (new (us.TextFormatter.Width ?? screenX4, int.Min (autoMax, screenX4))).Height;
                     us.TextFormatter.Height = textSize;
                     us.TextFormatter.Height = textSize;
                 }
                 }
                 else
                 else
@@ -241,12 +241,12 @@ public class DimAuto () : Dim
 
 
                     if (dimension == Dimension.Width)
                     if (dimension == Dimension.Width)
                     {
                     {
-                        int width = v.Width!.Calculate (0, screen, v, dimension);
+                        int width = v.Width!.Calculate (0, screenX4, v, dimension);
                         maxCentered = (v.X.GetAnchor (0) + width);
                         maxCentered = (v.X.GetAnchor (0) + width);
                     }
                     }
                     else
                     else
                     {
                     {
-                        int height = v.Height!.Calculate (0, screen, v, dimension);
+                        int height = v.Height!.Calculate (0, screenX4, v, dimension);
                         maxCentered = (v.Y.GetAnchor (0) + height);
                         maxCentered = (v.Y.GetAnchor (0) + height);
                     }
                     }
                 }
                 }
@@ -364,11 +364,11 @@ public class DimAuto () : Dim
                     // Need to set the relative layout for PosAnchorEnd subviews to calculate the size
                     // Need to set the relative layout for PosAnchorEnd subviews to calculate the size
                     if (dimension == Dimension.Width)
                     if (dimension == Dimension.Width)
                     {
                     {
-                        v.SetRelativeLayout (new Size (maxCalculatedSize, screen));
+                        v.SetRelativeLayout (new Size (maxCalculatedSize, screenX4));
                     }
                     }
                     else
                     else
                     {
                     {
-                        v.SetRelativeLayout (new Size (screen, maxCalculatedSize));
+                        v.SetRelativeLayout (new Size (screenX4, maxCalculatedSize));
                     }
                     }
                     maxAnchorEnd = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize + v.Frame.Width) : v.Y.GetAnchor (maxCalculatedSize + v.Frame.Height);
                     maxAnchorEnd = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize + v.Frame.Width) : v.Y.GetAnchor (maxCalculatedSize + v.Frame.Height);
                 }
                 }

+ 4 - 0
Terminal.Gui/View/Layout/DimAutoStyle.cs

@@ -33,6 +33,10 @@ public enum DimAutoStyle
     ///     <para>
     ///     <para>
     ///         The corresponding dimensions of <see cref="View.GetContentSize ()"/> and/or <see cref="View.Subviews"/> will be ignored.
     ///         The corresponding dimensions of <see cref="View.GetContentSize ()"/> and/or <see cref="View.Subviews"/> will be ignored.
     ///     </para>
     ///     </para>
+    ///     <para>
+    ///         If <see cref="DimAuto.MaximumContentDim"/> is set, the dimension will be the maximum of the formatted text and the
+    ///         demension provided by <see cref="DimAuto.MaximumContentDim"/>. Otherwise, the dimension will be that of the formatted text.
+    ///     </para>
     /// </summary>
     /// </summary>
     Text = 2,
     Text = 2,
 
 

+ 21 - 10
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -65,8 +65,6 @@ public partial class View
         // This is the only place where _frame should be set directly. Use Frame = or SetFrame instead.
         // This is the only place where _frame should be set directly. Use Frame = or SetFrame instead.
         _frame = frame;
         _frame = frame;
 
 
-        SetTextFormatterSize ();
-
         OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport));
         OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport));
     }
     }
 
 
@@ -235,7 +233,7 @@ public partial class View
                 return;
                 return;
             }
             }
 
 
-            if (_height is DimAuto)
+            if (_height is { } && _height.Has (typeof (DimAuto), out _))
             {
             {
                 // Reset ContentSize to Viewport
                 // Reset ContentSize to Viewport
                 _contentSize = null;
                 _contentSize = null;
@@ -243,6 +241,9 @@ public partial class View
 
 
             _height = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Height)} cannot be null");
             _height = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Height)} cannot be null");
 
 
+            // Reset TextFormatter - Will be recalculated in SetTextFormatterSize
+            TextFormatter.Height = null;
+
             OnResizeNeeded ();
             OnResizeNeeded ();
         }
         }
     }
     }
@@ -280,7 +281,7 @@ public partial class View
                 return;
                 return;
             }
             }
 
 
-            if (_width is DimAuto)
+            if (_width is { } && _width.Has (typeof (DimAuto), out _))
             {
             {
                 // Reset ContentSize to Viewport
                 // Reset ContentSize to Viewport
                 _contentSize = null;
                 _contentSize = null;
@@ -288,6 +289,9 @@ public partial class View
 
 
             _width = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Width)} cannot be null");
             _width = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Width)} cannot be null");
 
 
+            // Reset TextFormatter - Will be recalculated in SetTextFormatterSize
+            TextFormatter.Width = null;
+
             OnResizeNeeded ();
             OnResizeNeeded ();
         }
         }
     }
     }
@@ -576,7 +580,6 @@ public partial class View
         SetTextFormatterSize ();
         SetTextFormatterSize ();
 
 
         int newX, newW, newY, newH;
         int newX, newW, newY, newH;
-        Rectangle oldFrame = Frame;
 
 
         // Calculate the new X, Y, Width, and Height
         // Calculate the new X, Y, Width, and Height
         // If the Width or Height is Dim.Auto, calculate the Width or Height first. Otherwise, calculate the X or Y first.
         // If the Width or Height is Dim.Auto, calculate the Width or Height first. Otherwise, calculate the X or Y first.
@@ -584,7 +587,6 @@ public partial class View
         {
         {
             newW = _width.Calculate (0, superviewContentSize.Width, this, Dimension.Width);
             newW = _width.Calculate (0, superviewContentSize.Width, this, Dimension.Width);
             newX = _x.Calculate (superviewContentSize.Width, newW, this, Dimension.Width);
             newX = _x.Calculate (superviewContentSize.Width, newW, this, Dimension.Width);
-            //SetFrame (oldFrame with { X = newX, Width = newW });
         }
         }
         else
         else
         {
         {
@@ -603,8 +605,6 @@ public partial class View
             newH = _height.Calculate (newY, superviewContentSize.Height, this, Dimension.Height);
             newH = _height.Calculate (newY, superviewContentSize.Height, this, Dimension.Height);
         }
         }
 
 
-        SetFrame (oldFrame);
-
         Rectangle newFrame = new (newX, newY, newW, newH);
         Rectangle newFrame = new (newX, newY, newW, newH);
 
 
         if (Frame != newFrame)
         if (Frame != newFrame)
@@ -636,9 +636,21 @@ public partial class View
             {
             {
                 SetTitleTextFormatterSize ();
                 SetTitleTextFormatterSize ();
             }
             }
+
             SetNeedsLayout ();
             SetNeedsLayout ();
             SetNeedsDisplay ();
             SetNeedsDisplay ();
         }
         }
+
+        if (TextFormatter.Width is null)
+        {
+            TextFormatter.Width = GetContentSize ().Width;
+        }
+
+        if (TextFormatter.Height is null)
+        {
+            TextFormatter.Height = GetContentSize ().Height;
+        }
+
     }
     }
 
 
 
 
@@ -671,7 +683,7 @@ public partial class View
 
 
         LayoutAdornments ();
         LayoutAdornments ();
 
 
-        SetTextFormatterSize ();
+        //SetTextFormatterSize ();
 
 
         // Sort out the dependencies of the X, Y, Width, Height properties
         // Sort out the dependencies of the X, Y, Width, Height properties
         HashSet<View> nodes = new ();
         HashSet<View> nodes = new ();
@@ -747,7 +759,6 @@ public partial class View
                            Application.Top is { } && Application.Top != this && Application.Top.IsInitialized ? Application.Top.GetContentSize () :
                            Application.Top is { } && Application.Top != this && Application.Top.IsInitialized ? Application.Top.GetContentSize () :
                            Application.Screen.Size;
                            Application.Screen.Size;
 
 
-        SetTextFormatterSize ();
         SetRelativeLayout (superViewContentSize);
         SetRelativeLayout (superViewContentSize);
 
 
         if (IsInitialized)
         if (IsInitialized)

+ 23 - 10
Terminal.Gui/View/ViewText.cs

@@ -1,5 +1,6 @@
 #nullable enable
 #nullable enable
 
 
+using System.Diagnostics;
 using static Unix.Terminal.Curses;
 using static Unix.Terminal.Curses;
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
@@ -88,6 +89,7 @@ public partial class View
     /// </summary>
     /// </summary>
     public event EventHandler? TextChanged;
     public event EventHandler? TextChanged;
 
 
+    // TODO: Make this non-virtual. Nobody overrides it.
     /// <summary>
     /// <summary>
     ///     Gets or sets how the View's <see cref="Text"/> is aligned horizontally when drawn. Changing this property will
     ///     Gets or sets how the View's <see cref="Text"/> is aligned horizontally when drawn. Changing this property will
     ///     redisplay the <see cref="View"/>.
     ///     redisplay the <see cref="View"/>.
@@ -107,6 +109,7 @@ public partial class View
         }
         }
     }
     }
 
 
+    // TODO: Make this non-virtual. Nobody overrides it.
     /// <summary>
     /// <summary>
     ///     Gets or sets the direction of the View's <see cref="Text"/>. Changing this property will redisplay the
     ///     Gets or sets the direction of the View's <see cref="Text"/>. Changing this property will redisplay the
     ///     <see cref="View"/>.
     ///     <see cref="View"/>.
@@ -118,11 +121,7 @@ public partial class View
     public virtual TextDirection TextDirection
     public virtual TextDirection TextDirection
     {
     {
         get => TextFormatter.Direction;
         get => TextFormatter.Direction;
-        set
-        {
-            UpdateTextDirection (value);
-            TextFormatter.Direction = value;
-        }
+        set => UpdateTextDirection (value);
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -130,6 +129,7 @@ public partial class View
     /// </summary>
     /// </summary>
     public TextFormatter TextFormatter { get; init; } = new () { };
     public TextFormatter TextFormatter { get; init; } = new () { };
 
 
+    // TODO: Make this non-virtual. Nobody overrides it.
     /// <summary>
     /// <summary>
     ///     Gets or sets how the View's <see cref="Text"/> is aligned vertically when drawn. Changing this property will
     ///     Gets or sets how the View's <see cref="Text"/> is aligned vertically when drawn. Changing this property will
     ///     redisplay
     ///     redisplay
@@ -149,6 +149,7 @@ public partial class View
         }
         }
     }
     }
 
 
+    // TODO: Add a OnUpdateTextFormatterText method that invokes UpdateTextFormatterText so that overrides don't have to call base.
     /// <summary>
     /// <summary>
     ///     Can be overridden if the <see cref="Terminal.Gui.TextFormatter.Text"/> has
     ///     Can be overridden if the <see cref="Terminal.Gui.TextFormatter.Text"/> has
     ///     different format than the default.
     ///     different format than the default.
@@ -158,6 +159,8 @@ public partial class View
         if (TextFormatter is { })
         if (TextFormatter is { })
         {
         {
             TextFormatter.Text = _text;
             TextFormatter.Text = _text;
+            TextFormatter.Width = null;
+            TextFormatter.Height = null;
         }
         }
     }
     }
 
 
@@ -178,7 +181,7 @@ public partial class View
         UpdateTextFormatterText ();
         UpdateTextFormatterText ();
 
 
         // Default is to use GetContentSize ().
         // Default is to use GetContentSize ().
-        var size = GetContentSize ();
+        Size? size = _contentSize;
 
 
         // TODO: This is a hack. Figure out how to move this logic into DimAuto
         // TODO: This is a hack. Figure out how to move this logic into DimAuto
         // Use _width & _height instead of Width & Height to avoid debug spew
         // Use _width & _height instead of Width & Height to avoid debug spew
@@ -188,15 +191,24 @@ public partial class View
         {
         {
             TextFormatter.Width = null;
             TextFormatter.Width = null;
         }
         }
+        else
+        {
+            if (size is { })
+            {
+                TextFormatter.Width = size?.Width;
+            }
+        }
 
 
         if ((heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text)))
         if ((heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text)))
         {
         {
             TextFormatter.Height = null;
             TextFormatter.Height = null;
         }
         }
-
-        if (TextFormatter.Size is { })
+        else
         {
         {
-            TextFormatter.Size = size;
+            if (size is { })
+            {
+                TextFormatter.Height = size?.Height;
+            }
         }
         }
     }
     }
 
 
@@ -209,10 +221,11 @@ public partial class View
 
 
         if (directionChanged)
         if (directionChanged)
         {
         {
+            TextFormatter.Width = null;
+            TextFormatter.Height = null;
             OnResizeNeeded ();
             OnResizeNeeded ();
         }
         }
 
 
-        SetTextFormatterSize ();
         SetNeedsDisplay ();
         SetNeedsDisplay ();
     }
     }
 }
 }

+ 1 - 0
Terminal.Gui/Views/Button.cs

@@ -170,6 +170,7 @@ public class Button : View, IDesignable
     /// <inheritdoc/>
     /// <inheritdoc/>
     protected override void UpdateTextFormatterText ()
     protected override void UpdateTextFormatterText ()
     {
     {
+        base.UpdateTextFormatterText();
         if (NoDecorations)
         if (NoDecorations)
         {
         {
             TextFormatter.Text = Text;
             TextFormatter.Text = Text;

+ 1 - 0
Terminal.Gui/Views/CheckBox.cs

@@ -182,6 +182,7 @@ public class CheckBox : View
     /// <inheritdoc/>
     /// <inheritdoc/>
     protected override void UpdateTextFormatterText ()
     protected override void UpdateTextFormatterText ()
     {
     {
+        base.UpdateTextFormatterText();
         switch (TextAlignment)
         switch (TextAlignment)
         {
         {
             case Alignment.Start:
             case Alignment.Start:

+ 0 - 1
Terminal.Gui/Views/ScrollView.cs

@@ -623,7 +623,6 @@ public class ScrollView : View
         {
         {
             _horizontal.Position = Math.Max (0, -_contentOffset.X);
             _horizontal.Position = Math.Max (0, -_contentOffset.X);
         }
         }
-
         SetNeedsDisplay ();
         SetNeedsDisplay ();
     }
     }
 
 

+ 1 - 1
UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs

@@ -306,7 +306,7 @@ public partial class DimAutoTests
     [Theory]
     [Theory]
     [InlineData (0, 10, 0, 10, 10, 2)]
     [InlineData (0, 10, 0, 10, 10, 2)]
     [InlineData (0, 5, 0, 5, 5, 3)] // max width of 5 should cause wordwrap at 5 giving a height of 2 + 1
     [InlineData (0, 5, 0, 5, 5, 3)] // max width of 5 should cause wordwrap at 5 giving a height of 2 + 1
-    //[InlineData (0, 19, 0, 9, 19, 9)]
+    [InlineData (0, 19, 0, 9, 11, 2)]
     //[InlineData (0, 20, 0, 10, 20, 10)]
     //[InlineData (0, 20, 0, 10, 20, 10)]
     //[InlineData (0, 21, 0, 11, 21, 11)]
     //[InlineData (0, 21, 0, 11, 21, 11)]
     //[InlineData (1, 21, 1, 11, 21, 11)]
     //[InlineData (1, 21, 1, 11, 21, 11)]

+ 55 - 4
UnitTests/View/Layout/Dim.AutoTests.cs

@@ -528,6 +528,25 @@ public partial class DimAutoTests (ITestOutputHelper output)
 
 
     #region DimAutoStyle.Auto tests
     #region DimAutoStyle.Auto tests
 
 
+    [Theory]
+    [InlineData ("", 0, 0)]
+    [InlineData (" ", 1, 1)]
+    [InlineData ("01234", 5, 1)]
+    [InlineData ("01234\nABCDE", 5, 2)]
+    public void DimAutoStyle_Auto_JustText_Sizes_Correctly (string text, int expectedW, int expectedH)
+    {
+        var view = new View ();
+        view.Width = Auto ();
+        view.Height = Auto ();
+
+        view.Text = text;
+
+        view.SetRelativeLayout (Application.Screen.Size);
+
+        Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
+
+    }
+
     [Fact]
     [Fact]
     public void DimAutoStyle_Auto_Text_Size_Is_Used ()
     public void DimAutoStyle_Auto_Text_Size_Is_Used ()
     {
     {
@@ -622,6 +641,7 @@ public partial class DimAutoTests (ITestOutputHelper output)
     [InlineData ("", 0, 0)]
     [InlineData ("", 0, 0)]
     [InlineData (" ", 1, 1)]
     [InlineData (" ", 1, 1)]
     [InlineData ("01234", 5, 1)]
     [InlineData ("01234", 5, 1)]
+    [InlineData ("01234\nABCDE", 5, 2)]
     public void DimAutoStyle_Text_Sizes_Correctly (string text, int expectedW, int expectedH)
     public void DimAutoStyle_Text_Sizes_Correctly (string text, int expectedW, int expectedH)
     {
     {
         var view = new View ();
         var view = new View ();
@@ -677,7 +697,10 @@ public partial class DimAutoTests (ITestOutputHelper output)
     [InlineData ("", 0, 0)]
     [InlineData ("", 0, 0)]
     [InlineData (" ", 1, 1)]
     [InlineData (" ", 1, 1)]
     [InlineData ("01234", 5, 1)]
     [InlineData ("01234", 5, 1)]
-    public void DimAutoStyle_Text_Ignores_ContentSize (string text, int expectedW, int expectedH)
+    [InlineData ("01234ABCDE", 10, 1)]
+    [InlineData ("01234\nABCDE", 5, 2)]
+
+    public void DimAutoStyle_Text_NoMin_Not_Constrained_By_ContentSize (string text, int expectedW, int expectedH)
     {
     {
         var view = new View ();
         var view = new View ();
         view.Width = Auto (DimAutoStyle.Text);
         view.Width = Auto (DimAutoStyle.Text);
@@ -688,6 +711,31 @@ public partial class DimAutoTests (ITestOutputHelper output)
         Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
         Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
     }
     }
 
 
+
+    [Theory]
+    [InlineData ("", 0, 0)]
+    [InlineData (" ", 1, 1)]
+    [InlineData ("01234", 5, 1)]
+    [InlineData ("01234ABCDE", 10, 1)]
+    [InlineData ("01234\nABCDE", 5, 2)]
+    public void DimAutoStyle_Text_NoMin_Not_Constrained_By_SuperView (string text, int expectedW, int expectedH)
+    {
+        var superView = new View ()
+        {
+            Width = 1, Height = 1
+        };
+
+        var view = new View ();
+
+        view.Width = Auto (DimAutoStyle.Text);
+        view.Height = Auto (DimAutoStyle.Text);
+        view.Text = text;
+        superView.Add (view);
+
+        superView.SetRelativeLayout (Application.Screen.Size);
+        Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
+    }
+
     [Fact]
     [Fact]
     public void DimAutoStyle_Text_Pos_AnchorEnd_Locates_Correctly ()
     public void DimAutoStyle_Text_Pos_AnchorEnd_Locates_Correctly ()
     {
     {
@@ -902,7 +950,8 @@ public partial class DimAutoTests (ITestOutputHelper output)
             Height = 1,
             Height = 1,
             Width = Auto ()
             Width = Auto ()
         };
         };
-        Assert.Equal (new (expected, 1), view.TextFormatter.Size);
+        Assert.Equal (expected, view.TextFormatter.Width);
+        Assert.Equal (1, view.TextFormatter.Height);
     }
     }
 
 
     [Theory]
     [Theory]
@@ -917,7 +966,8 @@ public partial class DimAutoTests (ITestOutputHelper output)
             Width = Auto (),
             Width = Auto (),
             Height = 1
             Height = 1
         };
         };
-        Assert.Equal (new (expected, 1), view.TextFormatter.Size);
+        Assert.Equal (expected, view.TextFormatter.Width);
+        Assert.Equal (1, view.TextFormatter.Height);
 
 
         view = new ()
         view = new ()
         {
         {
@@ -927,7 +977,8 @@ public partial class DimAutoTests (ITestOutputHelper output)
             Width = 1,
             Width = 1,
             Height = Auto ()
             Height = Auto ()
         };
         };
-        Assert.Equal (new (1, expected), view.TextFormatter.Size);
+        Assert.Equal (1, view.TextFormatter.Width);
+        Assert.Equal (expected, view.TextFormatter.Height);
     }
     }
 
 
     // Test variations of Frame
     // Test variations of Frame

+ 3 - 5
UnitTests/Views/ButtonTests.cs

@@ -76,11 +76,9 @@ public class ButtonTests (ITestOutputHelper output)
     [InlineData (10, 3, 10, 3)]
     [InlineData (10, 3, 10, 3)]
     public void Button_AbsoluteSize_DefaultText (int width, int height, int expectedWidth, int expectedHeight)
     public void Button_AbsoluteSize_DefaultText (int width, int height, int expectedWidth, int expectedHeight)
     {
     {
-        var btn1 = new Button
-        {
-            Width = width,
-            Height = height,
-        };
+        var btn1 = new Button ();
+        btn1.Width = width;
+        btn1.Height = height;
 
 
         Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.Frame.Size);
         Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.Frame.Size);
         Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.Viewport.Size);
         Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.Viewport.Size);

+ 11 - 9
UnitTests/Views/ScrollViewTests.cs

@@ -349,7 +349,7 @@ public class ScrollViewTests (ITestOutputHelper output)
         Assert.True (sv.AutoHideScrollBars);
         Assert.True (sv.AutoHideScrollBars);
         Assert.True (sv.KeepContentAlwaysInViewport);
         Assert.True (sv.KeepContentAlwaysInViewport);
 
 
-        sv = new() { X = 1, Y = 2, Width = 20, Height = 10 };
+        sv = new () { X = 1, Y = 2, Width = 20, Height = 10 };
         Assert.True (sv.CanFocus);
         Assert.True (sv.CanFocus);
         Assert.Equal (new (1, 2, 20, 10), sv.Frame);
         Assert.Equal (new (1, 2, 20, 10), sv.Frame);
         Assert.Equal (Point.Empty, sv.ContentOffset);
         Assert.Equal (Point.Empty, sv.ContentOffset);
@@ -364,7 +364,7 @@ public class ScrollViewTests (ITestOutputHelper output)
     {
     {
         ((FakeDriver)Application.Driver).SetBufferSize (30, 30);
         ((FakeDriver)Application.Driver).SetBufferSize (30, 30);
 
 
-        var top = new View { Width = 30, Height = 30, ColorScheme = new() { Normal = Attribute.Default } };
+        var top = new View { Width = 30, Height = 30, ColorScheme = new () { Normal = Attribute.Default } };
 
 
         Size size = new (20, 10);
         Size size = new (20, 10);
 
 
@@ -374,7 +374,7 @@ public class ScrollViewTests (ITestOutputHelper output)
             Y = 1,
             Y = 1,
             Width = 10,
             Width = 10,
             Height = 5,
             Height = 5,
-            ColorScheme = new() { Normal = new (Color.Red, Color.Green) }
+            ColorScheme = new () { Normal = new (Color.Red, Color.Green) }
         };
         };
         sv.SetContentSize (size);
         sv.SetContentSize (size);
         string text = null;
         string text = null;
@@ -391,7 +391,7 @@ public class ScrollViewTests (ITestOutputHelper output)
 
 
         var view = new View
         var view = new View
         {
         {
-            ColorScheme = new() { Normal = new (Color.Blue, Color.Yellow) },
+            ColorScheme = new () { Normal = new (Color.Blue, Color.Yellow) },
             Width = Dim.Auto (DimAutoStyle.Text),
             Width = Dim.Auto (DimAutoStyle.Text),
             Height = Dim.Auto (DimAutoStyle.Text),
             Height = Dim.Auto (DimAutoStyle.Text),
             Text = text
             Text = text
@@ -523,7 +523,9 @@ public class ScrollViewTests (ITestOutputHelper output)
         view.Add (
         view.Add (
                   new Label
                   new Label
                   {
                   {
-                      Width = Dim.Fill (), Height = 1, Text = rule.Repeat (size.Width / rule.Length)
+                      Width = Dim.Fill (),
+                      Height = 1,
+                      Text = rule.Repeat (size.Width / rule.Length)
                   }
                   }
                  );
                  );
 
 
@@ -856,8 +858,8 @@ public class ScrollViewTests (ITestOutputHelper output)
  └──────────────────┘
  └──────────────────┘
 ";
 ";
 
 
-        pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-        Assert.Equal (new (1, 1, 21, 14), pos);
+        TestHelpers.AssertDriverContentsAre (expected, output);
+        
         top.Dispose ();
         top.Dispose ();
     }
     }
 
 
@@ -1090,7 +1092,7 @@ public class ScrollViewTests (ITestOutputHelper output)
             Width = width;
             Width = width;
             Height = height;
             Height = height;
 
 
-            labelFill = new() { Width = Dim.Fill (), Height = Dim.Fill (), Visible = false };
+            labelFill = new () { Width = Dim.Fill (), Height = Dim.Fill (), Visible = false };
 
 
             labelFill.LayoutComplete += (s, e) =>
             labelFill.LayoutComplete += (s, e) =>
                                         {
                                         {
@@ -1112,7 +1114,7 @@ public class ScrollViewTests (ITestOutputHelper output)
                                             labelFill.Text = fillText.ToString ();
                                             labelFill.Text = fillText.ToString ();
                                         };
                                         };
 
 
-            labelText = new() { X = Pos.Center (), Y = Pos.Center (), Text = text };
+            labelText = new () { X = Pos.Center (), Y = Pos.Center (), Text = text };
             Add (labelFill, labelText);
             Add (labelFill, labelText);
             CanFocus = true;
             CanFocus = true;
         }
         }