浏览代码

WIP - Trying to make TextFormatter have indepdentent width/height

Tig 1 年之前
父节点
当前提交
2cecc7762a

+ 93 - 25
Terminal.Gui/Text/TextFormatter.cs

@@ -1,3 +1,4 @@
+#nullable enable
 using System.Diagnostics;
 using System.Diagnostics;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 
 
@@ -15,7 +16,6 @@ public class TextFormatter
     private List<string> _lines = new ();
     private List<string> _lines = new ();
     private bool _multiLine;
     private bool _multiLine;
     private bool _preserveTrailingSpaces;
     private bool _preserveTrailingSpaces;
-    private Size _size;
     private int _tabWidth = 4;
     private int _tabWidth = 4;
     private string _text;
     private string _text;
     private Alignment _textAlignment = Alignment.Start;
     private Alignment _textAlignment = Alignment.Start;
@@ -177,6 +177,48 @@ public class TextFormatter
         set => _preserveTrailingSpaces = EnableNeedsFormat (value);
         set => _preserveTrailingSpaces = EnableNeedsFormat (value);
     }
     }
 
 
+    private int? _width;
+
+    public int? Width
+    {
+        get => _width;
+        set
+        {
+            if (_width == value)
+            {
+                return;
+            }
+            _width = value;
+            if (_width is null || _height is null)
+            {
+                return;
+            }
+            Size size = EnableNeedsFormat (Size!.Value);
+            _width = size.Width;
+        }
+    }
+
+    private int? _height;
+
+    public int? Height
+    {
+        get => _height;
+        set
+        {
+            if (_height == value)
+            {
+                return;
+            }
+            _height = value;
+            if (_width is null || _height is null)
+            {
+                return;
+            }
+            Size size = EnableNeedsFormat (Size!.Value);
+            _height = size.Height;
+        }
+    }
+
     /// <summary>Gets or sets the size <see cref="Text"/> will be constrained to when formatted.</summary>
     /// <summary>Gets or sets the size <see cref="Text"/> will be constrained to when formatted.</summary>
     /// <remarks>
     /// <remarks>
     ///     <para>
     ///     <para>
@@ -185,18 +227,38 @@ public class TextFormatter
     ///     </para>
     ///     </para>
     ///     <para>When set, <see cref="NeedsFormat"/> is set to <see langword="true"/>.</para>
     ///     <para>When set, <see cref="NeedsFormat"/> is set to <see langword="true"/>.</para>
     /// </remarks>
     /// </remarks>
-    public Size Size
+    public Size? Size
     {
     {
-        get => _size;
+        get
+        {
+            if (_width is null || _height is null)
+            {
+                return null;
+            }
+
+            return new Size (_width.Value, _height.Value);
+        }
         set
         set
         {
         {
             if (AutoSize)
             if (AutoSize)
             {
             {
-                _size = EnableNeedsFormat (GetAutoSize ());
+                Size size = EnableNeedsFormat (GetAutoSize ());
+                _width = size.Width;
+                _height = size.Height;
             }
             }
             else
             else
             {
             {
-                _size = EnableNeedsFormat (value);
+                if (value is null)
+                {
+                    _width = null;
+                    _height = null;
+                }
+                else
+                {
+                    Size size = EnableNeedsFormat (value.Value);
+                    _width = size.Width;
+                    _height = size.Height;
+                }
             }
             }
         }
         }
     }
     }
@@ -651,19 +713,20 @@ public class TextFormatter
     /// <returns>The size required to hold the formatted text.</returns>
     /// <returns>The size required to hold the formatted text.</returns>
     public Size FormatAndGetSize (Size? constrainSize = null)
     public Size FormatAndGetSize (Size? constrainSize = null)
     {
     {
-        if (constrainSize is null)
-        {
-            constrainSize = Size;
-        }
-        if (string.IsNullOrEmpty (Text) || constrainSize.Value.Height == 0 || constrainSize.Value.Width == 0)
+        if (string.IsNullOrEmpty (Text))
         {
         {
-            return Size.Empty;
+            return System.Drawing.Size.Empty;
         }
         }
 
 
         // HACK: This is a total hack to work around the fact that TextFormatter.Format does not match TextFormatter.Draw.
         // HACK: This is a total hack to work around the fact that TextFormatter.Format does not match TextFormatter.Draw.
-        Size prevSize = Size;
-        Size = constrainSize.Value;
-
+        int? prevWidth = _width;
+        int? prevHeight = _height;
+        if (constrainSize is { })
+        {
+            _width = constrainSize?.Width;
+            _height = constrainSize?.Height;
+        }
+        
         // HACK: Fill normally will fill the entire constraint size, but we need to know the actual size of the text.
         // HACK: Fill normally will fill the entire constraint size, but we need to know the actual size of the text.
         Alignment prevAlignment = Alignment;
         Alignment prevAlignment = Alignment;
         if (Alignment == Alignment.Fill)
         if (Alignment == Alignment.Fill)
@@ -681,11 +744,16 @@ public class TextFormatter
         // Undo hacks
         // Undo hacks
         Alignment = prevAlignment;
         Alignment = prevAlignment;
         VerticalAlignment = prevVerticalAlignment;
         VerticalAlignment = prevVerticalAlignment;
-        Size = prevSize;
+
+        if (constrainSize is { })
+        {
+            _width = prevWidth ?? null;
+            _height = prevHeight ?? null;
+        }
 
 
         if (lines.Count == 0)
         if (lines.Count == 0)
         {
         {
-            return Size.Empty;
+            return System.Drawing.Size.Empty;
         }
         }
 
 
         int width;
         int width;
@@ -720,7 +788,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.Height == 0 || Size.Width == 0)
+        if (string.IsNullOrEmpty (Text) || Size is null || Size?.Height == 0 || Size?.Width == 0)
         {
         {
             _lines = new List<string> { string.Empty };
             _lines = new List<string> { string.Empty };
             NeedsFormat = false;
             NeedsFormat = false;
@@ -745,9 +813,9 @@ public class TextFormatter
 
 
                 _lines = Format (
                 _lines = Format (
                                  text,
                                  text,
-                                 Size.Height,
+                                 Size!.Value.Height,
                                  VerticalAlignment == Alignment.Fill,
                                  VerticalAlignment == Alignment.Fill,
-                                 Size.Width > colsWidth && WordWrap,
+                                 Size!.Value.Width > colsWidth && WordWrap,
                                  PreserveTrailingSpaces,
                                  PreserveTrailingSpaces,
                                  TabWidth,
                                  TabWidth,
                                  Direction,
                                  Direction,
@@ -757,7 +825,7 @@ public class TextFormatter
 
 
                 if (!AutoSize)
                 if (!AutoSize)
                 {
                 {
-                    colsWidth = GetMaxColsForWidth (_lines, Size.Width, TabWidth);
+                    colsWidth = GetMaxColsForWidth (_lines, Size!.Value.Width, TabWidth);
 
 
                     if (_lines.Count > colsWidth)
                     if (_lines.Count > colsWidth)
                     {
                     {
@@ -769,9 +837,9 @@ public class TextFormatter
             {
             {
                 _lines = Format (
                 _lines = Format (
                                  text,
                                  text,
-                                 Size.Width,
+                                 Size!.Value.Width,
                                  Alignment == Alignment.Fill,
                                  Alignment == Alignment.Fill,
-                                 Size.Height > 1 && WordWrap,
+                                 Size!.Value.Height > 1 && WordWrap,
                                  PreserveTrailingSpaces,
                                  PreserveTrailingSpaces,
                                  TabWidth,
                                  TabWidth,
                                  Direction,
                                  Direction,
@@ -779,9 +847,9 @@ public class TextFormatter
                                  this
                                  this
                                 );
                                 );
 
 
-                if (!AutoSize && _lines.Count > Size.Height)
+                if (!AutoSize && _lines.Count > Size!.Value.Height)
                 {
                 {
-                    _lines.RemoveRange (Size.Height, _lines.Count - Size.Height);
+                    _lines.RemoveRange (Size!.Value.Height, _lines.Count -  Size!.Value.Height);
                 }
                 }
             }
             }
 
 
@@ -1952,7 +2020,7 @@ public class TextFormatter
     {
     {
         if (string.IsNullOrEmpty (text))
         if (string.IsNullOrEmpty (text))
         {
         {
-            return new (new (x, y), Size.Empty);
+            return new (new (x, y), System.Drawing.Size.Empty);
         }
         }
 
 
         int w, h;
         int w, h;

+ 27 - 6
Terminal.Gui/View/Layout/DimAuto.cs

@@ -70,19 +70,40 @@ public class DimAuto () : Dim
 
 
         if (Style.FastHasFlags (DimAutoStyle.Text))
         if (Style.FastHasFlags (DimAutoStyle.Text))
         {
         {
+
             if (dimension == Dimension.Width)
             if (dimension == Dimension.Width)
             {
             {
-                //us.TextFormatter.Size = new (superviewContentSize, 2048);
-                textSize = us.TextFormatter.FormatAndGetSize ().Width;
-                //us.TextFormatter.Size = new Size (textSize, 2048);
+                if (us.TextFormatter.Width is null)
+                {
+                    us.TextFormatter.Size = us.TextFormatter.FormatAndGetSize (new (int.Max (autoMax, superviewContentSize), screen));
+                }
+//                else
+                {
+                    textSize = us.TextFormatter.Width.Value;
+                }
             }
             }
             else
             else
             {
             {
-                //if (us.TextFormatter.Size.Width == 0)
+                if (us.TextFormatter.Height is null)
+                {
+                    textSize = us.TextFormatter.FormatAndGetSize (new (us.TextFormatter.Width ?? screen, int.Max (autoMax, superviewContentSize))).Height;
+                    us.TextFormatter.Height = textSize;
+                }
+                else
+                {
+                    textSize = us.TextFormatter.Height.Value;
+                }
+
+                //if (us.Width.Has (typeof(DimAuto), out var widthDim))
                 //{
                 //{
-                //    us.TextFormatter.Size = us.TextFormatter.GetAutoSize ();
+                //    DimAuto widthDimAuto = (DimAuto)widthDim;
+                //    textSize = us.TextFormatter.FormatAndGetSize (us.GetContentSize ()).Height;
                 //}
                 //}
-                textSize = us.TextFormatter.FormatAndGetSize ().Height;
+                //else
+                //{
+                //    textSize = us.TextFormatter.FormatAndGetSize ().Height;
+                //}
+
                 //us.TextFormatter.Size = us.TextFormatter.Size with { Height = textSize };
                 //us.TextFormatter.Size = us.TextFormatter.Size with { Height = textSize };
             }
             }
         }
         }

+ 5 - 0
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -576,6 +576,7 @@ 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.
@@ -583,6 +584,7 @@ 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
         {
         {
@@ -601,6 +603,8 @@ 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)
@@ -743,6 +747,7 @@ 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)

+ 11 - 35
Terminal.Gui/View/ViewText.cs

@@ -180,48 +180,24 @@ public partial class View
         // Default is to use GetContentSize ().
         // Default is to use GetContentSize ().
         var size = GetContentSize ();
         var size = GetContentSize ();
 
 
-        // TODO: This is a hack. Figure out how to move this into DimDimAuto
+        // 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
         DimAuto? widthAuto = _width as DimAuto;
         DimAuto? widthAuto = _width as DimAuto;
         DimAuto? heightAuto = _height as DimAuto;
         DimAuto? heightAuto = _height as DimAuto;
-        if ((widthAuto is { } && widthAuto.Style.FastHasFlags (DimAutoStyle.Text))
-            || (heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text)))
+        if ((widthAuto is { } && widthAuto.Style.FastHasFlags (DimAutoStyle.Text)))
         {
         {
-            int width = 0;
-            int height = 0;
-
-            if (widthAuto is null || !widthAuto.Style.FastHasFlags (DimAutoStyle.Text))
-            {
-                width = GetContentSize ().Width;
-            }
-
-            if (heightAuto is null || !heightAuto.Style.FastHasFlags (DimAutoStyle.Text))
-            {
-                height = GetContentSize ().Height;
-            }
-
-            if (widthAuto is { } && widthAuto.Style.FastHasFlags (DimAutoStyle.Text))
-            {
-                if (height == 0 && heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text))
-                {
-                   height = Application.Screen.Width * 4;
-                }
-                width = TextFormatter.FormatAndGetSize (new (Application.Screen.Width * 4, height)).Width;
-            }
-
-            if (heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text))
-            {
-                if (width == 0 && widthAuto is { } && widthAuto.Style.FastHasFlags (DimAutoStyle.Text))
-                {
-                    width = Application.Screen.Width * 4;
-                }
-                height = TextFormatter.FormatAndGetSize (new (width, Application.Screen.Height * 4)).Height;
-            }
+            TextFormatter.Width = null;
+        }
 
 
-            size = new (width, height);
+        if ((heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text)))
+        {
+            TextFormatter.Height = null;
         }
         }
 
 
-        TextFormatter.Size = size;
+        if (TextFormatter.Size is { })
+        {
+            TextFormatter.Size = size;
+        }
     }
     }
 
 
     private void UpdateTextDirection (TextDirection newDirection)
     private void UpdateTextDirection (TextDirection newDirection)

+ 18 - 18
Terminal.Gui/Views/MessageBox.cs

@@ -369,8 +369,8 @@ public static class MessageBox
             ButtonAlignment = Alignment.Center,
             ButtonAlignment = Alignment.Center,
             ButtonAlignmentModes = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems,
             ButtonAlignmentModes = AlignmentModes.StartToEnd | AlignmentModes.AddSpaceBetweenItems,
             BorderStyle = MessageBox.DefaultBorderStyle,
             BorderStyle = MessageBox.DefaultBorderStyle,
-            Width = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: 1, maximumContentDim: Dim.Percent (90)),
-            Height = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: 2, maximumContentDim: Dim.Percent (90)),
+            Width = Dim.Auto  (DimAutoStyle.Auto, /*minimumContentDim: Dim.Percent (DefaultMinimumWidth), */ maximumContentDim: Dim.Percent (90)),
+            Height = Dim.Auto (DimAutoStyle.Auto, /*minimumContentDim: Dim.Percent (DefaultMinimumHeight),*/ maximumContentDim: Dim.Percent (90)),
         };
         };
 
 
         if (width != 0)
         if (width != 0)
@@ -385,22 +385,22 @@ public static class MessageBox
 
 
         d.ColorScheme = useErrorColors ? Colors.ColorSchemes ["Error"] : Colors.ColorSchemes ["Dialog"];
         d.ColorScheme = useErrorColors ? Colors.ColorSchemes ["Error"] : Colors.ColorSchemes ["Dialog"];
 
 
-        d.LayoutComplete += (s, e) =>
-        {
-            if (wrapMessage)
-            {
-                int buttonHeight = buttonList.Count > 0 ? buttonList [0].Frame.Height : 0;
-                Debug.Assert (d.TextFormatter.WordWrap);
-                d.TextFormatter.Size = new Size (d.GetContentSize ().Width, Application.Screen.Height);
-                Size textSize = d.TextFormatter.GetAutoSize ();
-                textSize.Height += buttonHeight;
-
-                if (textSize != d.TextFormatter.Size)
-                {
-                    d.SetNeedsLayout ();
-                }
-            }
-        };
+        //d.LayoutComplete += (s, e) =>
+        //{
+        //    if (wrapMessage)
+        //    {
+        //        int buttonHeight = buttonList.Count > 0 ? buttonList [0].Frame.Height : 0;
+        //        Debug.Assert (d.TextFormatter.WordWrap);
+        //        d.TextFormatter.Size = new Size (d.GetContentSize ().Width, Application.Screen.Height);
+        //        Size textSize = d.TextFormatter.GetAutoSize ();
+        //        textSize.Height += buttonHeight;
+
+        //        if (textSize != d.TextFormatter.Size)
+        //        {
+        //            d.SetNeedsLayout ();
+        //        }
+        //    }
+        //};
 
 
         d.HotKeySpecifier = new Rune ('\xFFFF');
         d.HotKeySpecifier = new Rune ('\xFFFF');
         d.Text = message;
         d.Text = message;

+ 53 - 2
UICatalog/Scenarios/ComputedLayout.cs

@@ -7,8 +7,7 @@ using static Terminal.Gui.Dialog;
 namespace UICatalog.Scenarios;
 namespace UICatalog.Scenarios;
 
 
 /// <summary>
 /// <summary>
-///     This Scenario demonstrates how to use Termina.gui's Dim and Pos Layout System. [x] - Using Dim.Fill to fill a
-///     window [x] - Using Dim.Fill and Dim.Pos to automatically align controls based on an initial control [ ] - ...
+///     This Scenario demonstrates how to use Terminal.Gui's Dim and Pos Layout System. 
 /// </summary>
 /// </summary>
 [ScenarioMetadata ("Computed Layout", "Demonstrates the Computed (Dim and Pos) Layout System.")]
 [ScenarioMetadata ("Computed Layout", "Demonstrates the Computed (Dim and Pos) Layout System.")]
 [ScenarioCategory ("Layout")]
 [ScenarioCategory ("Layout")]
@@ -216,6 +215,58 @@ public class ComputedLayout : Scenario
                                      fv.Title =
                                      fv.Title =
                                          $"{frameView.GetType ().Name} {{X={fv.X},Y={fv.Y},Width={fv.Width},Height={fv.Height}}}";
                                          $"{frameView.GetType ().Name} {{X={fv.X},Y={fv.Y},Width={fv.Width},Height={fv.Height}}}";
                                  };
                                  };
+
+        labelList = new List<Label> ();
+        labelList.Add (new Label { Text = "The lines below show different alignment" });
+
+        labelList.Add (
+                       new Label
+                       {
+                           TextAlignment = Alignment.Start,
+                           Width = Dim.Fill (),
+                           X = 0,
+                           Y = Pos.Bottom (labelList.LastOrDefault ()),
+                           ColorScheme = Colors.ColorSchemes ["Dialog"],
+                           Text = $"{i++}-{txt}"
+                       }
+                      );
+
+        labelList.Add (
+                       new Label
+                       {
+                           TextAlignment = Alignment.End,
+                           Width = Dim.Fill (),
+                           X = 0,
+                           Y = Pos.Bottom (labelList.LastOrDefault ()),
+                           ColorScheme = Colors.ColorSchemes ["Dialog"],
+                           Text = $"{i++}-{txt}"
+                       }
+                      );
+
+        labelList.Add (
+                       new Label
+                       {
+                           TextAlignment = Alignment.Center,
+                           Width = Dim.Fill (),
+                           X = 0,
+                           Y = Pos.Bottom (labelList.LastOrDefault ()),
+                           ColorScheme = Colors.ColorSchemes ["Dialog"],
+                           Text = $"{i++}-{txt}"
+                       }
+                      );
+
+        labelList.Add (
+                       new Label
+                       {
+                           TextAlignment = Alignment.Fill,
+                           Width = Dim.Fill (),
+                           X = 0,
+                           Y = Pos.Bottom (labelList.LastOrDefault ()),
+                           ColorScheme = Colors.ColorSchemes ["Dialog"],
+                           Text = $"{i++}-{txt}"
+                       }
+                      );
+        frameView.Add (labelList.ToArray ());
         app.Add (frameView);
         app.Add (frameView);
 
 
         // Demonstrate Dim & Pos using percentages - a TextField that is 30% height and 80% wide
         // Demonstrate Dim & Pos using percentages - a TextField that is 30% height and 80% wide

+ 7 - 2
UICatalog/Scenarios/MessageBoxes.cs

@@ -65,7 +65,12 @@ public class MessageBoxes : Scenario
         frame.Add (heightEdit);
         frame.Add (heightEdit);
 
 
         frame.Add (
         frame.Add (
-                   new Label { X = Pos.Right (widthEdit) + 2, Y = Pos.Top (widthEdit), Text = "If height & width are both 0," }
+                   new Label
+                   {
+                       X = Pos.Right (widthEdit) + 2,
+                       Y = Pos.Top (widthEdit),
+                       Text = $"If width is 0, the dimension will be {MessageBox.DefaultMinimumWidth}%."
+                   }
                   );
                   );
 
 
         frame.Add (
         frame.Add (
@@ -73,7 +78,7 @@ public class MessageBoxes : Scenario
                    {
                    {
                        X = Pos.Right (heightEdit) + 2,
                        X = Pos.Right (heightEdit) + 2,
                        Y = Pos.Top (heightEdit),
                        Y = Pos.Top (heightEdit),
-                       Text = "the MessageBox will be sized automatically."
+                       Text = $"If height is 0, the dimension will be {MessageBox.DefaultMinimumWidth}%."
                    }
                    }
                   );
                   );
 
 

+ 6 - 1
UnitTests/Text/TextFormatterTests.cs

@@ -2216,7 +2216,7 @@ ssb
         Assert.False (tf.AutoSize);
         Assert.False (tf.AutoSize);
 
 
         // If autosize is false, no auto sizing!
         // If autosize is false, no auto sizing!
-        Assert.Equal (Size.Empty, tf.Size);
+        Assert.Null (tf.Size);
 
 
         tf.Size = new (1, 1); // This should have no impact (autosize overrides)
         tf.Size = new (1, 1); // This should have no impact (autosize overrides)
         tf.AutoSize = true;
         tf.AutoSize = true;
@@ -2236,6 +2236,11 @@ ssb
     public void Text_Set_SizeIsCorrect (string text, TextDirection textDirection, bool autoSize, int expectedWidth, int expectedHeight)
     public void Text_Set_SizeIsCorrect (string text, TextDirection textDirection, bool autoSize, int expectedWidth, int expectedHeight)
     {
     {
         var tf = new TextFormatter { Direction = textDirection, Text = text, AutoSize = autoSize };
         var tf = new TextFormatter { Direction = textDirection, Text = text, AutoSize = autoSize };
+
+        if (!autoSize)
+        {
+            tf.Size = Size.Empty;
+        }
         Assert.Equal (new Size (expectedWidth, expectedHeight), tf.Size);
         Assert.Equal (new Size (expectedWidth, expectedHeight), tf.Size);
     }
     }
 
 

+ 49 - 0
UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs

@@ -303,6 +303,55 @@ public partial class DimAutoTests
         Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y);
         Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y);
     }
     }
 
 
+    [Theory]
+    [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, 19, 0, 9, 19, 9)]
+    //[InlineData (0, 20, 0, 10, 20, 10)]
+    //[InlineData (0, 21, 0, 11, 21, 11)]
+    //[InlineData (1, 21, 1, 11, 21, 11)]
+    //[InlineData (21, 21, 11, 11, 21, 11)]
+    public void With_Text_And_Subview_Using_PosAnchorEnd (int minWidth, int maxWidth, int minHeight, int maxHeight, int expectedWidth, int expectedHeight)
+    {
+        var view = new View
+        {
+            Text = "01234ABCDE",
+            Width = Dim.Auto (),
+            Height = Dim.Auto ()
+        };
+
+        // Without a subview, width should be 10
+        // Without a subview, height should be 1
+        view.SetRelativeLayout (Application.Screen.Size);
+        Assert.Equal (10, view.Frame.Width);
+        Assert.Equal (1, view.Frame.Height);
+
+        view.Width = Dim.Auto (minimumContentDim: minWidth, maximumContentDim: maxWidth);
+        view.Height = Dim.Auto (minimumContentDim: minHeight, maximumContentDim: maxHeight);
+
+        var subview = new View
+        {
+            X = Pos.AnchorEnd (),
+            Y = Pos.AnchorEnd (),
+            Width = 1,
+            Height = 1
+        };
+
+        view.Add (subview);
+
+        // Assuming the calculation is done after layout
+        int calculatedX = view.X.Calculate (100, view.Width, view, Dimension.Width);
+        int calculatedY = view.Y.Calculate (100, view.Height, view, Dimension.Height);
+        int calculatedWidth = view.Width.Calculate (0, 100, view, Dimension.Width);
+        int calculatedHeight = view.Height.Calculate (0, 100, view, Dimension.Height);
+
+        Assert.Equal (expectedWidth, calculatedWidth);
+        Assert.Equal (expectedHeight, calculatedHeight);
+
+        Assert.Equal (0, calculatedX);
+        Assert.Equal (0, calculatedY);
+    }
+
     #endregion PosAnchorEnd
     #endregion PosAnchorEnd
 
 
     #region PosFunc
     #region PosFunc

+ 57 - 2
UnitTests/View/Layout/Dim.AutoTests.cs

@@ -509,7 +509,7 @@ public partial class DimAutoTests (ITestOutputHelper output)
             Height = Auto (),
             Height = Auto (),
             Text = "01234"
             Text = "01234"
         };
         };
-
+        view.SetRelativeLayout (new (100, 100));
         Assert.Equal (new (0, 0, 5, 1), view.Frame);
         Assert.Equal (new (0, 0, 5, 1), view.Frame);
         Assert.Equal (new (5, 1), view.GetContentSize ());
         Assert.Equal (new (5, 1), view.GetContentSize ());
 
 
@@ -618,6 +618,61 @@ public partial class DimAutoTests (ITestOutputHelper output)
         super.Dispose ();
         super.Dispose ();
     }
     }
 
 
+    [Theory]
+    [InlineData ("", 0, 0)]
+    [InlineData (" ", 1, 1)]
+    [InlineData ("01234", 5, 1)]
+    public void DimAutoStyle_Text_Sizes_Correctly (string text, int expectedW, int expectedH)
+    {
+        var view = new View ();
+        view.Width = Auto (DimAutoStyle.Text);
+        view.Height = Auto (DimAutoStyle.Text);
+
+        view.Text = text;
+
+        view.SetRelativeLayout (Application.Screen.Size);
+
+        Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
+
+    }
+
+    [Theory]
+    [InlineData ("", 0, 0, 0, 0)]
+    [InlineData (" ", 5, 5, 5, 5)]
+    [InlineData ("01234", 5, 5, 5, 5)]
+    [InlineData ("01234", 4, 3, 5, 3)]
+    [InlineData ("01234ABCDE", 5, 0, 10, 1)]
+    public void DimAutoStyle_Text_Sizes_Correctly_With_Min (string text, int minWidth, int minHeight, int expectedW, int expectedH)
+    {
+        var view = new View ();
+        view.Width = Auto (DimAutoStyle.Text, minimumContentDim: minWidth);
+        view.Height = Auto (DimAutoStyle.Text, minimumContentDim: minHeight);
+
+        view.Text = text;
+
+        view.SetRelativeLayout (Application.Screen.Size);
+
+        Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
+
+    }
+
+    [Theory]
+    [InlineData ("", 0, 0, 0)]
+    [InlineData (" ", 5, 1, 1)]
+    [InlineData ("01234", 5, 5, 1)]
+    [InlineData ("01234", 4, 4, 2)]
+    [InlineData ("01234ABCDE", 5, 5, 2)]
+    [InlineData ("01234ABCDE", 1, 1, 10)]
+    public void DimAutoStyle_Text_Sizes_Correctly_With_Max_Width (string text, int maxWidth, int expectedW, int expectedH)
+    {
+        var view = new View ();
+        view.Width = Auto (DimAutoStyle.Text, maximumContentDim: maxWidth);
+        view.Height = Auto (DimAutoStyle.Text);
+        view.Text = text;
+
+        Assert.Equal (new (expectedW, expectedH), view.Frame.Size);
+    }
+
     [Theory]
     [Theory]
     [InlineData ("", 0, 0)]
     [InlineData ("", 0, 0)]
     [InlineData (" ", 1, 1)]
     [InlineData (" ", 1, 1)]
@@ -775,7 +830,7 @@ public partial class DimAutoTests (ITestOutputHelper output)
             Text = "_1234",
             Text = "_1234",
             Width = Auto ()
             Width = Auto ()
         };
         };
-        Assert.Equal (Size.Empty, view.Frame.Size); // Height is 0, so width is 0 regardless of text
+        Assert.Equal (new (4, 0), view.Frame.Size);
 
 
         view.Height = 1;
         view.Height = 1;
         view.SetRelativeLayout (Application.Screen.Size);
         view.SetRelativeLayout (Application.Screen.Size);