diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 0d466bbde..4104b2a59 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -2098,17 +2098,20 @@ namespace Terminal.Gui { bool SetWidthHeight (Rect nBounds) { - bool aSize; + bool aSize = false; var canSizeW = SetWidth (nBounds.Width, out int rW); var canSizeH = SetHeight (nBounds.Height, out int rH); - if (canSizeW && canSizeH) { + if (canSizeW) { aSize = true; - Bounds = nBounds; width = rW; + } + if (canSizeH) { + aSize = true; height = rH; + } + if (aSize) { + Bounds = new Rect (Bounds.X, Bounds.Y, canSizeW ? rW : Bounds.Width, canSizeH ? rH : Bounds.Height); textFormatter.Size = Bounds.Size; - } else { - aSize = false; } return aSize; @@ -2266,15 +2269,13 @@ namespace Terminal.Gui { return true; } - bool CanSetWidth (int desiredWidth, out int resultWidth, out int currentWidth) + bool CanSetWidth (int desiredWidth, out int resultWidth) { int w = desiredWidth; - currentWidth = Width != null ? Width.Anchor (0) : 0; bool canSetWidth; if (Width is Dim.DimCombine || Width is Dim.DimView || Width is Dim.DimFill) { // It's a Dim.DimCombine and so can't be assigned. Let it have it's width anchored. w = Width.Anchor (w); - currentWidth = Width.Anchor (w); canSetWidth = false; } else if (Width is Dim.DimFactor factor) { // Tries to get the SuperView width otherwise the view width. @@ -2283,7 +2284,6 @@ namespace Terminal.Gui { sw -= Frame.X; } w = Width.Anchor (sw); - currentWidth = Width.Anchor (sw); canSetWidth = false; } else { canSetWidth = true; @@ -2293,15 +2293,13 @@ namespace Terminal.Gui { return canSetWidth; } - bool CanSetHeight (int desiredHeight, out int resultHeight, out int currentHeight) + bool CanSetHeight (int desiredHeight, out int resultHeight) { int h = desiredHeight; - currentHeight = Height != null ? Height.Anchor (0) : 0; bool canSetHeight; if (Height is Dim.DimCombine || Height is Dim.DimView || Height is Dim.DimFill) { // It's a Dim.DimCombine and so can't be assigned. Let it have it's height anchored. h = Height.Anchor (h); - currentHeight = Height.Anchor (h); canSetHeight = false; } else if (Height is Dim.DimFactor factor) { // Tries to get the SuperView height otherwise the view height. @@ -2310,7 +2308,6 @@ namespace Terminal.Gui { sh -= Frame.Y; } h = Height.Anchor (sh); - currentHeight = Height.Anchor (sh); canSetHeight = false; } else { canSetHeight = true; @@ -2328,7 +2325,7 @@ namespace Terminal.Gui { /// true if the width can be directly assigned, false otherwise. public bool SetWidth (int desiredWidth, out int resultWidth) { - return CanSetWidth (desiredWidth, out resultWidth, out _); + return CanSetWidth (desiredWidth, out resultWidth); } /// @@ -2339,7 +2336,7 @@ namespace Terminal.Gui { /// true if the height can be directly assigned, false otherwise. public bool SetHeight (int desiredHeight, out int resultHeight) { - return CanSetHeight (desiredHeight, out resultHeight, out _); + return CanSetHeight (desiredHeight, out resultHeight); } /// @@ -2349,7 +2346,10 @@ namespace Terminal.Gui { /// true if the width can be directly assigned, false otherwise. public bool GetCurrentWidth (out int currentWidth) { - return CanSetWidth (0, out _, out currentWidth); + SetRelativeLayout (SuperView == null ? Frame : SuperView.Frame); + currentWidth = Frame.Width; + + return CanSetWidth (0, out _); } /// @@ -2359,7 +2359,10 @@ namespace Terminal.Gui { /// true if the height can be directly assigned, false otherwise. public bool GetCurrentHeight (out int currentHeight) { - return CanSetHeight (0, out _, out currentHeight); + SetRelativeLayout (SuperView == null ? Frame : SuperView.Frame); + currentHeight = Frame.Height; + + return CanSetHeight (0, out _); } } } diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index 69f7e825e..2c438bddd 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -23,6 +23,7 @@ namespace Terminal.Gui { /// public Label () { + Initialize (); } /// @@ -33,6 +34,7 @@ namespace Terminal.Gui { /// public Label (ustring text) : base (text) { + Initialize (); } /// @@ -43,12 +45,19 @@ namespace Terminal.Gui { /// public Label (int x, int y, ustring text) : base (x, y, text) { + Initialize (); } /// public Label (ustring text, TextDirection direction) : base (text, direction) { + Initialize (); + } + + void Initialize () + { + AutoSize = true; } /// diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 7c697bed4..d6abee6d2 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -1170,5 +1170,167 @@ namespace Terminal.Gui.Views { // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); } + + [Fact] + public void SetWidth_CanSetWidth () + { + var top = new View () { + X = 0, + Y = 0, + Width = 80, + }; + + var v = new View () { + Width = Dim.Fill () + }; + top.Add (v); + + Assert.False (v.SetWidth (70, out int rWidth)); + Assert.Equal (70, rWidth); + + v.Width = Dim.Fill (1); + Assert.False (v.SetWidth (70, out rWidth)); + Assert.Equal (69, rWidth); + + v.Width = null; + Assert.True (v.SetWidth (70, out rWidth)); + Assert.Equal (70, rWidth); + + v.IsInitialized = true; + v.Width = Dim.Fill (1); + Assert.Throws (() => v.Width = 75); + v.LayoutStyle = LayoutStyle.Absolute; + v.Width = 75; + Assert.True (v.SetWidth (60, out rWidth)); + Assert.Equal (60, rWidth); + } + + [Fact] + public void SetHeight_CanSetHeight () + { + var top = new View () { + X = 0, + Y = 0, + Height = 20 + }; + + var v = new View () { + Height = Dim.Fill () + }; + top.Add (v); + + Assert.False (v.SetHeight (10, out int rHeight)); + Assert.Equal (10, rHeight); + + v.Height = Dim.Fill (1); + Assert.False (v.SetHeight (10, out rHeight)); + Assert.Equal (9, rHeight); + + v.Height = null; + Assert.True (v.SetHeight (10, out rHeight)); + Assert.Equal (10, rHeight); + + v.IsInitialized = true; + v.Height = Dim.Fill (1); + Assert.Throws (() => v.Height = 15); + v.LayoutStyle = LayoutStyle.Absolute; + v.Height = 15; + Assert.True (v.SetHeight (5, out rHeight)); + Assert.Equal (5, rHeight); + } + + [Fact] + public void GetCurrentWidth_CanSetWidth () + { + var top = new View () { + X = 0, + Y = 0, + Width = 80, + }; + + var v = new View () { + Width = Dim.Fill () + }; + top.Add (v); + + Assert.False (v.GetCurrentWidth (out int cWidth)); + Assert.Equal (80, cWidth); + + v.Width = Dim.Fill (1); + Assert.False (v.GetCurrentWidth (out cWidth)); + Assert.Equal (79, cWidth); + } + + [Fact] + public void GetCurrentHeight_CanSetHeight () + { + var top = new View () { + X = 0, + Y = 0, + Height = 20 + }; + + var v = new View () { + Height = Dim.Fill () + }; + top.Add (v); + + Assert.False (v.GetCurrentHeight (out int cHeight)); + Assert.Equal (20, cHeight); + + v.Height = Dim.Fill (1); + Assert.False (v.GetCurrentHeight (out cHeight)); + Assert.Equal (19, cHeight); + } + + [Fact] + public void AutoSize_False_ResizeView_Is_Always_False () + { + var label = new Label () { AutoSize = false }; + + label.Text = "New text"; + + Assert.False (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ()); + } + + [Fact] + public void AutoSize_True_ResizeView_With_Dim_Absolute () + { + var label = new Label (); + + label.Text = "New text"; + + Assert.True (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=8,Height=1}", label.Bounds.ToString ()); + } + + [Fact] + public void AutoSize_True_ResizeView_With_Dim_Fill () + { + var win = new Window (new Rect (0, 0, 30, 80), ""); + var label = new Label () { Width = Dim.Fill (), Height = Dim.Fill () }; + win.Add (label); + + label.Text = "New text\nNew line"; + win.LayoutSubviews (); + + Assert.True (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ()); + } + + [Fact] + public void AutoSize_True_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute () + { + var win = new Window (new Rect (0, 0, 30, 80), ""); + var label = new Label () { Width = Dim.Fill () }; + win.Add (label); + + label.Text = "New text\nNew line"; + win.LayoutSubviews (); + + Assert.True (label.AutoSize); + Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ()); + } } }