瀏覽代碼

Addressed review feedback from @dodexahedron.

Tig 1 年之前
父節點
當前提交
3ed30767a0

+ 123 - 132
Terminal.Gui/Text/TextFormatter.cs

@@ -54,7 +54,10 @@ public class TextFormatter
 
             if (_autoSize)
             {
-                Size = GetAutoSize ();
+                Size size = CalcRect (0, 0, Text, Direction, TabWidth).Size;
+
+                Width = size.Width - GetHotKeySpecifierLength ();
+                Height = size.Height - GetHotKeySpecifierLength (false);
             }
             else
             {
@@ -619,75 +622,80 @@ public class TextFormatter
     /// </remarks>
     public List<string> GetLines ()
     {
+        int width = _width.GetValueOrDefault ();
+        int height = _height.GetValueOrDefault ();
+
         // With this check, we protect against subclasses with overrides of Text
-        if (string.IsNullOrEmpty (Text) || Width is null || Width == 0 || Height is null || Height == 0)
+        if (string.IsNullOrEmpty (Text) || width == 0 || height == 0)
         {
-            _lines = new() { string.Empty };
+            _lines = [string.Empty];
             NeedsFormat = false;
 
             return _lines;
         }
 
-        if (NeedsFormat)
+        if (!NeedsFormat)
         {
-            string text = _text!;
+            return _lines;
+        }
 
-            if (FindHotKey (_text!, HotKeySpecifier, out _hotKeyPos, out Key newHotKey))
-            {
-                HotKey = newHotKey;
-                text = RemoveHotKeySpecifier (Text, _hotKeyPos, HotKeySpecifier);
-                text = ReplaceHotKeyWithTag (text, _hotKeyPos);
-            }
+        string text = _text!;
 
-            if (IsVerticalDirection (Direction))
+        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 == Alignment.Fill,
+                             width > colsWidth && WordWrap,
+                             PreserveTrailingSpaces,
+                             TabWidth,
+                             Direction,
+                             MultiLine,
+                             this
+                            );
+
+            if (!AutoSize)
             {
-                int colsWidth = GetSumMaxCharWidth (text, 0, 1, TabWidth);
-
-                _lines = Format (
-                                 text,
-                                 Height.Value,
-                                 VerticalAlignment == Alignment.Fill,
-                                 Width.Value > colsWidth && WordWrap,
-                                 PreserveTrailingSpaces,
-                                 TabWidth,
-                                 Direction,
-                                 MultiLine,
-                                 this
-                                );
-
-                if (!AutoSize)
-                {
-                    colsWidth = GetMaxColsForWidth (_lines, Width.Value, TabWidth);
+                colsWidth = GetMaxColsForWidth (_lines, width, TabWidth);
 
-                    if (_lines.Count > colsWidth)
-                    {
-                        _lines.RemoveRange (colsWidth, _lines.Count - colsWidth);
-                    }
+                if (_lines.Count > colsWidth)
+                {
+                    _lines.RemoveRange (colsWidth, _lines.Count - colsWidth);
                 }
             }
-            else
+        }
+        else
+        {
+            _lines = Format (
+                             text,
+                             width,
+                             Alignment == Alignment.Fill,
+                             height > 1 && WordWrap,
+                             PreserveTrailingSpaces,
+                             TabWidth,
+                             Direction,
+                             MultiLine,
+                             this
+                            );
+
+            if (!AutoSize && _lines.Count > height)
             {
-                _lines = Format (
-                                 text,
-                                 Width.Value,
-                                 Alignment == Alignment.Fill,
-                                 Height.Value > 1 && WordWrap,
-                                 PreserveTrailingSpaces,
-                                 TabWidth,
-                                 Direction,
-                                 MultiLine,
-                                 this
-                                );
-
-                if (!AutoSize && _lines.Count > Height.Value)
-                {
-                    _lines.RemoveRange (Height.Value, _lines.Count - Height.Value);
-                }
+                _lines.RemoveRange (height, _lines.Count - height);
             }
-
-            NeedsFormat = false;
         }
 
+        NeedsFormat = false;
+
         return _lines;
     }
 
@@ -713,10 +721,7 @@ public class TextFormatter
                 return;
             }
 
-            if (value < 0)
-            {
-                throw new ArgumentOutOfRangeException (nameof (Height), value, @"Must be greater than or equal to 0.");
-            }
+            ArgumentOutOfRangeException.ThrowIfNegative (value.GetValueOrDefault (), nameof (Height));
 
             _height = value;
 
@@ -854,7 +859,6 @@ public class TextFormatter
             if (AutoSize)
             {
                 Size = GetAutoSize ();
-                ;
             }
         }
     }
@@ -888,10 +892,7 @@ public class TextFormatter
                 return;
             }
 
-            if (value < 0)
-            {
-                throw new ArgumentOutOfRangeException (nameof (Width), value, @"Must be greater than or equal to 0.");
-            }
+            ArgumentOutOfRangeException.ThrowIfNegative (value.GetValueOrDefault (), nameof (Width));
 
             _width = value;
 
@@ -939,48 +940,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?
@@ -1191,10 +1192,7 @@ public class TextFormatter
         TextFormatter? textFormatter = null
     )
     {
-        if (width < 0)
-        {
-            throw new ArgumentOutOfRangeException ($"{nameof (width)} cannot be negative.");
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (width, nameof (width));
 
         List<string> lines = new ();
 
@@ -1372,21 +1370,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++;
 
@@ -1395,11 +1393,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 ())
@@ -1461,10 +1459,7 @@ public class TextFormatter
         TextFormatter? textFormatter = null
     )
     {
-        if (width < 0)
-        {
-            throw new ArgumentOutOfRangeException ($"{nameof (width)} cannot be negative.");
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (width, nameof (width));
 
         if (string.IsNullOrEmpty (text))
         {
@@ -1584,10 +1579,8 @@ public class TextFormatter
         int tabWidth = 0
     )
     {
-        if (width < 0)
-        {
-            throw new ArgumentOutOfRangeException ($"{nameof (width)} cannot be negative.");
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (width, nameof (width));
+
 
         if (string.IsNullOrEmpty (text))
         {
@@ -1730,10 +1723,8 @@ public class TextFormatter
         TextFormatter? textFormatter = null
     )
     {
-        if (width < 0)
-        {
-            throw new ArgumentOutOfRangeException ($"{nameof (width)} cannot be negative.");
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (width, nameof (width));
+
 
         List<string> lineResult = new ();
 
@@ -1844,13 +1835,13 @@ public class TextFormatter
     private static string PerformCorrectFormatDirection (TextDirection textDirection, string line)
     {
         return textDirection switch
-               {
-                   TextDirection.RightLeft_BottomTop
-                       or TextDirection.RightLeft_TopBottom
-                       or TextDirection.BottomTop_LeftRight
-                       or TextDirection.BottomTop_RightLeft => StringExtensions.ToString (line.EnumerateRunes ().Reverse ()),
-                   _ => line
-               };
+        {
+            TextDirection.RightLeft_BottomTop
+                or TextDirection.RightLeft_TopBottom
+                or TextDirection.BottomTop_LeftRight
+                or TextDirection.BottomTop_RightLeft => StringExtensions.ToString (line.EnumerateRunes ().Reverse ()),
+            _ => line
+        };
     }
 
     private static List<Rune> PerformCorrectFormatDirection (TextDirection textDirection, List<Rune> runes)
@@ -1861,13 +1852,13 @@ public class TextFormatter
     private static List<string> PerformCorrectFormatDirection (TextDirection textDirection, List<string> lines)
     {
         return textDirection switch
-               {
-                   TextDirection.TopBottom_RightLeft
-                       or TextDirection.LeftRight_BottomTop
-                       or TextDirection.RightLeft_BottomTop
-                       or TextDirection.BottomTop_RightLeft => lines.ToArray ().Reverse ().ToList (),
-                   _ => lines
-               };
+        {
+            TextDirection.TopBottom_RightLeft
+                or TextDirection.LeftRight_BottomTop
+                or TextDirection.RightLeft_BottomTop
+                or TextDirection.BottomTop_RightLeft => lines.ToArray ().Reverse ().ToList (),
+            _ => lines
+        };
     }
 
     /// <summary>

+ 1 - 4
Terminal.Gui/View/Layout/Dim.cs

@@ -160,10 +160,7 @@ public abstract class Dim
     /// </example>
     public static Dim? Percent (int percent, DimPercentMode mode = DimPercentMode.ContentSize)
     {
-        if (percent is < 0 /*or > 100*/)
-        {
-            throw new ArgumentException ("Percent value must be positive.");
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (percent, nameof (percent));
 
         return new DimPercent (percent, mode);
     }

+ 2 - 8
Terminal.Gui/View/Layout/Pos.cs

@@ -197,10 +197,7 @@ public abstract class Pos
     /// </example>
     public static Pos AnchorEnd (int offset)
     {
-        if (offset < 0)
-        {
-            throw new ArgumentException (@"Must be positive", nameof (offset));
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (offset, nameof (offset));
 
         return new PosAnchorEnd (offset);
     }
@@ -246,10 +243,7 @@ public abstract class Pos
     /// </example>
     public static Pos Percent (int percent)
     {
-        if (percent is < 0)
-        {
-            throw new ArgumentException ("Percent value must be positive.");
-        }
+        ArgumentOutOfRangeException.ThrowIfNegative (percent, nameof (percent));
 
         return new PosPercent (percent);
     }

+ 2 - 2
UnitTests/View/Layout/Dim.PercentTests.cs

@@ -67,9 +67,9 @@ public class DimPercentTests
     public void DimPercent_Invalid_Throws ()
     {
         Dim dim = Dim.Percent (0);
-        Assert.Throws<ArgumentException> (() => dim = Dim.Percent (-1));
+        Assert.Throws<ArgumentOutOfRangeException> (() => dim = Dim.Percent (-1));
         //Assert.Throws<ArgumentException> (() => dim = Dim.Percent (101));
-        Assert.Throws<ArgumentException> (() => dim = Dim.Percent (-1000001));
+        Assert.Throws<ArgumentOutOfRangeException> (() => dim = Dim.Percent (-1000001));
         //Assert.Throws<ArgumentException> (() => dim = Dim.Percent (1000001));
     }
 

+ 1 - 1
UnitTests/View/Layout/Pos.AnchorEndTests.cs

@@ -67,7 +67,7 @@ public class PosAnchorEndTests (ITestOutputHelper output)
     {
         Pos pos;
         int n = -1;
-        Assert.Throws<ArgumentException> (() => pos = Pos.AnchorEnd (n));
+        Assert.Throws<ArgumentOutOfRangeException> (() => pos = Pos.AnchorEnd (n));
     }
 
     [Theory]

+ 1 - 1
UnitTests/View/Layout/Pos.PercentTests.cs

@@ -78,7 +78,7 @@ public class PosPercentTests (ITestOutputHelper output)
     public void PosPercent_ThrowsOnIvalid ()
     {
         Pos pos = Percent (0);
-        Assert.Throws<ArgumentException> (() => pos = Percent (-1));
+        Assert.Throws<ArgumentOutOfRangeException> (() => pos = Percent (-1));
 
         //Assert.Throws<ArgumentException> (() => pos = Pos.Percent (101));
         //Assert.Throws<ArgumentException> (() => pos = Pos.Percent (1000001));