From 38bed3fd98d517ed66de263108ffa245f417a95d Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 18 Jun 2022 02:13:55 +0100 Subject: [PATCH] Added exceptions for AutoSize. --- Terminal.Gui/Core/View.cs | 73 +++++++++++------------ UnitTests/PanelViewTests.cs | 6 +- UnitTests/ViewTests.cs | 113 +++++++++++++++++++++++++++++++----- 3 files changed, 138 insertions(+), 54 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 17bf8d197..1dfa23a06 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -571,9 +571,8 @@ namespace Terminal.Gui { var isValidNewAutSize = autoSize ? IsValidAutoSizeWidth (width) : false; - if (autoSize && !isValidNewAutSize) { - TextFormatter.AutoSize = false; - autoSize = false; + if (IsInitialized && autoSize && !isValidNewAutSize) { + throw new InvalidOperationException ("Must set AutoSize to false before set the Width."); } SetMinWidthHeight (); SetNeedsLayout (); @@ -601,9 +600,8 @@ namespace Terminal.Gui { var isValidNewAutSize = autoSize ? IsValidAutoSizeHeight (height) : false; - if (autoSize && !isValidNewAutSize) { - TextFormatter.AutoSize = false; - autoSize = false; + if (IsInitialized && autoSize && !isValidNewAutSize) { + throw new InvalidOperationException ("Must set AutoSize to false before set the Height."); } SetMinWidthHeight (); SetNeedsLayout (); @@ -633,7 +631,7 @@ namespace Terminal.Gui { if (!AutoSize && !ustring.IsNullOrEmpty (TextFormatter.Text)) { switch (TextFormatter.IsVerticalDirection (TextDirection)) { case true: - var colWidth = TextFormatter.GetSumMaxCharWidth (TextFormatter.Text, 0, 1); + var colWidth = TextFormatter.GetSumMaxCharWidth (new List { TextFormatter.Text }, 0, 1); if (Width == null || (Width is Dim.DimAbsolute && Width.Anchor (0) < colWidth)) { width = colWidth; Bounds = new Rect (Bounds.X, Bounds.Y, colWidth, Bounds.Height); @@ -2389,9 +2387,6 @@ namespace Terminal.Gui { if ((IsInitialized && AutoSize) || (directionChanged && AutoSize && isValidOldAutSize)) { ResizeView (true); - } else if (directionChanged && AutoSize && !isValidOldAutSize) { - TextFormatter.AutoSize = false; - autoSize = false; } else if (IsInitialized) { var b = new Rect (Bounds.X, Bounds.Y, Bounds.Height, Bounds.Width); SetWidthHeight (b); @@ -2411,10 +2406,10 @@ namespace Terminal.Gui { /// public virtual bool IsInitialized { get => isInitialized; - set { + private set { isInitialized = value; SetMinWidthHeight (); - if (autoSize && !IsValidAutoSize (out _)) { + if (autoSize && !IsValidAutoSize (out Size autSize)) { TextFormatter.AutoSize = false; autoSize = false; } @@ -2512,10 +2507,8 @@ namespace Terminal.Gui { bool SetWidthHeight (Rect nBounds) { bool aSize = false; - var canSizeW = SetWidth (nBounds.Width - (TextFormatter.IsHorizontalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0), out int rW); - var canSizeH = SetHeight (nBounds.Height - (TextFormatter.IsVerticalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0), out int rH); + var canSizeW = SetWidth (nBounds.Width - GetHotKeySpecifierLength (), out int rW); + var canSizeH = SetHeight (nBounds.Height - GetHotKeySpecifierLength (false), out int rH); if (canSizeW) { aSize = true; width = rW; @@ -2535,15 +2528,11 @@ namespace Terminal.Gui { bool IsValidAutoSize (out Size autoSize) { var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection); - autoSize = new Size (rect.Size.Width - (TextFormatter.IsHorizontalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0), - rect.Size.Height - (TextFormatter.IsVerticalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0)); + autoSize = new Size (rect.Size.Width - GetHotKeySpecifierLength (), + rect.Size.Height - GetHotKeySpecifierLength (false)); return !(!(Width is Dim.DimAbsolute) || !(Height is Dim.DimAbsolute) - || frame.Size.Width != rect.Size.Width - (TextFormatter.IsHorizontalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0) - || frame.Size.Height != rect.Size.Height - (TextFormatter.IsVerticalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0)); + || frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength () + || frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false)); } bool IsValidAutoSizeWidth (Dim width) @@ -2551,8 +2540,7 @@ namespace Terminal.Gui { var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection); var dimValue = width.Anchor (0); return !(!(width is Dim.DimAbsolute) || dimValue != rect.Size.Width - - (TextFormatter.IsHorizontalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0)); + - GetHotKeySpecifierLength ()); } bool IsValidAutoSizeHeight (Dim height) @@ -2560,8 +2548,25 @@ namespace Terminal.Gui { var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection); var dimValue = height.Anchor (0); return !(!(height is Dim.DimAbsolute) || dimValue != rect.Size.Height - - (TextFormatter.IsVerticalDirection (TextDirection) - && TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0)); + - GetHotKeySpecifierLength (false)); + } + + /// + /// Get the width or height of the length. + /// + /// trueif is the width (default)falseif is the height. + /// The length of the . + public int GetHotKeySpecifierLength (bool isWidth = true) + { + if (isWidth) { + return TextFormatter.IsHorizontalDirection (TextDirection) && + TextFormatter.Text?.Contains (HotKeySpecifier) == true + ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0; + } else { + return TextFormatter.IsVerticalDirection (TextDirection) && + TextFormatter.Text?.Contains (HotKeySpecifier) == true + ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0; + } } /// @@ -2570,10 +2575,8 @@ namespace Terminal.Gui { /// The bounds size minus the length. public Size GetTextFormatterBoundsSize () { - return new Size (TextFormatter.Size.Width - (TextFormatter.IsHorizontalDirection (TextDirection) - && TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0), - TextFormatter.Size.Height - (TextFormatter.IsVerticalDirection (TextDirection) - && TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0)); + return new Size (TextFormatter.Size.Width - GetHotKeySpecifierLength (), + TextFormatter.Size.Height - GetHotKeySpecifierLength (false)); } /// @@ -2585,10 +2588,8 @@ namespace Terminal.Gui { if (TextFormatter.Text == null) return Bounds.Size; - return new Size (frame.Size.Width + (TextFormatter.IsHorizontalDirection (TextDirection) - && TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0), - frame.Size.Height + (TextFormatter.IsVerticalDirection (TextDirection) - && TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0)); + return new Size (frame.Size.Width + GetHotKeySpecifierLength (), + frame.Size.Height + GetHotKeySpecifierLength (false)); } /// diff --git a/UnitTests/PanelViewTests.cs b/UnitTests/PanelViewTests.cs index 1d7b8bdfa..5d20b96d6 100644 --- a/UnitTests/PanelViewTests.cs +++ b/UnitTests/PanelViewTests.cs @@ -346,11 +346,11 @@ namespace Terminal.Gui.Views { var top = Application.Top; var win = new Window (); var label = new Label () { - Width = 24, - Height = 13, ColorScheme = Colors.TopLevel, Text = "This is a test\nwith a \nPanelView", - TextAlignment = TextAlignment.Centered + TextAlignment = TextAlignment.Centered, + Width = 24, + Height = 13 }; var pv = new PanelView (label) { Width = 24, diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index cb41cfb91..e1defcb2d 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -1176,7 +1176,7 @@ namespace Terminal.Gui.Core { Application.Shutdown (); } - [Fact] + [Fact, AutoInitShutdown] public void SetWidth_CanSetWidth () { var top = new View () { @@ -1200,8 +1200,12 @@ namespace Terminal.Gui.Core { v.Width = null; Assert.True (v.SetWidth (70, out rWidth)); Assert.Equal (70, rWidth); + Assert.False (v.IsInitialized); - v.IsInitialized = true; + Application.Top.Add (top); + Application.Begin (Application.Top); + + Assert.True (v.IsInitialized); v.Width = Dim.Fill (1); Assert.Throws (() => v.Width = 75); v.LayoutStyle = LayoutStyle.Absolute; @@ -1210,7 +1214,7 @@ namespace Terminal.Gui.Core { Assert.Equal (60, rWidth); } - [Fact] + [Fact, AutoInitShutdown] public void SetHeight_CanSetHeight () { var top = new View () { @@ -1234,8 +1238,13 @@ namespace Terminal.Gui.Core { v.Height = null; Assert.True (v.SetHeight (10, out rHeight)); Assert.Equal (10, rHeight); + Assert.False (v.IsInitialized); + + Application.Top.Add (top); + Application.Begin (Application.Top); + + Assert.True (v.IsInitialized); - v.IsInitialized = true; v.Height = Dim.Fill (1); Assert.Throws (() => v.Height = 15); v.LayoutStyle = LayoutStyle.Absolute; @@ -1360,37 +1369,50 @@ namespace Terminal.Gui.Core { Assert.Equal ("{X=0,Y=0,Width=8,Height=1}", label.Bounds.ToString ()); } - [Fact] - public void AutoSize_False_ResizeView_With_Dim_Fill () + [Fact, AutoInitShutdown] + public void AutoSize_False_ResizeView_With_Dim_Fill_After_IsInitialized () { var win = new Window (new Rect (0, 0, 30, 80), ""); var label = new Label () { Width = Dim.Fill (), Height = Dim.Fill () }; win.Add (label); + Application.Top.Add (win); + + // Text is empty so height=0 + Assert.True (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ()); label.Text = "New text\nNew line"; - win.LayoutSubviews (); + Application.Top.LayoutSubviews (); + Assert.True (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ()); + + Application.Begin (Application.Top); Assert.False (label.AutoSize); Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ()); } - [Fact] - public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute () + [Fact, AutoInitShutdown] + public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute_After_IsInitialized () { var win = new Window (new Rect (0, 0, 30, 80), ""); var label = new Label () { Width = Dim.Fill () }; win.Add (label); + Application.Top.Add (win); // Text is empty so height=0 - Assert.False (label.AutoSize); + Assert.True (label.AutoSize); Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ()); - // Here the SetMinWidthHeight ensuring the minimum height label.Text = "New text\nNew line"; - win.LayoutSubviews (); + Application.Top.LayoutSubviews (); + Assert.True (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ()); + + Application.Begin (Application.Top); Assert.False (label.AutoSize); - Assert.Equal ("{X=0,Y=0,Width=28,Height=1}", label.Bounds.ToString ()); + Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ()); } [Fact, AutoInitShutdown] @@ -2827,8 +2849,7 @@ Y var btn = new Button () { X = Pos.Center (), Y = Pos.Center (), - Text = "Say He_llo 你", - AutoSize = true + Text = "Say He_llo 你" }; var win = new Window () { @@ -2912,5 +2933,67 @@ Y Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetBoundsTextFormatterSize ()); Assert.Equal (verticalView.Frame.Size, verticalView.GetTextFormatterBoundsSize ()); } + + [Fact, AutoInitShutdown] + public void AutoSize_Exceptions () + { + var exception = Record.Exception (() => new View () { Text = "Say Hello 你", AutoSize = true, Width = 10 }); + Assert.Null (exception); + + var view1 = new View () { Text = "Say Hello view1 你", AutoSize = true, Width = 10 }; + var view2 = new View () { Text = "Say Hello view2 你", Height = 10, AutoSize = true }; + var view3 = new View () { Text = "Say Hello view3 你", Width = 10 }; + var view4 = new View () { + Text = "Say Hello view4 你", + Height = 10, + AutoSize = true, + TextDirection = TextDirection.TopBottom_LeftRight + }; + var view5 = new View () { + Text = "Say Hello view5 你", + Height = 10, + TextDirection = TextDirection.TopBottom_LeftRight + }; + Application.Top.Add (view1, view2, view3, view4, view5); + + Assert.False (view1.IsInitialized); + Assert.False (view2.IsInitialized); + Assert.False (view3.IsInitialized); + Assert.False (view4.IsInitialized); + Assert.False (view5.IsInitialized); + + Application.Begin (Application.Top); + + Assert.True (view1.IsInitialized); + Assert.True (view2.IsInitialized); + Assert.True (view3.IsInitialized); + Assert.True (view4.IsInitialized); + Assert.True (view5.IsInitialized); + + Assert.False (view1.AutoSize); + Assert.Equal (new Rect (0, 0, 10, 1), view1.Frame); + Assert.True (view2.AutoSize); + Assert.Equal (new Rect (0, 0, 18, 1), view2.Frame); + Assert.False (view3.AutoSize); + Assert.Equal (new Rect (0, 0, 10, 1), view3.Frame); + Assert.True (view4.AutoSize); + Assert.Equal (new Rect (0, 0, 2, 17), view4.Frame); + Assert.False (view5.AutoSize); + Assert.Equal (new Rect (0, 0, 2, 10), view5.Frame); + + exception = Record.Exception (() => view1.Width = 20); + Assert.Null (exception); + Assert.Equal (new Rect (0, 0, 20, 1), view1.Frame); + Assert.Throws (() => view2.Height = 10); + exception = Record.Exception (() => view3.Width = 20); + Assert.Null (exception); + Assert.Equal (new Rect (0, 0, 20, 1), view3.Frame); + exception = Record.Exception (() => view4.TextDirection = TextDirection.LeftRight_TopBottom); + Assert.Null (exception); + Assert.Equal (new Rect (0, 0, 18, 1), view4.Frame); + exception = Record.Exception (() => view5.TextDirection = TextDirection.LeftRight_TopBottom); + Assert.Null (exception); + Assert.Equal (new Rect (0, 0, 10, 2), view5.Frame); + } } }