Sfoglia il codice sorgente

Tons of changes - mostly experiments, but some goodness.

There's a huge issue that TextFormatter is confused about AutoSize.
a) It behaves 'automatically' even when AutoSize == false (e.g. in Text_set).
b) It doesn't support auto sizing only one dimension.
Tig 1 anno fa
parent
commit
09565a0ef1

+ 128 - 58
Terminal.Gui/Text/TextFormatter.cs

@@ -30,10 +30,10 @@ public class TextFormatter
 
     /// <summary>Gets or sets whether the <see cref="Size"/> should be automatically changed to fit the <see cref="Text"/>.</summary>
     /// <remarks>
-    ///     <para>Used by <see cref="View.AutoSize"/> to resize the view's <see cref="View.Viewport"/> to fit <see cref="Size"/>.</para>
+    ///     <para>Used by <see cref="View.AutoSize"/> to resize the view's <see cref="View.ContentSize"/> to fit <see cref="Size"/>.</para>
     ///     <para>
-    ///         AutoSize is ignored if <see cref="TextAlignment.Justified"/> and
-    ///         <see cref="VerticalTextAlignment.Justified"/> are used.
+    ///         <see cref="TextAlignment.Justified"/> and
+    ///         <see cref="VerticalTextAlignment.Justified"/> are ignored when <see cref="AutoSize"/> is <see langword="true"/>.
     ///     </para>
     /// </remarks>
     public bool AutoSize
@@ -43,13 +43,81 @@ public class TextFormatter
         {
             _autoSize = EnableNeedsFormat (value);
 
-            if (_autoSize)// && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified)
+            if (_autoSize)
             {
-                Size = CalcRect (0, 0, _text, Direction, TabWidth).Size;
+                Size = GetAutoSize ();
             }
         }
     }
 
+    private Size GetAutoSize ()
+    {
+        if (string.IsNullOrEmpty(_text))
+        {
+            return Size.Empty;
+        }
+
+        int width = int.MaxValue;
+        int height = int.MaxValue;
+        string text = _text;
+        List<string> lines;
+
+        if (FindHotKey (_text, HotKeySpecifier, out _hotKeyPos, out Key newHotKey))
+        {
+            HotKey = newHotKey;
+            text = RemoveHotKeySpecifier (Text, _hotKeyPos, HotKeySpecifier);
+            text = ReplaceHotKeyWithTag (text, _hotKeyPos);
+        }
+
+        if (IsVerticalDirection (Direction))
+        {
+            int colsWidth = GetSumMaxCharWidth (text, 0, 1, TabWidth);
+
+            lines = Format (
+                            text,
+                            height,
+                            VerticalAlignment == VerticalTextAlignment.Justified,
+                            width > colsWidth && WordWrap,
+                            PreserveTrailingSpaces,
+                            TabWidth,
+                            Direction,
+                            MultiLine
+                           );
+            colsWidth = GetMaxColsForWidth (lines, width, TabWidth);
+
+            if (lines.Count > colsWidth)
+            {
+                lines.RemoveRange (colsWidth, lines.Count - colsWidth);
+            }
+            height = lines.Max (static line => line.GetColumns ());
+            width = lines.Count;
+        }
+        else
+        {
+            lines = Format (
+                            text,
+                            width,
+                            false, // Ignore justification because autosize means no justification
+                            height > 1 && WordWrap,
+                            PreserveTrailingSpaces,
+                            TabWidth,
+                            Direction,
+                            MultiLine
+                           );
+
+            // Format always returns at least 1 line
+            if (lines.Count == 1 && string.IsNullOrEmpty (lines [0]))
+            {
+                return Size.Empty;
+            }
+
+            width = lines.Max (static line => line.GetColumns ());
+            height = lines.Count;
+        }
+
+        return new (width, height);
+    }
+
     /// <summary>
     ///     Gets the cursor position of the <see cref="HotKey"/>. If the <see cref="HotKey"/> is defined, the cursor will
     ///     be positioned over it.
@@ -65,9 +133,9 @@ public class TextFormatter
         {
             _textDirection = EnableNeedsFormat (value);
 
-            if (AutoSize)// && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified)
+            if (AutoSize)
             {
-                Size = CalcRect (0, 0, Text, Direction, TabWidth).Size;
+                Size = GetAutoSize ();
             }
         }
     }
@@ -150,7 +218,8 @@ public class TextFormatter
         {
             if (AutoSize)// && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified)
             {
-                _size = EnableNeedsFormat (CalcRect (0, 0, Text, Direction, TabWidth).Size);
+                //_size = EnableNeedsFormat (CalcRect (0, 0, Text, Direction, TabWidth).Size);
+                _size = EnableNeedsFormat (value);
             }
             else
             {
@@ -175,9 +244,10 @@ public class TextFormatter
             bool textWasNull = _text is null && value != null;
             _text = EnableNeedsFormat (value);
 
+            // BUGBUG: If AutoSize is false, there should be no "automatic behavior" like setting the size
             if (AutoSize || (textWasNull && Size.IsEmpty))
             {
-                Size = CalcRect (0, 0, _text, Direction, TabWidth).Size;
+                Size = GetAutoSize ();
             }
         }
     }
@@ -287,13 +357,13 @@ public class TextFormatter
             Rune [] runes = linesFormatted [line].ToRunes ();
 
             runes = Direction switch
-                    {
-                        TextDirection.RightLeft_BottomTop => runes.Reverse ().ToArray (),
-                        TextDirection.RightLeft_TopBottom => runes.Reverse ().ToArray (),
-                        TextDirection.BottomTop_LeftRight => runes.Reverse ().ToArray (),
-                        TextDirection.BottomTop_RightLeft => runes.Reverse ().ToArray (),
-                        _ => runes
-                    };
+            {
+                TextDirection.RightLeft_BottomTop => runes.Reverse ().ToArray (),
+                TextDirection.RightLeft_TopBottom => runes.Reverse ().ToArray (),
+                TextDirection.BottomTop_LeftRight => runes.Reverse ().ToArray (),
+                TextDirection.BottomTop_RightLeft => runes.Reverse ().ToArray (),
+                _ => runes
+            };
 
             // When text is justified, we lost left or right, so we use the direction to align. 
 
@@ -700,48 +770,48 @@ public class TextFormatter
     public static bool IsHorizontalDirection (TextDirection textDirection)
     {
         return textDirection switch
-               {
-                   TextDirection.LeftRight_TopBottom => true,
-                   TextDirection.LeftRight_BottomTop => true,
-                   TextDirection.RightLeft_TopBottom => true,
-                   TextDirection.RightLeft_BottomTop => true,
-                   _ => false
-               };
+        {
+            TextDirection.LeftRight_TopBottom => true,
+            TextDirection.LeftRight_BottomTop => true,
+            TextDirection.RightLeft_TopBottom => true,
+            TextDirection.RightLeft_BottomTop => true,
+            _ => false
+        };
     }
 
     /// <summary>Check if it is a vertical direction</summary>
     public static bool IsVerticalDirection (TextDirection textDirection)
     {
         return textDirection switch
-               {
-                   TextDirection.TopBottom_LeftRight => true,
-                   TextDirection.TopBottom_RightLeft => true,
-                   TextDirection.BottomTop_LeftRight => true,
-                   TextDirection.BottomTop_RightLeft => true,
-                   _ => false
-               };
+        {
+            TextDirection.TopBottom_LeftRight => true,
+            TextDirection.TopBottom_RightLeft => true,
+            TextDirection.BottomTop_LeftRight => true,
+            TextDirection.BottomTop_RightLeft => true,
+            _ => false
+        };
     }
 
     /// <summary>Check if it is Left to Right direction</summary>
     public static bool IsLeftToRight (TextDirection textDirection)
     {
         return textDirection switch
-               {
-                   TextDirection.LeftRight_TopBottom => true,
-                   TextDirection.LeftRight_BottomTop => true,
-                   _ => false
-               };
+        {
+            TextDirection.LeftRight_TopBottom => true,
+            TextDirection.LeftRight_BottomTop => true,
+            _ => false
+        };
     }
 
     /// <summary>Check if it is Top to Bottom direction</summary>
     public static bool IsTopToBottom (TextDirection textDirection)
     {
         return textDirection switch
-               {
-                   TextDirection.TopBottom_LeftRight => true,
-                   TextDirection.TopBottom_RightLeft => true,
-                   _ => false
-               };
+        {
+            TextDirection.TopBottom_LeftRight => true,
+            TextDirection.TopBottom_RightLeft => true,
+            _ => false
+        };
     }
 
     // TODO: Move to StringExtensions?
@@ -1122,21 +1192,21 @@ public class TextFormatter
                     case ' ':
                         return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length);
                     case '\t':
-                    {
-                        length += tabWidth + 1;
-
-                        if (length == tabWidth && tabWidth > cWidth)
                         {
-                            return to + 1;
-                        }
+                            length += tabWidth + 1;
 
-                        if (length > cWidth && tabWidth > cWidth)
-                        {
-                            return to;
-                        }
+                            if (length == tabWidth && tabWidth > cWidth)
+                            {
+                                return to + 1;
+                            }
 
-                        return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length);
-                    }
+                            if (length > cWidth && tabWidth > cWidth)
+                            {
+                                return to;
+                            }
+
+                            return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length);
+                        }
                     default:
                         to++;
 
@@ -1145,11 +1215,11 @@ public class TextFormatter
             }
 
             return cLength switch
-                   {
-                       > 0 when to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t' => from,
-                       > 0 when to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t') => from,
-                       _ => to
-                   };
+            {
+                > 0 when to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t' => from,
+                > 0 when to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t') => from,
+                _ => to
+            };
         }
 
         if (start < text.GetRuneCount ())
@@ -1742,7 +1812,7 @@ public class TextFormatter
         return lineIdx;
     }
 
-    /// <summary>Calculates the rectangle required to hold text, assuming no word wrapping or justification.</summary>
+    /// <summary>Calculates the rectangle required to hold text, assuming no word wrapping, justification, or hotkeys.</summary>
     /// <remarks>
     ///     This API will return incorrect results if the text includes glyphs who's width is dependent on surrounding
     ///     glyphs (e.g. Arabic).

+ 81 - 0
Terminal.Gui/View/Layout/PosDim.cs

@@ -1,4 +1,5 @@
 using System.Diagnostics;
+using System.Runtime.InteropServices.JavaScript;
 using static System.Net.Mime.MediaTypeNames;
 using static Terminal.Gui.Dialog;
 using static Terminal.Gui.Dim;
@@ -354,6 +355,16 @@ public class Pos
         return Anchor (superviewDimension);
     }
 
+
+    /// <summary>
+    /// Diagnostics API to determine if this Pos object references other views.
+    /// </summary>
+    /// <returns></returns>
+    internal virtual bool ReferencesOtherViews ()
+    {
+        return false;
+    }
+
     internal class PosAbsolute (int n) : Pos
     {
         private readonly int _n = n;
@@ -447,6 +458,25 @@ public class Pos
 
             return left - right;
         }
+
+        /// <summary>
+        /// Diagnostics API to determine if this Pos object references other views.
+        /// </summary>
+        /// <returns></returns>
+        internal override bool ReferencesOtherViews ()
+        {
+            if (_left.ReferencesOtherViews ())
+            {
+                return true;
+            }
+
+            if (_right.ReferencesOtherViews ())
+            {
+                return true;
+            }
+
+            return false;
+        }
     }
 
     internal class PosFactor (float factor) : Pos
@@ -531,6 +561,15 @@ public class Pos
                 _ => 0
             };
         }
+
+        /// <summary>
+        /// Diagnostics API to determine if this Pos object references other views.
+        /// </summary>
+        /// <returns></returns>
+        internal override bool ReferencesOtherViews ()
+        {
+            return true;
+        }
     }
 }
 
@@ -839,6 +878,15 @@ public class Dim
         return Math.Max (Anchor (superviewContentSize - location), 0);
     }
 
+    /// <summary>
+    /// Diagnostics API to determine if this Dim object references other views.
+    /// </summary>
+    /// <returns></returns>
+    internal virtual bool ReferencesOtherViews ()
+    {
+        return false;
+    }
+
     internal class DimAbsolute (int n) : Dim
     {
         private readonly int _n = n;
@@ -915,6 +963,15 @@ public class Dim
             return int.Min (max, _max?.Anchor (superviewContentSize) ?? superviewContentSize);
         }
 
+        /// <summary>
+        /// Diagnostics API to determine if this Dim object references other views.
+        /// </summary>
+        /// <returns></returns>
+        internal override bool ReferencesOtherViews ()
+        {
+            return _style is Dim.DimAutoStyle.Subviews or Dim.DimAutoStyle.Auto;
+        }
+
     }
     internal class DimCombine (bool add, Dim left, Dim right) : Dim
     {
@@ -955,6 +1012,25 @@ public class Dim
             return newDimension;
         }
 
+
+        /// <summary>
+        /// Diagnostics API to determine if this Dim object references other views.
+        /// </summary>
+        /// <returns></returns>
+        internal override bool ReferencesOtherViews ()
+        {
+            if (_left.ReferencesOtherViews ())
+            {
+                return true;
+            }
+
+            if (_right.ReferencesOtherViews ())
+            {
+                return true;
+            }
+
+            return false;
+        }
     }
 
     internal class DimFactor (float factor, bool remaining = false) : Dim
@@ -1033,5 +1109,10 @@ public class Dim
                 _ => 0
             };
         }
+
+        internal override bool ReferencesOtherViews ()
+        {
+            return true;
+        }
     }
 }

+ 15 - 39
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -348,6 +348,7 @@ public partial class View
         {
             TextFormatter.AutoSize = value;
 
+            // BUGBUG: This is all a hack until AutoSize is removed
             if (value)
             {
                 UpdateTextFormatterText ();
@@ -365,18 +366,9 @@ public partial class View
             }
             else
             {
-                if (IsInitialized)
-                {
-                    Height = ContentSize.Height;
-                    Width = ContentSize.Width;
-
-                }
-                else
-                {
-                    _height = ContentSize.Height;
-                    _width = ContentSize.Width;
-                    OnResizeNeeded ();
-                }
+                _height = ContentSize.Height;
+                _width = ContentSize.Width;
+                OnResizeNeeded ();
             }
         }
     }
@@ -688,7 +680,7 @@ public partial class View
             superView = viewToMove.SuperView;
         }
 
-        if (superView.Margin is { } && superView == viewToMove.SuperView)
+        if (superView?.Margin is { } && superView == viewToMove.SuperView)
         {
             maxDimension -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
         }
@@ -991,27 +983,27 @@ public partial class View
     {
         // TODO: Identify a real-world use-case where this API should be virtual. 
         // TODO: Until then leave it `internal` and non-virtual
+
         // First try SuperView.Viewport, then Application.Top, then Driver.Viewport.
         // Finally, if none of those are valid, use int.MaxValue (for Unit tests).
         Size contentSize = SuperView is { IsInitialized: true } ? SuperView.ContentSize :
                            Application.Top is { } && Application.Top != this && Application.Top.IsInitialized ? Application.Top.ContentSize :
                            Application.Driver?.Screen.Size ?? new (int.MaxValue, int.MaxValue);
-        SetRelativeLayout (contentSize);
 
-        // TODO: Determine what, if any of the below is actually needed here.
+
+
+        SetTextFormatterSize ();
+
+        SetRelativeLayout (contentSize);
 
         if (IsInitialized)
         {
-            //if (AutoSize)
-            {
-            //    SetFrameToFitText ();
-               SetTextFormatterSize ();
-            }
-
             LayoutAdornments ();
-            SetNeedsDisplay ();
-            SetNeedsLayout ();
         }
+
+        SetNeedsDisplay ();
+        SetNeedsLayout ();
+
     }
 
     internal bool LayoutNeeded { get; private set; } = true;
@@ -1062,22 +1054,6 @@ public partial class View
         Debug.Assert (_height is { });
 
         CheckDimAuto ();
-
-        SetTextFormatterSize ();
-
-        var autoSize = Size.Empty;
-
-        //if (AutoSize)
-        //{
-        //    // TODO: Nuke this from orbit once Dim.Auto is fully implemented
-        //    autoSize = GetTextAutoSize ();
-        //}
-        SetTextFormatterSize ();
-        if (TextFormatter.NeedsFormat)
-        {
-            TextFormatter.Format ();
-        }
-
         int newX = _x.Calculate (superviewContentSize.Width, _width, this, Dim.Dimension.Width);
         int newW = _width.Calculate (newX, superviewContentSize.Width, this, Dim.Dimension.Width);
         int newY = _y.Calculate (superviewContentSize.Height, _height, this, Dim.Dimension.Height);

+ 2 - 2
Terminal.Gui/View/View.cs

@@ -139,6 +139,8 @@ public partial class View : Responder, ISupportInitializeNotification
     /// </remarks>
     public View ()
     {
+        CreateAdornments ();
+
         HotKeySpecifier = (Rune)'_';
         TitleTextFormatter.HotKeyChanged += TitleTextFormatter_HotKeyChanged;
 
@@ -150,8 +152,6 @@ public partial class View : Responder, ISupportInitializeNotification
         TabStop = false;
 
         AddCommands ();
-
-        CreateAdornments ();
     }
 
     /// <summary>

+ 22 - 2
Terminal.Gui/View/ViewContent.cs

@@ -289,10 +289,10 @@ public partial class View
         get
         {
 #if DEBUG
-            if (LayoutStyle == LayoutStyle.Computed && !IsInitialized)
+            if ((_width.ReferencesOtherViews () || _height.ReferencesOtherViews ()) && !IsInitialized)
             {
                 Debug.WriteLine (
-                                 $"WARNING: Viewport is being accessed before the View has been initialized. This is likely a bug in {this}"
+                                 $"WARNING: The dimensions of {this} are dependent on other views and Viewport is being accessed before the View has been initialized. This is likely a bug."
                                 );
             }
 #endif // DEBUG
@@ -305,6 +305,26 @@ public partial class View
 
             Thickness thickness = GetAdornmentsThickness ();
 
+            if (Frame.Size == Size.Empty)
+            {
+                // The Frame has not been set yet (e.g. the view has not been added to a SuperView yet).
+                // 
+                if ((Width is Dim.DimAuto widthAuto && widthAuto._style != Dim.DimAutoStyle.Subviews)
+                    || (Height is Dim.DimAuto heightAuto && heightAuto._style != Dim.DimAutoStyle.Subviews))
+                {
+                    if (TextFormatter.NeedsFormat)
+                    {
+                        // This updates TextFormatter.Size to the text size
+                        TextFormatter.AutoSize = true;
+
+                        // Whenever DimAutoStyle.Text is set, ContentSize will match TextFormatter.Size.
+                        ContentSize = TextFormatter.Size;
+
+                    }
+                }
+                //SetRelativeLayout (SuperView?.ContentSize ?? new Size (int.MaxValue, int.MaxValue));
+            }
+
             return new (
                         _viewportLocation,
                         new (

+ 1 - 1
Terminal.Gui/View/ViewDrawing.cs

@@ -413,7 +413,7 @@ public partial class View
     {
         if (!IsInitialized)
         {
-            return false;
+           return false;
         }
 
         // Each of these renders lines to either this View's LineCanvas 

+ 57 - 95
Terminal.Gui/View/ViewText.cs

@@ -48,19 +48,9 @@ public partial class View
         get => _text;
         set
         {
-            if (value == _text)
-            {
-                return;
-            }
-
             string old = _text;
             _text = value;
 
-            if (!string.IsNullOrEmpty (_text))
-            {
-
-            }
-
             UpdateTextFormatterText ();
             OnResizeNeeded ();
 #if DEBUG
@@ -180,38 +170,32 @@ public partial class View
                    : 0;
     }
 
-    // BUGBUG: This API is fundamentally broken. Text autosize should have nothing to do with what's visible (Viewport) and only ContentSize.
-    /// <summary>
-    ///     Gets the Frame dimensions required to fit <see cref="Text"/> within <see cref="ContentSize"/> using the text
-    ///     <see cref="NavigationDirection"/> specified by the <see cref="TextFormatter"/> property and accounting for any
-    ///     <see cref="HotKeySpecifier"/> characters.
-    /// </summary>
-    /// <remarks>
-    /// </remarks>
-    /// <returns>The <see cref="Size"/> of the <see cref="Frame"/> required to fit the formatted text.</returns>
-    public Size GetTextAutoSize ()
-    {
-        var x = 0;
-        var y = 0;
-
-        if (IsInitialized)
-        {
-            x = Viewport.X;
-            y = Viewport.Y;
-        }
-
-        Rectangle rect = TextFormatter.CalcRect (x, y, TextFormatter.Text, TextFormatter.Direction);
+    ///// <summary>
+    /////     Gets dimensions required to fit <see cref="Text"/> within <see cref="ContentSize"/> using the text
+    /////     <see cref="NavigationDirection"/> specified by the <see cref="TextFormatter"/> property and accounting for any
+    /////     <see cref="HotKeySpecifier"/> characters.
+    ///// </summary>
+    ///// <remarks>
+    ///// </remarks>
+    ///// <returns>The <see cref="Size"/> of the <see cref="ContentSize"/> required to fit the formatted text.</returns>
+    //public Size GetTextAutoSize ()
+    //{
+    //    var x = 0;
+    //    var y = 0;
 
-        int newWidth = rect.Size.Width
-                       - GetHotKeySpecifierLength ()
-                       + (Margin == null ? 0 : Margin.Thickness.Horizontal + Border.Thickness.Horizontal + Padding.Thickness.Horizontal);
+    //    if (IsInitialized)
+    //    {
+    //        x = Viewport.X;
+    //        y = Viewport.Y;
+    //    }
 
-        int newHeight = rect.Size.Height
-                        - GetHotKeySpecifierLength (false)
-                        + (Margin == null ? 0 : Margin.Thickness.Vertical + Border.Thickness.Vertical + Padding.Thickness.Vertical);
+    //    // Get the size of the text without the hot key specifier
+    //    Rectangle rect = TextFormatter.CalcRect (x, y, TextFormatter.Text, TextFormatter.Direction);
+    //    int newWidth = rect.Size.Width - GetHotKeySpecifierLength ();
+    //    int newHeight = rect.Size.Height - GetHotKeySpecifierLength (false);
 
-        return new (newWidth, newHeight);
-    }
+    //    return new (newWidth, newHeight);
+    //}
 
     /// <summary>
     ///     Can be overridden if the <see cref="Terminal.Gui.TextFormatter.Text"/> has
@@ -248,82 +232,60 @@ public partial class View
     /// <returns></returns>
     internal void SetTextFormatterSize ()
     {
+        UpdateTextFormatterText ();
+
         //if (!IsInitialized)
         //{
-        //    TextFormatter.Size = Size.Empty;
-
         //    return;
         //}
 
-        if (string.IsNullOrEmpty (TextFormatter.Text))
-        {
-            TextFormatter.Size = ContentSize;
-
-            return;
-        }
-
-        int w = Viewport.Size.Width + GetHotKeySpecifierLength ();
+        //Dim.DimAuto widthAuto = Width as Dim.DimAuto;
+        //Dim.DimAuto heightAuto = Height as Dim.DimAuto;
 
         // TODO: This is a hack. Figure out how to move this into DimDimAuto
-        if (Width is Dim.DimAuto widthAuto && widthAuto._style != Dim.DimAutoStyle.Subviews)
+        if ((Width is Dim.DimAuto widthAuto && widthAuto._style != Dim.DimAutoStyle.Subviews)
+            || (Height is Dim.DimAuto heightAuto && heightAuto._style != Dim.DimAutoStyle.Subviews))
         {
-            if (Height is Dim.DimAuto)
-            {
-                // Both are auto. 
-                TextFormatter.Size = new Size (SuperView?.ContentSize.Width ?? int.MaxValue, SuperView?.ContentSize.Height ?? int.MaxValue);
-            }
-            else
-            {
-                TextFormatter.Size = new Size (SuperView?.ContentSize.Width ?? int.MaxValue, ContentSize.Height + GetHotKeySpecifierLength ());
-            }
+            // This updates TextFormatter.Size to the text size
+            TextFormatter.AutoSize = true;
 
-            w = TextFormatter.FormatAndGetSize ().Width;
-        }
-        else
-        {
-            TextFormatter.Size = new Size (w, SuperView?.Viewport.Height ?? 0);
+            // Whenever DimAutoStyle.Text is set, ContentSize will match TextFormatter.Size.
+            ContentSize = TextFormatter.Size;
+            return;
         }
 
-        int h = ContentSize.Height + GetHotKeySpecifierLength ();
+        TextFormatter.AutoSize = false;
+        TextFormatter.Size = new Size (ContentSize.Width, ContentSize.Height);
+    }
 
-        // TODO: This is a hack. Figure out how to move this into DimDimAuto
-        if (Height is Dim.DimAuto heightAuto && heightAuto._style != Dim.DimAutoStyle.Subviews)
-        {
-            TextFormatter.NeedsFormat = true;
-            h = TextFormatter.FormatAndGetSize ().Height;
-        }
+    ////private bool IsValidAutoSize (out Size autoSize)
+    ////{
+    ////    Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
 
-        TextFormatter.Size = new Size (w, h);
-    }
+    ////    autoSize = new Size (
+    ////                         rect.Size.Width - GetHotKeySpecifierLength (),
+    ////                         rect.Size.Height - GetHotKeySpecifierLength (false));
+
+    ////    return !((ValidatePosDim && (!(Width is Dim.DimAbsolute) || !(Height is Dim.DimAbsolute)))
+    ////             || _frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength ()
+    ////             || _frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false));
+    ////}
 
-    //private bool IsValidAutoSize (out Size autoSize)
+    //private bool IsValidAutoSizeHeight (Dim height)
     //{
     //    Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
+    //    int dimValue = height.Anchor (0);
 
-    //    autoSize = new Size (
-    //                         rect.Size.Width - GetHotKeySpecifierLength (),
-    //                         rect.Size.Height - GetHotKeySpecifierLength (false));
-
-    //    return !((ValidatePosDim && (!(Width is Dim.DimAbsolute) || !(Height is Dim.DimAbsolute)))
-    //             || _frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength ()
-    //             || _frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false));
+    //    return !((ValidatePosDim && !(height is Dim.DimAbsolute)) || dimValue != rect.Size.Height - GetHotKeySpecifierLength (false));
     //}
 
-    private bool IsValidAutoSizeHeight (Dim height)
-    {
-        Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
-        int dimValue = height.Anchor (0);
-
-        return !((ValidatePosDim && !(height is Dim.DimAbsolute)) || dimValue != rect.Size.Height - GetHotKeySpecifierLength (false));
-    }
-
-    private bool IsValidAutoSizeWidth (Dim width)
-    {
-        Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
-        int dimValue = width.Anchor (0);
+    //private bool IsValidAutoSizeWidth (Dim width)
+    //{
+    //    Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
+    //    int dimValue = width.Anchor (0);
 
-        return !((ValidatePosDim && !(width is Dim.DimAbsolute)) || dimValue != rect.Size.Width - GetHotKeySpecifierLength ());
-    }
+    //    return !((ValidatePosDim && !(width is Dim.DimAbsolute)) || dimValue != rect.Size.Width - GetHotKeySpecifierLength ());
+    //}
 
     ///// <summary>
     /////     Sets the size of the View to the minimum width or height required to fit <see cref="Text"/>.

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

@@ -20,11 +20,10 @@ public class CheckBox : View
         _charChecked = Glyphs.Checked;
         _charUnChecked = Glyphs.UnChecked;
 
-        // Ensures a height of 1 if AutoSize is set to false
+        Width = Dim.Auto (Dim.DimAutoStyle.Text);
         Height = 1;
 
         CanFocus = true;
-        AutoSize = true;
 
         // Things this view knows how to do
         AddCommand (Command.Accept, OnToggled);

+ 1 - 1
Terminal.Gui/Views/ScrollBarView.cs

@@ -944,7 +944,7 @@ public class ScrollBarView : View
         // BUGBUG: v2 - If Host is also the ScrollBarView's superview, this is all bogus because it's not
         // supported that a view can reference it's superview's Dims. This code also assumes the host does 
         //  not have a margin/borderframe/padding.
-        if (!IsInitialized)
+        if (!IsInitialized || _otherScrollBarView is { IsInitialized: false })
         {
             return;
         }

+ 17 - 25
UICatalog/Scenarios/Buttons.cs

@@ -33,7 +33,14 @@ public class Buttons : Scenario
         defaultButton.Accept += (s, e) => Application.RequestStop ();
         main.Add (defaultButton);
 
-        var swapButton = new Button { X = 50, Text = "S_wap Default (Absolute Layout)" };
+        var swapButton = new Button
+        {
+            X = 50,
+            Width = 45,
+            Height = 3,
+            Text = "S_wap Default (Size = 45, 3)",
+            ColorScheme = Colors.ColorSchemes ["Error"]
+        };
 
         swapButton.Accept += (s, e) =>
                              {
@@ -51,29 +58,23 @@ public class Buttons : Scenario
                              };
         }
 
-        var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (editLabel) + 1, Text = "Color Buttons:" };
+        var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (swapButton) + 1, Text = "Color Buttons: " };
         main.Add (colorButtonsLabel);
 
         View prev = colorButtonsLabel;
 
-        //With this method there is no need to call Application.TopReady += () => Application.TopRedraw (Top.Bounds);
-        Pos x = Pos.Right (colorButtonsLabel) + 2;
-
         foreach (KeyValuePair<string, ColorScheme> colorScheme in Colors.ColorSchemes)
         {
             var colorButton = new Button
             {
-                ColorScheme = colorScheme.Value,
-                X = Pos.Right (prev) + 2,
+                X = Pos.Right (prev),
                 Y = Pos.Y (colorButtonsLabel),
-                Text = $"_{colorScheme.Key}"
+                Text = $"_{colorScheme.Key}",
+                ColorScheme = colorScheme.Value,
             };
             DoMessage (colorButton, colorButton.Text);
             main.Add (colorButton);
             prev = colorButton;
-
-            // BUGBUG: AutoSize is true and the X doesn't change
-            //x += colorButton.Frame.Width + 2;
         }
 
         Button button;
@@ -91,7 +92,7 @@ public class Buttons : Scenario
 
         // Note the 'N' in 'Newline' will be the hotkey
         main.Add (
-                  button = new () { X = 2, Y = Pos.Bottom (button) + 1, Text = "a Newline\nin the button" }
+                  button = new () { X = 2, Y = Pos.Bottom (button) + 1, Height = 2, Text = "a Newline\nin the button" }
                  );
         button.Accept += (s, e) => MessageBox.Query ("Message", "Question?", "Yes", "No");
 
@@ -110,16 +111,14 @@ public class Buttons : Scenario
 
         var removeButton = new Button
         {
-            X = 2, Y = Pos.Bottom (button) + 1, ColorScheme = Colors.ColorSchemes ["Error"], Text = "Remove this button"
+            X = 2, Y = Pos.Bottom (button) + 1,
+            ColorScheme = Colors.ColorSchemes ["Error"], Text = "Remove this button"
         };
         main.Add (removeButton);
 
         // This in interesting test case because `moveBtn` and below are laid out relative to this one!
         removeButton.Accept += (s, e) =>
                                {
-                                   // Now this throw a InvalidOperationException on the TopologicalSort method as is expected.
-                                   //main.Remove (removeButton);
-
                                    removeButton.Visible = false;
                                };
 
@@ -138,7 +137,6 @@ public class Buttons : Scenario
         {
             X = 0,
             Y = Pos.Center () - 1,
-            AutoSize = false,
             Width = 30,
             Height = 1,
             ColorScheme = Colors.ColorSchemes ["Error"],
@@ -148,29 +146,23 @@ public class Buttons : Scenario
         moveBtn.Accept += (s, e) =>
                           {
                               moveBtn.X = moveBtn.Frame.X + 5;
-
-                              // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
-                              //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
                           };
         computedFrame.Add (moveBtn);
 
         // Demonstrates how changing the View.Frame property can SIZE Views (#583)
         var sizeBtn = new Button
         {
-            X = 0,
             Y = Pos.Center () + 1,
-            AutoSize = false,
+            X = 0,
             Width = 30,
             Height = 1,
+            Text = "Grow This \u263a Button _via Pos",
             ColorScheme = Colors.ColorSchemes ["Error"],
-            Text = "Size This \u263a Button _via Pos"
         };
 
         sizeBtn.Accept += (s, e) =>
                           {
                               sizeBtn.Width = sizeBtn.Frame.Width + 5;
-
-                              //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
                           };
         computedFrame.Add (sizeBtn);
 

+ 3 - 3
UICatalog/Scenarios/Dialogs.cs

@@ -21,10 +21,10 @@ public class Dialogs : Scenario
             Text = "_Number of Buttons:"
         };
 
-        var label = new Label {
-            X = 0, 
+        var label = new Label
+        {
+            X = 0,
             Y = 0,
-            AutoSize = false,
             Width = Dim.Width (numButtonsLabel),
             Height = 1,
             TextAlignment = TextAlignment.Right,

+ 34 - 18
UnitTests/Text/TextFormatterTests.cs

@@ -2197,33 +2197,30 @@ ssb
     {
         var tf = new TextFormatter { Direction = textDirection, Text = "你你" };
 
-        if (textDirection == TextDirection.LeftRight_TopBottom)
-        {
-            Assert.Equal (4, tf.Size.Width);
-            Assert.Equal (1, tf.Size.Height);
-        }
-        else
-        {
-            Assert.Equal (2, tf.Size.Width);
-            Assert.Equal (2, tf.Size.Height);
-        }
+        //if (textDirection == TextDirection.LeftRight_TopBottom)
+        //{
+        //    Assert.Equal (4, tf.Size.Width);
+        //    Assert.Equal (1, tf.Size.Height);
+        //}
+        //else
+        //{
+        //    Assert.Equal (2, tf.Size.Width);
+        //    Assert.Equal (2, tf.Size.Height);
+        //}
 
         Assert.False (tf.AutoSize);
 
         tf.Size = new (1, 1);
-        Assert.Equal (1, tf.Size.Width);
-        Assert.Equal (1, tf.Size.Height);
+        Assert.Equal (new Size (1, 1), tf.Size);
         tf.AutoSize = true;
 
         if (textDirection == TextDirection.LeftRight_TopBottom)
         {
-            Assert.Equal (4, tf.Size.Width);
-            Assert.Equal (1, tf.Size.Height);
+            Assert.Equal (new Size (4, 1), tf.Size);
         }
         else
         {
-            Assert.Equal (2, tf.Size.Width);
-            Assert.Equal (2, tf.Size.Height);
+            Assert.Equal (new Size (2, 2), tf.Size);
         }
     }
 
@@ -2396,6 +2393,26 @@ ssb
         }
     }
 
+    [Theory]
+    // BUGBUG: This is a bug in the current implementation, the expected size should be 0, 0 because autosize is false
+    [InlineData ("你", TextDirection.LeftRight_TopBottom, false, 2, 1)]
+    [InlineData ("你", TextDirection.LeftRight_TopBottom, true, 2, 1)]
+    // BUGBUG: This is a bug in the current implementation, the expected size should be 0, 0 because autosize is false
+    [InlineData ("你", TextDirection.TopBottom_LeftRight, false, 1, 2)]
+    [InlineData ("你", TextDirection.TopBottom_LeftRight, true, 1, 2)]
+
+    // BUGBUG: This is a bug in the current implementation, the expected size should be 0, 0 because autosize is false
+    [InlineData ("你你", TextDirection.LeftRight_TopBottom, false, 4, 1)]
+    [InlineData ("你你", TextDirection.LeftRight_TopBottom, true, 4, 1)]
+    // BUGBUG: This is a bug in the current implementation, the expected size should be 0, 0 because autosize is false
+    [InlineData ("你你", TextDirection.TopBottom_LeftRight, false, 1, 4)]
+    [InlineData ("你你", TextDirection.TopBottom_LeftRight, true, 1, 4)]
+    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 };
+        Assert.Equal (new Size (expectedWidth, expectedHeight), tf.Size);
+    }
+
     [Theory]
     [InlineData (TextDirection.LeftRight_TopBottom, false)]
     [InlineData (TextDirection.LeftRight_TopBottom, true)]
@@ -2404,8 +2421,7 @@ ssb
     public void TestSize_TextChange (TextDirection textDirection, bool autoSize)
     {
         var tf = new TextFormatter { Direction = textDirection, Text = "你", AutoSize = autoSize };
-        Assert.Equal (2, tf.Size.Width);
-        Assert.Equal (1, tf.Size.Height);
+        Assert.Equal (new Size (2, 1), tf.Size);
         tf.Text = "你你";
 
         Assert.Equal (autoSize, tf.AutoSize);

+ 24 - 0
UnitTests/View/Layout/Dim.AutoTests.cs

@@ -203,6 +203,28 @@ public class DimAutoTests
         Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame);
     }
 
+    [Fact]
+    public void NoSubViews_Does_Nothing_Vertical ()
+    {
+        var superView = new View
+        {
+            X = 0,
+            Y = 0,
+            Width = Dim.Auto (),
+            Height = Dim.Auto (),
+            TextDirection = TextDirection.TopBottom_LeftRight,
+            ValidatePosDim = true
+        };
+
+        superView.BeginInit ();
+        superView.EndInit ();
+        superView.SetRelativeLayout (new (10, 10));
+        Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame);
+
+        superView.SetRelativeLayout (new (10, 10));
+        Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame);
+    }
+
     [Theory]
     [InlineData (0, 0, 0, 0, 0, 0)]
     [InlineData (0, 0, 5, 0, 5, 0)]
@@ -648,6 +670,8 @@ public class DimAutoTests
         super.Add (view);
 
         Rectangle expectedViewport = new (0, 0, 8, 1);
+        Assert.Equal (expectedViewport.Size, view.ContentSize);
+        Assert.Equal (expectedViewport, view.Frame);
         Assert.Equal (expectedViewport, view.Viewport);
 
         super.LayoutSubviews ();

+ 167 - 166
UnitTests/View/Text/AutoSizeTrueTests.cs

@@ -918,205 +918,205 @@ public class AutoSizeTrueTests
         Assert.Equal (expectedLabelBounds, label.Viewport);
     }
 
-    [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);
-        var top = new Toplevel ();
-        top.Add (win);
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+    //[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);
+    //    var top = new Toplevel ();
+    //    top.Add (win);
+    //    Application.Begin (top);
+    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
 
-        Size size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 1), size);
+    //    Size size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 1), size);
 
-        view.Text = $"{text}\n{text}";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 2), size);
+    //    view.Text = $"{text}\n{text}";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 2), size);
 
-        view.Text = $"{text}\n{text}\n{text}+";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length + 1, 3), size);
+    //    view.Text = $"{text}\n{text}\n{text}+";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length + 1, 3), size);
 
-        text = string.Empty;
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (0, 0), size);
+    //    text = string.Empty;
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (0, 0), size);
 
-        text = "1";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (1, 1), size);
+    //    text = "1";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (1, 1), size);
 
-        text = "界";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (2, 1), size);
-    }
+    //    text = "界";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (2, 1), size);
+    //}
 
-    [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);
-        var top = new Toplevel ();
-        top.Add (win);
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+    //[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);
+    //    var top = new Toplevel ();
+    //    top.Add (win);
+    //    Application.Begin (top);
+    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
 
-        Size size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 1), size);
+    //    Size size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 1), size);
 
-        view.Text = $"{text}\n{text}";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 2), size);
+    //    view.Text = $"{text}\n{text}";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 2), size);
 
-        view.Text = $"{text}\n{text}\n{text}+";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length + 1, 3), size);
+    //    view.Text = $"{text}\n{text}\n{text}+";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length + 1, 3), size);
 
-        text = string.Empty;
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (0, 0), size);
+    //    text = string.Empty;
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (0, 0), size);
 
-        text = "1";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (1, 1), size);
+    //    text = "1";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (1, 1), size);
 
-        text = "界";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (2, 1), size);
-    }
+    //    text = "界";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    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);
-        var top = new Toplevel ();
-        top.Add (win);
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+    //[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);
+    //    var top = new Toplevel ();
+    //    top.Add (win);
+    //    Application.Begin (top);
+    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
 
-        Size size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 1), size);
+    //    Size size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 1), size);
 
-        view.Text = $"{text}\n{text}";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 2), size);
+    //    view.Text = $"{text}\n{text}";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 2), size);
 
-        view.Text = $"{text}\n{text}\n{text}+";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length + 1, 3), size);
+    //    view.Text = $"{text}\n{text}\n{text}+";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length + 1, 3), size);
 
-        text = string.Empty;
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (0, 0), size);
+    //    text = string.Empty;
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (0, 0), size);
 
-        text = "1";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (1, 1), size);
+    //    text = "1";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (1, 1), size);
 
-        text = "界";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (2, 1), size);
-    }
+    //    text = "界";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    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);
-        var top = new Toplevel ();
-        top.Add (win);
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+    //[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);
+    //    var top = new Toplevel ();
+    //    top.Add (win);
+    //    Application.Begin (top);
+    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
 
-        Size size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 1), size);
+    //    Size size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 1), size);
 
-        view.Text = $"{text}\n{text}";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length, 2), size);
+    //    view.Text = $"{text}\n{text}";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length, 2), size);
 
-        view.Text = $"{text}\n{text}\n{text}+";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (text.Length + 1, 3), size);
+    //    view.Text = $"{text}\n{text}\n{text}+";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (text.Length + 1, 3), size);
 
-        text = string.Empty;
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (0, 0), size);
+    //    text = string.Empty;
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (0, 0), size);
 
-        text = "1";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (1, 1), size);
+    //    text = "1";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (1, 1), size);
 
-        text = "界";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (2, 1), size);
-    }
+    //    text = "界";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    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);
-        var top = new Toplevel ();
-        top.Add (win);
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
+    //[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);
+    //    var top = new Toplevel ();
+    //    top.Add (win);
+    //    Application.Begin (top);
+    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
 
-        Size size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (1, text.Length), size);
+    //    Size size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (1, text.Length), size);
 
-        view.Text = $"{text}\n{text}";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (2, text.Length), size);
+    //    view.Text = $"{text}\n{text}";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (2, text.Length), size);
 
-        view.Text = $"{text}\n{text}\n{text}+";
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (3, text.Length + 1), size);
+    //    view.Text = $"{text}\n{text}\n{text}+";
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (3, text.Length + 1), size);
 
-        text = string.Empty;
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (0, 0), size);
+    //    text = string.Empty;
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (0, 0), size);
 
-        text = "1";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (1, 1), size);
+    //    text = "1";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (1, 1), size);
 
-        text = "界";
-        view.Text = text;
-        size = view.GetTextAutoSize ();
-        Assert.Equal (new Size (2, 1), size);
-    }
+    //    text = "界";
+    //    view.Text = text;
+    //    size = view.GetTextAutoSize ();
+    //    Assert.Equal (new Size (2, 1), size);
+    //}
 
     [Fact]
     [SetupFakeDriver]
@@ -1721,6 +1721,7 @@ Y
         view.TextDirection = TextDirection.TopBottom_LeftRight;
         Application.Refresh ();
 
+        Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
         Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
 
         expected = @"
@@ -1746,7 +1747,7 @@ Y
         // Setting to false causes Width and Height to be set to the current ContentSize
         view.AutoSize = false;
 
-        Assert.Equal (new Rectangle (0, 0, 12, 12), view.Frame);
+        Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
 
         view.Height = 1;
         view.Width = 12;

+ 43 - 3
UnitTests/View/Text/TextTests.cs

@@ -8,10 +8,9 @@ namespace Terminal.Gui.ViewTests;
 ///     Tests of the <see cref="View.Text"/> and <see cref="View.TextFormatter"/> properties (independent of
 ///     AutoSize).
 /// </summary>
-public class TextTests
+public class TextTests (ITestOutputHelper output)
 {
-    private readonly ITestOutputHelper _output;
-    public TextTests (ITestOutputHelper output) { _output = output; }
+    private readonly ITestOutputHelper _output = output;
 
     // Test that View.PreserveTrailingSpaces removes trailing spaces
     [Fact]
@@ -111,6 +110,47 @@ public class TextTests
         protected override void UpdateTextFormatterText () { TextFormatter.Text = $">{Text}<"; }
     }
 
+    [Fact]
+    public void TextDirection_Horizontal_Dims_Correct ()
+    {
+        // Initializes a view with a vertical direction
+        var view = new View
+        {
+            Text = "01234",
+            TextDirection = TextDirection.LeftRight_TopBottom,
+            Width = Dim.Auto (Dim.DimAutoStyle.Text),
+            Height = Dim.Auto (Dim.DimAutoStyle.Text)
+        };
+        Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame);
+        Assert.Equal (new Rectangle (0, 0, 5, 1), view.Viewport);
+
+        view.BeginInit ();
+        view.EndInit ();
+        Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame);
+        Assert.Equal (new Rectangle (0, 0, 5, 1), view.Viewport);
+    }
+
+    [Fact]
+    public void TextDirection_Vertical_Dims_Correct ()
+    {
+        // Initializes a view with a vertical direction
+        var view = new View
+        {
+            TextDirection = TextDirection.TopBottom_LeftRight,
+            Text = "01234",
+            Width = Dim.Auto (Dim.DimAutoStyle.Text),
+            Height = Dim.Auto (Dim.DimAutoStyle.Text),
+        };
+        Assert.Equal (new Rectangle (0, 0, 1, 5), view.Frame);
+        Assert.Equal (new Rectangle (0, 0, 1, 5), view.Viewport);
+
+        view.BeginInit ();
+        Assert.Equal (new Rectangle (0, 0, 1, 5), view.Frame);
+        view.EndInit ();
+        Assert.Equal (new Rectangle (0, 0, 1, 5), view.Frame);
+        Assert.Equal (new Rectangle (0, 0, 1, 5), view.Viewport);
+    }
+
     // Test behavior of AutoSize property. 
     // - Default is false
     // - Setting to true invalidates Height/Width

+ 4 - 1
UnitTests/View/ViewTests.cs

@@ -829,7 +829,10 @@ At 0,0
         // Initializes a view with a vertical direction
         r = new View
         {
-            Text = "Vertical View", TextDirection = TextDirection.TopBottom_LeftRight, AutoSize = true
+            Text = "Vertical View",
+            TextDirection = TextDirection.TopBottom_LeftRight,
+            Width = Dim.Auto (),
+            Height = Dim.Auto ()
         }; // BUGBUG: AutoSize or Height need be set
         Assert.NotNull (r);
         Assert.Equal (LayoutStyle.Computed, r.LayoutStyle);

+ 266 - 237
UnitTests/Views/ButtonTests.cs

@@ -32,253 +32,278 @@ public class ButtonTests (ITestOutputHelper output)
         view.Dispose ();
     }
 
-    // BUGBUG: This test is NOT a unit test and needs to be broken apart into 
-    //         more specific tests (e.g. it tests Checkbox as well as Button)
-    [Fact]
-    [AutoInitShutdown]
-    public void AutoSize_False_With_Fixed_Width ()
-    {
-        var tab = new View ();
-
-        var lblWidth = 8;
-
-        var view = new View
-        {
-            Y = 1,
-            Width = lblWidth,
-            Height = 1,
-            TextAlignment = TextAlignment.Right,
-            Text = "Find:"
-        };
-        tab.Add (view);
+//    // BUGBUG: This test is NOT a unit test and needs to be broken apart into 
+//    //         more specific tests (e.g. it tests Checkbox as well as Button)
+//    [Fact]
+//    [AutoInitShutdown]
+//    public void AutoSize_False_With_Fixed_Width ()
+//    {
+//        var tab = new View ();
+
+//        var lblWidth = 8;
+
+//        var view = new View
+//        {
+//            Y = 1,
+//            Width = lblWidth,
+//            Height = 1,
+//            TextAlignment = TextAlignment.Right,
+//            Text = "Find:"
+//        };
+//        tab.Add (view);
+
+//        var txtToFind = new TextField
+//        {
+//            X = Pos.Right (view) + 1, Y = Pos.Top (view), Width = 20, Text = "Testing buttons."
+//        };
+//        tab.Add (txtToFind);
+
+//        var btnFindNext = new Button
+//        {
+//            X = Pos.Right (txtToFind) + 1,
+//            Y = Pos.Top (view),
+//            Width = 20,
+//            Enabled = !string.IsNullOrEmpty (txtToFind.Text),
+//            TextAlignment = TextAlignment.Centered,
+//            IsDefault = true,
+//            Text = "Find _Next"
+//        };
+//        tab.Add (btnFindNext);
+
+//        var btnFindPrevious = new Button
+//        {
+//            X = Pos.Right (txtToFind) + 1,
+//            Y = Pos.Top (btnFindNext) + 1,
+//            Width = 20,
+//            Enabled = !string.IsNullOrEmpty (txtToFind.Text),
+//            TextAlignment = TextAlignment.Centered,
+//            Text = "Find _Previous"
+//        };
+//        tab.Add (btnFindPrevious);
+
+//        var btnCancel = new Button
+//        {
+//            X = Pos.Right (txtToFind) + 1,
+//            Y = Pos.Top (btnFindPrevious) + 2,
+//            Width = 20,
+//            TextAlignment = TextAlignment.Centered,
+//            Text = "Cancel"
+//        };
+//        tab.Add (btnCancel);
+
+//        var ckbMatchCase = new CheckBox
+//        {
+//            X = 0,
+//            Y = Pos.Top (txtToFind) + 2,
+//            Checked = true, Text = "Match c_ase"
+//        };
+//        tab.Add (ckbMatchCase);
+//        Assert.Equal (new (0, 3, 10, 1), ckbMatchCase.Frame);
+
+//        var ckbMatchWholeWord = new CheckBox
+//        {
+//            X = 0,
+//            Y = Pos.Top (ckbMatchCase) + 1,
+//            Checked = false,
+//            Text = "Match _whole word"
+//        };
+//        tab.Add (ckbMatchWholeWord);
+
+//        var tabView = new TabView { Width = Dim.Fill (), Height = Dim.Fill () };
+//        tabView.AddTab (new () { DisplayText = "Find", View = tab }, true);
+
+//        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
+
+//        tab.Width = view.Width + txtToFind.Width + btnFindNext.Width + 2;
+//        tab.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4;
+
+//        win.Add (tabView);
+//        var top = new Toplevel ();
+//        top.Add (win);
+
+//        Application.Begin (top);
+//        ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
+
+//        Assert.Equal (new (0, 3, 10, 1), ckbMatchCase.Frame);
+
+//        Assert.Equal (new (0, 0, 54, 11), win.Frame);
+//        Assert.Equal (new (0, 0, 52, 9), tabView.Frame);
+//        Assert.Equal (new (0, 0, 50, 7), tab.Frame);
+//        Assert.Equal (new (0, 1, 8, 1), view.Frame);
+//        Assert.Equal (new (9, 1, 20, 1), txtToFind.Frame);
+
+//        Assert.Equal (0, txtToFind.ScrollOffset);
+//        Assert.Equal (16, txtToFind.CursorPosition);
+
+//        Assert.Equal (new (30, 1, 20, 1), btnFindNext.Frame);
+//        Assert.Equal (new (30, 2, 20, 1), btnFindPrevious.Frame);
+//        Assert.Equal (new (30, 4, 20, 1), btnCancel.Frame);
+
+//        //        Assert.Equal (new (0, 3, 12, 1), ckbMatchCase.Frame);
+//        //        Assert.Equal (new (0, 4, 18, 1), ckbMatchWholeWord.Frame);
+
+//        var btn1 =
+//            $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Find Next {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
+//        var btn2 = $"{CM.Glyphs.LeftBracket} Find Previous {CM.Glyphs.RightBracket}";
+//        var btn3 = $"{CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket}";
+
+//        var expected = @$"
+//┌────────────────────────────────────────────────────┐
+//│╭────╮                                              │
+//││Find│                                              │
+//││    ╰─────────────────────────────────────────────╮│
+//││                                                  ││
+//││   Find: Testing buttons.       {btn1}   ││
+//││                               {btn2}  ││
+//││{CM.Glyphs.Checked} Match case                                      ││
+//││{CM.Glyphs.UnChecked} Match whole word                 {btn3}     ││
+//│└──────────────────────────────────────────────────┘│
+//└────────────────────────────────────────────────────┘
+//";
+
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+//        view.Dispose ();
+//    }
+
+//    [Fact]
+//    [AutoInitShutdown]
+//    public void AutoSize_Stays_True_AnchorEnd ()
+//    {
+//        var btn = new Button { Y = Pos.Center (), Text = "Say Hello 你", AutoSize = true };
+//        var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
+
+//        btn.X = Pos.AnchorEnd (0) - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
+//        btn.X = Pos.AnchorEnd (0) - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
+
+//        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
+//        win.Add (btn);
+//        var top = new Toplevel ();
+//        top.Add (win);
+
+//        Assert.True (btn.AutoSize);
+
+//        Application.Begin (top);
+//        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+
+//        var expected = @$"
+//┌────────────────────────────┐
+//│                            │
+//│            {btnTxt}│
+//│                            │
+//└────────────────────────────┘
+//";
+
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+
+//        Assert.True (btn.AutoSize);
+//        btn.Text = "Say Hello 你 changed";
+//        btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
+//        Assert.True (btn.AutoSize);
+//        Application.Refresh ();
+
+//        expected = @$"
+//┌────────────────────────────┐
+//│                            │
+//│    {btnTxt}│
+//│                            │
+//└────────────────────────────┘
+//";
+
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+//        top.Dispose ();
+//    }
+
+//    [Fact]
+//    [AutoInitShutdown]
+//    public void AutoSize_Stays_True_With_EmptyText ()
+//    {
+//        var btn = new Button { X = Pos.Center (), Y = Pos.Center (), AutoSize = true };
+
+//        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
+//        win.Add (btn);
+//        var top = new Toplevel ();
+//        top.Add (win);
+
+//        Assert.True (btn.AutoSize);
+
+//        btn.Text = "Say Hello 你";
+
+//        Assert.True (btn.AutoSize);
+
+//        Application.Begin (top);
+//        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+
+//        var expected = @$"
+//┌────────────────────────────┐
+//│                            │
+//│      {CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}      │
+//│                            │
+//└────────────────────────────┘
+//";
+
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+//        top.Dispose ();
+//    }
 
-        var txtToFind = new TextField
-        {
-            X = Pos.Right (view) + 1, Y = Pos.Top (view), Width = 20, Text = "Testing buttons."
-        };
-        tab.Add (txtToFind);
-
-        var btnFindNext = new Button
-        {
-            AutoSize = false,
-            X = Pos.Right (txtToFind) + 1,
-            Y = Pos.Top (view),
-            Width = 20,
-            Enabled = !string.IsNullOrEmpty (txtToFind.Text),
-            TextAlignment = TextAlignment.Centered,
-            IsDefault = true,
-            Text = "Find _Next"
-        };
-        tab.Add (btnFindNext);
-
-        var btnFindPrevious = new Button
-        {
-            AutoSize = false,
-            X = Pos.Right (txtToFind) + 1,
-            Y = Pos.Top (btnFindNext) + 1,
-            Width = 20,
-            Enabled = !string.IsNullOrEmpty (txtToFind.Text),
-            TextAlignment = TextAlignment.Centered,
-            Text = "Find _Previous"
-        };
-        tab.Add (btnFindPrevious);
-
-        var btnCancel = new Button
-        {
-            AutoSize = false,
-            X = Pos.Right (txtToFind) + 1,
-            Y = Pos.Top (btnFindPrevious) + 2,
-            Width = 20,
-            TextAlignment = TextAlignment.Centered,
-            Text = "Cancel"
-        };
-        tab.Add (btnCancel);
-
-        var ckbMatchCase = new CheckBox { X = 0, Y = Pos.Top (txtToFind) + 2, Checked = true, Text = "Match c_ase" };
-        tab.Add (ckbMatchCase);
-
-        var ckbMatchWholeWord = new CheckBox
+    [Theory]
+    [InlineData ("01234", 0, 0, 0, 0)]
+    [InlineData ("01234", 1, 0, 1, 0)]
+    [InlineData ("01234", 0, 1, 0, 1)]
+    [InlineData ("01234", 1, 1, 1, 1)]
+    [InlineData ("01234", 10, 1, 10, 1)]
+    [InlineData ("01234", 10, 3, 10, 3)]
+    [InlineData ("0_1234", 0, 0, 0, 0)]
+    [InlineData ("0_1234", 1, 0, 1, 0)]
+    [InlineData ("0_1234", 0, 1, 0, 1)]
+    [InlineData ("0_1234", 1, 1, 1, 1)]
+    [InlineData ("0_1234", 10, 1, 10, 1)]
+    [InlineData ("0_12你", 10, 3, 10, 3)]
+    [InlineData ("0_12你", 0, 0, 0, 0)]
+    [InlineData ("0_12你", 1, 0, 1, 0)]
+    [InlineData ("0_12你", 0, 1, 0, 1)]
+    [InlineData ("0_12你", 1, 1, 1, 1)]
+    [InlineData ("0_12你", 10, 1, 10, 1)]
+    [InlineData ("0_12你", 10, 3, 10, 3)]
+    public void Button_AbsoluteSize_Text (string text, int width, int height, int expectedWidth, int expectedHeight)
+    {
+        var btn1 = new Button
         {
-            X = 0, Y = Pos.Top (ckbMatchCase) + 1, Checked = false, Text = "Match _whole word"
+            X = 0,
+            Y = 0,
+            Width = width,
+            Height = height,
+            Text = text
         };
-        tab.Add (ckbMatchWholeWord);
-
-        var tabView = new TabView { Width = Dim.Fill (), Height = Dim.Fill () };
-        tabView.AddTab (new () { DisplayText = "Find", View = tab }, true);
-
-        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
-
-        tab.Width = view.Width + txtToFind.Width + btnFindNext.Width + 2;
-        tab.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4;
-
-        win.Add (tabView);
-        var top = new Toplevel ();
-        top.Add (win);
-
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (54, 11);
-
-        Assert.Equal (new (0, 0, 54, 11), win.Frame);
-        Assert.Equal (new (0, 0, 52, 9), tabView.Frame);
-        Assert.Equal (new (0, 0, 50, 7), tab.Frame);
-        Assert.Equal (new (0, 1, 8, 1), view.Frame);
-        Assert.Equal (new (9, 1, 20, 1), txtToFind.Frame);
-
-        Assert.Equal (0, txtToFind.ScrollOffset);
-        Assert.Equal (16, txtToFind.CursorPosition);
-
-        Assert.Equal (new (30, 1, 20, 1), btnFindNext.Frame);
-        Assert.Equal (new (30, 2, 20, 1), btnFindPrevious.Frame);
-        Assert.Equal (new (30, 4, 20, 1), btnCancel.Frame);
-
-        //        Assert.Equal (new (0, 3, 12, 1), ckbMatchCase.Frame);
-        //        Assert.Equal (new (0, 4, 18, 1), ckbMatchWholeWord.Frame);
-
-        var btn1 =
-            $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Find Next {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}";
-        var btn2 = $"{CM.Glyphs.LeftBracket} Find Previous {CM.Glyphs.RightBracket}";
-        var btn3 = $"{CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket}";
-
-        var expected = @$"
-┌────────────────────────────────────────────────────┐
-│╭────╮                                              │
-││Find│                                              │
-││    ╰─────────────────────────────────────────────╮│
-││                                                  ││
-││   Find: Testing buttons.       {btn1}   ││
-││                               {btn2}  ││
-││{CM.Glyphs.Checked} Match case                                      ││
-││{CM.Glyphs.UnChecked} Match whole word                 {btn3}     ││
-│└──────────────────────────────────────────────────┘│
-└────────────────────────────────────────────────────┘
-";
-
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-        view.Dispose ();
-    }
-
-    [Fact]
-    [AutoInitShutdown]
-    public void AutoSize_Stays_True_AnchorEnd ()
-    {
-        var btn = new Button { Y = Pos.Center (), Text = "Say Hello 你", AutoSize = true };
-        var btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
-
-        btn.X = Pos.AnchorEnd (0) - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
-        btn.X = Pos.AnchorEnd (0) - Pos.Function (() => btn.TextFormatter.Text.GetColumns ());
-
-        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
-        win.Add (btn);
-        var top = new Toplevel ();
-        top.Add (win);
-
-        Assert.True (btn.AutoSize);
-
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
-
-        var expected = @$"
-┌────────────────────────────┐
-│                            │
-│            {btnTxt}│
-│                            │
-└────────────────────────────┘
-";
-
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
 
-        Assert.True (btn.AutoSize);
-        btn.Text = "Say Hello 你 changed";
-        btnTxt = $"{CM.Glyphs.LeftBracket} {btn.Text} {CM.Glyphs.RightBracket}";
-        Assert.True (btn.AutoSize);
-        Application.Refresh ();
+        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.TextFormatter.Size);
 
-        expected = @$"
-┌────────────────────────────┐
-│                            │
-│    {btnTxt}│
-│                            │
-└────────────────────────────┘
-";
-
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-        top.Dispose ();
+        btn1.Dispose ();
     }
 
-    [Fact]
-    [AutoInitShutdown]
-    public void AutoSize_Stays_True_With_EmptyText ()
-    {
-        var btn = new Button { X = Pos.Center (), Y = Pos.Center (), AutoSize = true };
-
-        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
-        win.Add (btn);
-        var top = new Toplevel ();
-        top.Add (win);
-
-        Assert.True (btn.AutoSize);
-
-        btn.Text = "Say Hello 你";
-
-        Assert.True (btn.AutoSize);
-
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
-
-        var expected = @$"
-┌────────────────────────────┐
-│                            │
-│      {CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}      │
-│                            │
-└────────────────────────────┘
-";
-
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
-        top.Dispose ();
-    }
-
-    [Fact]
-    [SetupFakeDriver]
-    public void Button_AutoSize_False_With_Fixed_Width ()
+    [Theory]
+    [InlineData (0, 0, 0, 0)]
+    [InlineData (1, 0, 1, 0)]
+    [InlineData (0, 1, 0, 1)]
+    [InlineData (1, 1, 1, 1)]
+    [InlineData (10, 1, 10, 1)]
+    [InlineData (10, 3, 10, 3)]
+    public void Button_AbsoluteSize_DefaultText (int width, int height, int expectedWidth, int expectedHeight)
     {
-        ((FakeDriver)Application.Driver).SetBufferSize (20, 5);
-
-        var top = new View { Width = 20, Height = 5 };
-
         var btn1 = new Button
         {
-            AutoSize = false,
-            X = Pos.Center (),
-            Y = Pos.Center (),
-            Width = 16,
-            Height = 1,
-            Text = "Open me!"
+            X = 0,
+            Y = 0,
+            Width = width,
+            Height = height,
         };
 
-        var btn2 = new Button
-        {
-            AutoSize = false,
-            X = Pos.Center (),
-            Y = Pos.Center () + 1,
-            Width = 16,
-            Height = 1,
-            Text = "Close me!"
-        };
-        top.Add (btn1, btn2);
-        top.BeginInit ();
-        top.EndInit ();
-        top.Draw ();
-
-        Assert.Equal ("{Width=16, Height=1}", btn1.TextFormatter.Size.ToString ());
-        Assert.Equal ("{Width=16, Height=1}", btn2.TextFormatter.Size.ToString ());
-
-        TestHelpers.AssertDriverContentsWithFrameAre (
-                                                      @$"
-    {CM.Glyphs.LeftBracket} {btn1.Text} {CM.Glyphs.RightBracket}
-   {CM.Glyphs.LeftBracket} {btn2.Text} {CM.Glyphs.RightBracket}",
-                                                      output
-                                                     );
-        top.Dispose ();
+        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.TextFormatter.Size);
+
+        btn1.Dispose ();
     }
 
     [Fact]
@@ -342,7 +367,7 @@ public class ButtonTests (ITestOutputHelper output)
         Assert.Equal (string.Empty, btn.Text);
         btn.BeginInit ();
         btn.EndInit ();
-        btn.SetRelativeLayout(new (25,25));
+        btn.SetRelativeLayout (new (100, 100));
 
         Assert.Equal ($"{CM.Glyphs.LeftBracket}  {CM.Glyphs.RightBracket}", btn.TextFormatter.Text);
         Assert.False (btn.IsDefault);
@@ -384,6 +409,10 @@ public class ButtonTests (ITestOutputHelper output)
         Assert.True (btn.IsDefault);
         Assert.Equal (TextAlignment.Centered, btn.TextAlignment);
         Assert.True (btn.CanFocus);
+
+        btn.SetRelativeLayout (new (100, 100));
+        // 0123456789012345678901234567890123456789
+        // [* Test *]
         Assert.Equal (new (0, 0, 10, 1), btn.Viewport);
         Assert.Equal (new (0, 0, 10, 1), btn.Frame);
         Assert.Equal (KeyCode.T, btn.HotKey);
@@ -715,7 +744,7 @@ public class ButtonTests (ITestOutputHelper output)
         Assert.Equal (new (0, 0, 30, 5), pos);
         top.Dispose ();
     }
-    
+
     [Theory]
     [InlineData (MouseFlags.Button1Pressed, MouseFlags.Button1Released, MouseFlags.Button1Clicked)]
     [InlineData (MouseFlags.Button2Pressed, MouseFlags.Button2Released, MouseFlags.Button2Clicked)]

+ 137 - 74
UnitTests/Views/CheckBoxTests.cs

@@ -10,6 +10,67 @@ public class CheckBoxTests
     public CheckBoxTests (ITestOutputHelper output) { _output = output; }
 
 
+    [Theory]
+    [InlineData ("01234", 0, 0, 0, 0)]
+    [InlineData ("01234", 1, 0, 1, 0)]
+    [InlineData ("01234", 0, 1, 0, 1)]
+    [InlineData ("01234", 1, 1, 1, 1)]
+    [InlineData ("01234", 10, 1, 10, 1)]
+    [InlineData ("01234", 10, 3, 10, 3)]
+    [InlineData ("0_1234", 0, 0, 0, 0)]
+    [InlineData ("0_1234", 1, 0, 1, 0)]
+    [InlineData ("0_1234", 0, 1, 0, 1)]
+    [InlineData ("0_1234", 1, 1, 1, 1)]
+    [InlineData ("0_1234", 10, 1, 10, 1)]
+    [InlineData ("0_12你", 10, 3, 10, 3)]
+    [InlineData ("0_12你", 0, 0, 0, 0)]
+    [InlineData ("0_12你", 1, 0, 1, 0)]
+    [InlineData ("0_12你", 0, 1, 0, 1)]
+    [InlineData ("0_12你", 1, 1, 1, 1)]
+    [InlineData ("0_12你", 10, 1, 10, 1)]
+    [InlineData ("0_12你", 10, 3, 10, 3)]
+    public void CheckBox_AbsoluteSize_Text (string text, int width, int height, int expectedWidth, int expectedHeight)
+    {
+        var checkBox = new CheckBox
+        {
+            X = 0,
+            Y = 0,
+            Width = width,
+            Height = height,
+            Text = text
+        };
+
+        Assert.Equal (new Size (expectedWidth, expectedHeight), checkBox.Frame.Size);
+        Assert.Equal (new Size (expectedWidth, expectedHeight), checkBox.Viewport.Size);
+        Assert.Equal (new Size (expectedWidth, expectedHeight), checkBox.TextFormatter.Size);
+
+        checkBox.Dispose ();
+    }
+
+    [Theory]
+    [InlineData (0, 0, 0, 0)]
+    [InlineData (1, 0, 1, 0)]
+    [InlineData (0, 1, 0, 1)]
+    [InlineData (1, 1, 1, 1)]
+    [InlineData (10, 1, 10, 1)]
+    [InlineData (10, 3, 10, 3)]
+    public void CheckBox_AbsoluteSize_DefaultText (int width, int height, int expectedWidth, int expectedHeight)
+    {
+        var checkBox = new CheckBox
+        {
+            X = 0,
+            Y = 0,
+            Width = width,
+            Height = height,
+        };
+
+        Assert.Equal (new Size (expectedWidth, expectedHeight), checkBox.Frame.Size);
+        Assert.Equal (new Size (expectedWidth, expectedHeight), checkBox.Viewport.Size);
+        Assert.Equal (new Size (expectedWidth, expectedHeight), checkBox.TextFormatter.Size);
+
+        checkBox.Dispose ();
+    }
+
     // Test that Title and Text are the same
     [Fact]
     public void Text_Mirrors_Title ()
@@ -71,93 +132,93 @@ public class CheckBoxTests
         Assert.False (checkBox.Checked);
     }
 
-    [Fact]
-    [AutoInitShutdown]
-    public void AutoSize_Stays_True_AnchorEnd_With_HotKeySpecifier ()
-    {
-        var checkBox = new CheckBox { Y = Pos.Center (), Text = "C_heck this out 你" };
+//    [Fact]
+//    [AutoInitShutdown]
+//    public void AutoSize_Stays_True_AnchorEnd_With_HotKeySpecifier ()
+//    {
+//        var checkBox = new CheckBox { Y = Pos.Center (), Text = "C_heck this out 你" };
 
-        checkBox.X = Pos.AnchorEnd (0) - Pos.Function (() => checkBox.GetSizeNeededForTextWithoutHotKey ().Width);
+//        checkBox.X = Pos.AnchorEnd (0) - Pos.Function (() => checkBox.GetSizeNeededForTextWithoutHotKey ().Width);
 
-        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" };
-        win.Add (checkBox);
-        var top = new Toplevel ();
-        top.Add (win);
+//        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" };
+//        win.Add (checkBox);
+//        var top = new Toplevel ();
+//        top.Add (win);
 
-        Assert.True (checkBox.AutoSize);
+//        //Assert.True (checkBox.AutoSize);
 
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+//        Application.Begin (top);
+//        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
 
-        var expected = @$"
-┌┤Test Demo 你├──────────────┐
-│                            │
-│         {CM.Glyphs.UnChecked} Check this out 你│
-│                            │
-└────────────────────────────┘
-";
+//        var expected = @$"
+//┌┤Test Demo 你├──────────────┐
+//│                            │
+//│         {CM.Glyphs.UnChecked} Check this out 你│
+//│                            │
+//└────────────────────────────┘
+//";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
 
-        Assert.True (checkBox.AutoSize);
-        checkBox.Text = "Check this out 你 changed";
-        Assert.True (checkBox.AutoSize);
-        Application.Refresh ();
+//        //Assert.True (checkBox.AutoSize);
+//        checkBox.Text = "Check this out 你 changed";
+////        Assert.True (checkBox.AutoSize);
+//        Application.Refresh ();
 
-        expected = @$"
-┌┤Test Demo 你├──────────────┐
-│                            │
-│ {CM.Glyphs.UnChecked} Check this out 你 changed│
-│                            │
-└────────────────────────────┘
-";
+//        expected = @$"
+//┌┤Test Demo 你├──────────────┐
+//│                            │
+//│ {CM.Glyphs.UnChecked} Check this out 你 changed│
+//│                            │
+//└────────────────────────────┘
+//";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
-    }
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+//    }
 
-    [Fact]
-    [AutoInitShutdown]
-    public void AutoSize_Stays_True_AnchorEnd_Without_HotKeySpecifier ()
-    {
-        var checkBox = new CheckBox { Y = Pos.Center (), Text = "Check this out 你" };
+//    [Fact]
+//    [AutoInitShutdown]
+//    public void AutoSize_Stays_True_AnchorEnd_Without_HotKeySpecifier ()
+//    {
+//        var checkBox = new CheckBox { Y = Pos.Center (), Text = "Check this out 你" };
 
-        checkBox.X = Pos.AnchorEnd (0) - Pos.Function (() => checkBox.GetSizeNeededForTextWithoutHotKey ().Width);
+//        checkBox.X = Pos.AnchorEnd (0) - Pos.Function (() => checkBox.GetSizeNeededForTextWithoutHotKey ().Width);
 
-        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" };
-        win.Add (checkBox);
-        var top = new Toplevel ();
-        top.Add (win);
+//        var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" };
+//        win.Add (checkBox);
+//        var top = new Toplevel ();
+//        top.Add (win);
 
-        Assert.True (checkBox.AutoSize);
+////        Assert.True (checkBox.AutoSize);
 
-        Application.Begin (top);
-        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
+//        Application.Begin (top);
+//        ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
 
-        var expected = @$"
-┌┤Test Demo 你├──────────────┐
-│                            │
-│         {CM.Glyphs.UnChecked} Check this out 你│
-│                            │
-└────────────────────────────┘
-";
+//        var expected = @$"
+//┌┤Test Demo 你├──────────────┐
+//│                            │
+//│         {CM.Glyphs.UnChecked} Check this out 你│
+//│                            │
+//└────────────────────────────┘
+//";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
 
-        Assert.True (checkBox.AutoSize);
-        checkBox.Text = "Check this out 你 changed";
-        Assert.True (checkBox.AutoSize);
-        Application.Refresh ();
+// //       Assert.True (checkBox.AutoSize);
+//        checkBox.Text = "Check this out 你 changed";
+////        Assert.True (checkBox.AutoSize);
+//        Application.Refresh ();
 
-        expected = @$"
-┌┤Test Demo 你├──────────────┐
-│                            │
-│ {CM.Glyphs.UnChecked} Check this out 你 changed│
-│                            │
-└────────────────────────────┘
-";
+//        expected = @$"
+//┌┤Test Demo 你├──────────────┐
+//│                            │
+//│ {CM.Glyphs.UnChecked} Check this out 你 changed│
+//│                            │
+//└────────────────────────────┘
+//";
 
-        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
-    }
+//        TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
+//    }
 
 //    [Fact]
 //    [AutoInitShutdown]
@@ -241,7 +302,8 @@ public class CheckBoxTests
     public void Constructors_Defaults ()
     {
         var ckb = new CheckBox ();
-        Assert.True (ckb.AutoSize);
+        Assert.True (ckb.Width is Dim.DimAuto);
+        Assert.Equal (Dim.Sized (1), ckb.Height);
         Assert.False (ckb.Checked);
         Assert.False (ckb.AllowNullChecked);
         Assert.Equal (string.Empty, ckb.Text);
@@ -250,7 +312,8 @@ public class CheckBoxTests
         Assert.Equal (new Rectangle (0, 0, 2, 1), ckb.Frame);
 
         ckb = new CheckBox { Text = "Test", Checked = true };
-        Assert.True (ckb.AutoSize);
+        Assert.True (ckb.Width is Dim.DimAuto);
+        Assert.Equal (Dim.Sized (1), ckb.Height);
         Assert.True (ckb.Checked);
         Assert.False (ckb.AllowNullChecked);
         Assert.Equal ("Test", ckb.Text);
@@ -259,7 +322,8 @@ public class CheckBoxTests
         Assert.Equal (new Rectangle (0, 0, 6, 1), ckb.Frame);
 
         ckb = new CheckBox { Text = "Test", X = 1, Y = 2 };
-        Assert.True (ckb.AutoSize);
+        Assert.True (ckb.Width is Dim.DimAuto);
+        Assert.Equal (Dim.Sized (1), ckb.Height);
         Assert.False (ckb.Checked);
         Assert.False (ckb.AllowNullChecked);
         Assert.Equal ("Test", ckb.Text);
@@ -268,7 +332,8 @@ public class CheckBoxTests
         Assert.Equal (new Rectangle (1, 2, 6, 1), ckb.Frame);
 
         ckb = new CheckBox { Text = "Test", X = 3, Y = 4, Checked = true };
-        Assert.True (ckb.AutoSize);
+        Assert.True (ckb.Width is Dim.DimAuto);
+        Assert.Equal (Dim.Sized (1), ckb.Height);
         Assert.True (ckb.Checked);
         Assert.False (ckb.AllowNullChecked);
         Assert.Equal ("Test", ckb.Text);
@@ -405,7 +470,6 @@ public class CheckBoxTests
             Y = Pos.Center (),
             Text = "Check first out 你",
             TextAlignment = TextAlignment.Justified,
-            AutoSize = false,
             Width = 25
         };
 
@@ -415,7 +479,6 @@ public class CheckBoxTests
             Y = Pos.Bottom (checkBox1),
             Text = "Check second out 你",
             TextAlignment = TextAlignment.Justified,
-            AutoSize = false,
             Width = 25
         };
         var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" };

+ 70 - 67
UnitTests/Views/LabelTests.cs

@@ -55,7 +55,7 @@ public class LabelTests
     [Fact]
     public void MouseClick_SetsFocus_OnNextSubview ()
     {
-        var superView = new View () { CanFocus = true, Height = 1, Width = 15};
+        var superView = new View () { CanFocus = true, Height = 1, Width = 15 };
         var focusedView = new View () { CanFocus = true, Width = 1, Height = 1 };
         var label = new Label () { X = 2, Title = "_x" };
         var nextSubview = new View () { CanFocus = true, X = 4, Width = 4, Height = 1 };
@@ -215,66 +215,66 @@ public class LabelTests
         Assert.Equal (KeyCode.Null, label.HotKey);
     }
 
-//    [Fact]
-//    [AutoInitShutdown]
-//    public void Label_Draw_Fill_Remaining_AutoSize_True ()
-//    {
-//        var label = new Label { Text = "This label needs to be cleared before rewritten." };
-
-//        var tf1 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom };
-//        tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten.";
-//        Size tf1Size = tf1.Size;
-
-//        var tf2 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, FillRemaining = true };
-//        tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten.";
-//        Size tf2Size = tf2.Size;
-
-//        var top = new Toplevel ();
-//        top.Add (label);
-//        Application.Begin (top);
-
-//        Assert.True (label.AutoSize);
-
-//        tf1.Draw (
-//                  new Rectangle (new Point (0, 1), tf1Size),
-//                  label.GetNormalColor (),
-//                  label.ColorScheme.HotNormal
-//                 );
-
-//        tf2.Draw (new Rectangle (new Point (0, 2), tf2Size), label.GetNormalColor (), label.ColorScheme.HotNormal);
-
-//        TestHelpers.AssertDriverContentsWithFrameAre (
-//                                                      @"
-//This label 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
-//                                                     );
-
-//        label.Text = "This label is rewritten.";
-//        label.Draw ();
-
-//        tf1.Text = "This TextFormatter (tf1) is rewritten.";
-
-//        tf1.Draw (
-//                  new Rectangle (new Point (0, 1), tf1Size),
-//                  label.GetNormalColor (),
-//                  label.ColorScheme.HotNormal
-//                 );
-
-//        tf2.Text = "This TextFormatter (tf2) is rewritten.";
-//        tf2.Draw (new Rectangle (new Point (0, 2), tf2Size), label.GetNormalColor (), label.ColorScheme.HotNormal);
-
-//        TestHelpers.AssertDriverContentsWithFrameAre (
-//                                                      @"
-//This label is rewritten.                                               
-//This TextFormatter (tf1) is rewritten.will not be cleared on rewritten.
-//This TextFormatter (tf2) is rewritten.                                 
-//",
-//                                                      _output
-//                                                     );
-//    }
+    //    [Fact]
+    //    [AutoInitShutdown]
+    //    public void Label_Draw_Fill_Remaining_AutoSize_True ()
+    //    {
+    //        var label = new Label { Text = "This label needs to be cleared before rewritten." };
+
+    //        var tf1 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom };
+    //        tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten.";
+    //        Size tf1Size = tf1.Size;
+
+    //        var tf2 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, FillRemaining = true };
+    //        tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten.";
+    //        Size tf2Size = tf2.Size;
+
+    //        var top = new Toplevel ();
+    //        top.Add (label);
+    //        Application.Begin (top);
+
+    //        Assert.True (label.AutoSize);
+
+    //        tf1.Draw (
+    //                  new Rectangle (new Point (0, 1), tf1Size),
+    //                  label.GetNormalColor (),
+    //                  label.ColorScheme.HotNormal
+    //                 );
+
+    //        tf2.Draw (new Rectangle (new Point (0, 2), tf2Size), label.GetNormalColor (), label.ColorScheme.HotNormal);
+
+    //        TestHelpers.AssertDriverContentsWithFrameAre (
+    //                                                      @"
+    //This label 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
+    //                                                     );
+
+    //        label.Text = "This label is rewritten.";
+    //        label.Draw ();
+
+    //        tf1.Text = "This TextFormatter (tf1) is rewritten.";
+
+    //        tf1.Draw (
+    //                  new Rectangle (new Point (0, 1), tf1Size),
+    //                  label.GetNormalColor (),
+    //                  label.ColorScheme.HotNormal
+    //                 );
+
+    //        tf2.Text = "This TextFormatter (tf2) is rewritten.";
+    //        tf2.Draw (new Rectangle (new Point (0, 2), tf2Size), label.GetNormalColor (), label.ColorScheme.HotNormal);
+
+    //        TestHelpers.AssertDriverContentsWithFrameAre (
+    //                                                      @"
+    //This label is rewritten.                                               
+    //This TextFormatter (tf1) is rewritten.will not be cleared on rewritten.
+    //This TextFormatter (tf2) is rewritten.                                 
+    //",
+    //                                                      _output
+    //                                                     );
+    //    }
 
     [Fact]
     [AutoInitShutdown]
@@ -476,16 +476,18 @@ e
 
 
     [Fact]
-    [AutoInitShutdown]
+    [SetupFakeDriver]
     public void Full_Border ()
     {
-        var label = new Label { Text = "Test", /*Width = 6, Height = 3, */BorderStyle = LineStyle.Single };
-        var top = new Toplevel ();
-        top.Add (label);
-        Application.Begin (top);
+        var label = new Label { BorderStyle = LineStyle.Single , Text = "Test",} ;
+        label.BeginInit();
+        label.EndInit();
+        label.SetRelativeLayout (Application.Driver.Screen.Size);
 
-        Assert.Equal (new (0, 0, 6, 3), label.Frame);
         Assert.Equal (new (0, 0, 4, 1), label.Viewport);
+        Assert.Equal (new (0, 0, 6, 3), label.Frame);
+
+        label.Draw ();
 
         TestHelpers.AssertDriverContentsWithFrameAre (
                                                       @"
@@ -494,6 +496,7 @@ e
 └────┘",
                                                       _output
                                                      );
+        label.Dispose ();
     }
 
     [Fact]