diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs index c515cd705..51067b10c 100644 --- a/Terminal.Gui/View/Layout/ViewLayout.cs +++ b/Terminal.Gui/View/Layout/ViewLayout.cs @@ -938,6 +938,11 @@ public partial class View _height = Frame.Height; } + if (!string.IsNullOrEmpty (Title)) + { + SetTitleTextFormatterSize (); + } + SetNeedsLayout (); SetNeedsDisplay (); } diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs index 8eab04bba..05ab9f2d9 100644 --- a/Terminal.Gui/View/View.cs +++ b/Terminal.Gui/View/View.cs @@ -456,12 +456,7 @@ public partial class View : Responder, ISupportInitializeNotification _title = value; TitleTextFormatter.Text = _title; - TitleTextFormatter.Size = new ( - TextFormatter.GetWidestLineLength (TitleTextFormatter.Text) - - (TitleTextFormatter.Text?.Contains ((char)HotKeySpecifier.Value) == true - ? Math.Max (HotKeySpecifier.GetColumns (), 0) - : 0), - 1); + SetTitleTextFormatterSize (); SetHotKeyFromTitle (); SetNeedsDisplay (); #if DEBUG @@ -475,6 +470,16 @@ public partial class View : Responder, ISupportInitializeNotification } } + private void SetTitleTextFormatterSize () + { + TitleTextFormatter.Size = new ( + TextFormatter.GetWidestLineLength (TitleTextFormatter.Text) + - (TitleTextFormatter.Text?.Contains ((char)HotKeySpecifier.Value) == true + ? Math.Max (HotKeySpecifier.GetColumns (), 0) + : 0), + 1); + } + /// Called when the has been changed. Invokes the event. /// The that is/has been replaced. /// The new to be replaced. diff --git a/UnitTests/Drawing/JustifierTests.cs b/UnitTests/Drawing/JustifierTests.cs index 2f98ec430..481848640 100644 --- a/UnitTests/Drawing/JustifierTests.cs +++ b/UnitTests/Drawing/JustifierTests.cs @@ -199,8 +199,6 @@ public class JustifierTests (ITestOutputHelper output) [InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30 }, 101, new [] { 0, 50, 71 })] [InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30, 40 }, 101, new [] { 0, 10, 30, 61 })] [InlineData (Justification.FirstLeftRestRight, new [] { 10, 20, 30, 40, 50 }, 151, new [] { 0, 10, 30, 60, 101 })] - [InlineData (Justification.FirstLeftRestRight, new [] { 3, 3, 3 }, 21, new [] { 0, 14, 18 })] - [InlineData (Justification.FirstLeftRestRight, new [] { 3, 4, 5 }, 21, new [] { 0, 11, 16 })] public void TestJustifications_PutSpaceBetweenItems (Justification justification, int [] sizes, int containerSize, int [] expected) { int [] positions = new Justifier diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs index cd57e86a2..9188562d0 100644 --- a/UnitTests/Text/TextFormatterTests.cs +++ b/UnitTests/Text/TextFormatterTests.cs @@ -4082,6 +4082,75 @@ B")] [SetupFakeDriver] [Theory] + + // LeftRight_TopBottom + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +0 2 4** +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Right, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +**0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Centered, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +*0 2 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Justified, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +0 2 4 +******* +******* +******* +******* +******* +*******")] + + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Right, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +*0 你 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Centered, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Justified, VerticalTextAlignment.Top, TextDirection.LeftRight_TopBottom, @" +0 你 4 +******* +******* +******* +******* +******* +*******")] + + // LeftRight_BottomTop [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.LeftRight_BottomTop, @" 0 2 4** ******* @@ -4148,6 +4217,208 @@ B")] ******* *******")] + // RightLeft_TopBottom + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +4 2 0** +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Right, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +**4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Centered, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +*4 2 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Justified, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +4 2 0 +******* +******* +******* +******* +******* +*******")] + + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Right, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +*4 你 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Centered, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Justified, VerticalTextAlignment.Top, TextDirection.RightLeft_TopBottom, @" +4 你 0 +******* +******* +******* +******* +******* +*******")] + + // RightLeft_BottomTop + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +4 2 0** +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Right, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +**4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Centered, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +*4 2 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Justified, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +4 2 0 +******* +******* +******* +******* +******* +*******")] + + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Right, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +*4 你 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Centered, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Justified, VerticalTextAlignment.Top, TextDirection.RightLeft_BottomTop, @" +4 你 0 +******* +******* +******* +******* +******* +*******")] + + // TopBottom_LeftRight + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.TopBottom_LeftRight, @" +0****** + ****** +2****** + ****** +4****** +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Bottom, TextDirection.TopBottom_LeftRight, @" +******* +******* +0****** + ****** +2****** + ****** +4******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Middle, TextDirection.TopBottom_LeftRight, @" +******* +0****** + ****** +2****** + ****** +4****** +*******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Justified, TextDirection.TopBottom_LeftRight, @" +0****** + ****** + ****** +2****** + ****** + ****** +4******")] + + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.TopBottom_LeftRight, @" +0****** + ****** +你***** + ****** +4****** +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Bottom, TextDirection.TopBottom_LeftRight, @" +******* +******* +0****** + ****** +你***** + ****** +4******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Middle, TextDirection.TopBottom_LeftRight, @" +******* +0****** + ****** +你***** + ****** +4****** +*******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Justified, TextDirection.TopBottom_LeftRight, @" +0****** + ****** + ****** +你***** + ****** + ****** +4******")] + + // TopBottom_RightLeft [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.TopBottom_RightLeft, @" 0****** ****** @@ -4224,6 +4495,140 @@ B")] ***** * *****4* *******")] + + // BottomTop_LeftRight + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.BottomTop_LeftRight, @" +4****** + ****** +2****** + ****** +0****** +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Bottom, TextDirection.BottomTop_LeftRight, @" +******* +******* +4****** + ****** +2****** + ****** +0******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Middle, TextDirection.BottomTop_LeftRight, @" +******* +4****** + ****** +2****** + ****** +0****** +*******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Justified, TextDirection.BottomTop_LeftRight, @" +4****** + ****** + ****** +2****** + ****** + ****** +0******")] + + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.BottomTop_LeftRight, @" +4****** + ****** +你***** + ****** +0****** +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Bottom, TextDirection.BottomTop_LeftRight, @" +******* +******* +4****** + ****** +你***** + ****** +0******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Middle, TextDirection.BottomTop_LeftRight, @" +******* +4****** + ****** +你***** + ****** +0****** +*******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Justified, TextDirection.BottomTop_LeftRight, @" +4****** + ****** + ****** +你***** + ****** + ****** +0******")] + + // BottomTop_RightLeft + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.BottomTop_RightLeft, @" +4****** + ****** +2****** + ****** +0****** +******* +*******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Bottom, TextDirection.BottomTop_RightLeft, @" +******* +******* +4****** + ****** +2****** + ****** +0******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Middle, TextDirection.BottomTop_RightLeft, @" +******* +4****** + ****** +2****** + ****** +0****** +*******")] + [InlineData ("0 2 4", TextAlignment.Left, VerticalTextAlignment.Justified, TextDirection.BottomTop_RightLeft, @" +4****** + ****** + ****** +2****** + ****** + ****** +0******")] + + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Top, TextDirection.BottomTop_RightLeft, @" +4****** + ****** +你***** + ****** +0****** +******* +*******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Bottom, TextDirection.BottomTop_RightLeft, @" +******* +******* +4****** + ****** +你***** + ****** +0******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Middle, TextDirection.BottomTop_RightLeft, @" +******* +4****** + ****** +你***** + ****** +0****** +*******")] + [InlineData ("0 你 4", TextAlignment.Left, VerticalTextAlignment.Justified, TextDirection.BottomTop_RightLeft, @" +4****** + ****** + ****** +你***** + ****** + ****** +0******")] public void Draw_Text_Alignment (string text, TextAlignment horizontalTextAlignment, VerticalTextAlignment verticalTextAlignment, TextDirection textDirection, string expectedText) { TextFormatter tf = new () diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index bc5ec027d..8d354e86d 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -1064,7 +1064,7 @@ public class DimAutoTests (ITestOutputHelper output) Assert.Equal (15, calculatedHeight); // 5 (Y position) + 10 (Height) } - [Fact] + [Fact (Skip = "DimAuto_TextOnly")] public void DimAuto_With_Subview_At_PosPercent () { var view = new View () { Width = 100, Height = 100 }; @@ -1083,7 +1083,7 @@ public class DimAutoTests (ITestOutputHelper output) Assert.Equal (60, calculatedHeight); // 50% of 100 (Height) + 10 } - [Fact] + [Fact (Skip = "DimAuto_TextOnly")] public void DimAuto_With_Subview_At_PosCenter () { var view = new View () { Width = 100, Height = 100 }; @@ -1102,7 +1102,7 @@ public class DimAutoTests (ITestOutputHelper output) Assert.Equal (60, calculatedHeight); // Centered in 100 (Height) + 10 } - [Fact] + [Fact (Skip = "DimAuto_TextOnly")] public void DimAuto_With_Subview_At_PosAnchorEnd () { var dimWidth = Dim.Auto (min: 50); diff --git a/UnitTests/View/TitleTests.cs b/UnitTests/View/TitleTests.cs index 1262d1cab..2ab9e13aa 100644 --- a/UnitTests/View/TitleTests.cs +++ b/UnitTests/View/TitleTests.cs @@ -9,8 +9,8 @@ namespace Terminal.Gui.ViewTests; public class TitleTests { - private readonly ITestOutputHelper output; - public TitleTests (ITestOutputHelper output) { this.output = output; } + private readonly ITestOutputHelper _output; + public TitleTests (ITestOutputHelper output) { this._output = output; } [Fact] public void Set_Title_Fires_TitleChanged () @@ -76,4 +76,33 @@ public class TitleTests Assert.Equal (Key.H, view.HotKey); } + + [SetupFakeDriver] + [Fact] + public void Change_View_Size_Update_Title_Size () + { + var view = new View { Title = "_Hello World", Width = Dim.Auto (), Height = Dim.Auto (), BorderStyle = LineStyle.Single}; + var top = new Toplevel (); + top.Add (view); + Application.Begin (top); + + Assert.Equal (string.Empty, view.Text); + Assert.Equal (new (2, 2), view.Frame.Size); + TestHelpers.AssertDriverContentsWithFrameAre (@" +┌┐ +└┘", _output); + + var text = "This text will increment the view size and display the title."; + view.Text = text; + top.Draw (); + Assert.Equal (text, view.Text); + // SetupFakeDriver only create a screen with 25 cols and 25 rows + Assert.Equal (new (25, 3), view.Frame.Size); + TestHelpers.AssertDriverContentsWithFrameAre (@" +┌┤Hello World├──────────┐ +│This text will incremen│ +└───────────────────────┘", _output); + + top.Dispose (); + } } diff --git a/UnitTests/Views/LabelTests.cs b/UnitTests/Views/LabelTests.cs index 9f2bb151a..1347e19ff 100644 --- a/UnitTests/Views/LabelTests.cs +++ b/UnitTests/Views/LabelTests.cs @@ -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." }; + [Fact] + [AutoInitShutdown] + public void Label_Draw_Fill_Remaining_AutoSize_False () + { + Size tfSize = new Size (80, 1); - // 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 label = new Label { Text = "This label needs to be cleared before rewritten.", Width = tfSize.Width, Height = tfSize.Height }; - // 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 tf1 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, Size = tfSize }; + tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten."; - // var top = new Toplevel (); - // top.Add (label); - // Application.Begin (top); + var tf2 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, Size = tfSize, FillRemaining = true }; + tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten."; - // Assert.True (label.AutoSize); + var top = new Toplevel (); + top.Add (label); + Application.Begin (top); - // tf1.Draw ( - // new Rectangle (new Point (0, 1), tf1Size), - // label.GetNormalColor (), - // label.ColorScheme.HotNormal - // ); + Assert.False (label.TextFormatter.AutoSize); + Assert.False (tf1.AutoSize); + Assert.False (tf2.AutoSize); + Assert.False (label.TextFormatter.FillRemaining); + Assert.False (tf1.FillRemaining); + Assert.True (tf2.FillRemaining); - // tf2.Draw (new Rectangle (new Point (0, 2), tf2Size), label.GetNormalColor (), label.ColorScheme.HotNormal); + tf1.Draw (new Rectangle (new Point (0, 1), tfSize), 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 - // ); + tf2.Draw (new Rectangle (new Point (0, 2), tfSize), label.GetNormalColor (), label.ColorScheme.HotNormal); - // label.Text = "This label is rewritten."; - // label.Draw (); + 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 + ); - // tf1.Text = "This TextFormatter (tf1) is rewritten."; + Assert.False (label.NeedsDisplay); + Assert.False (label.LayoutNeeded); + Assert.False (label.SubViewNeedsDisplay); + label.Text = "This label is rewritten."; + Assert.True (label.NeedsDisplay); + Assert.True (label.LayoutNeeded); + Assert.False (label.SubViewNeedsDisplay); + label.Draw (); - // tf1.Draw ( - // new Rectangle (new Point (0, 1), tf1Size), - // label.GetNormalColor (), - // label.ColorScheme.HotNormal - // ); + tf1.Text = "This TextFormatter (tf1) is rewritten."; + tf1.Draw (new Rectangle (new Point (0, 1), tfSize), 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); + tf2.Text = "This TextFormatter (tf2) is rewritten."; + tf2.Draw (new Rectangle (new Point (0, 2), tfSize), 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 - // ); - // } + 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]