From d47b18417690030b2f6825057f946612c9271243 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 6 Aug 2024 09:38:05 -0600 Subject: [PATCH 01/16] Added unit tests that fail --- UnitTests/View/Layout/Dim.AutoTests.cs | 383 ++++++++++++---------- UnitTests/View/Layout/Dim.PercentTests.cs | 12 +- 2 files changed, 213 insertions(+), 182 deletions(-) diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index bd0e2eaf7..401a6bb61 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -8,29 +8,31 @@ public partial class DimAutoTests (ITestOutputHelper output) { private readonly ITestOutputHelper _output = output; - private class DimAutoTestView : View + [SetupFakeDriver] + [Fact] + public void Change_To_Non_Auto_Resets_ContentSize () { - public DimAutoTestView () + View view = new () { - ValidatePosDim = true; - Width = Auto (); - Height = Auto (); - } + Width = Auto (), + Height = Auto (), + Text = "01234" + }; + view.SetRelativeLayout (new (100, 100)); + Assert.Equal (new (0, 0, 5, 1), view.Frame); + Assert.Equal (new (5, 1), view.GetContentSize ()); - public DimAutoTestView (Dim width, Dim height) - { - ValidatePosDim = true; - Width = width; - Height = height; - } + // Change text to a longer string + view.Text = "0123456789"; - public DimAutoTestView (string text, Dim width, Dim height) - { - ValidatePosDim = true; - Text = text; - Width = width; - Height = height; - } + Assert.Equal (new (0, 0, 10, 1), view.Frame); + Assert.Equal (new (10, 1), view.GetContentSize ()); + + // If ContentSize was reset, these should cause it to update + view.Width = 5; + view.Height = 1; + + Assert.Equal (new (5, 1), view.GetContentSize ()); } [Theory] @@ -74,6 +76,46 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 10, expectedHeight), superView.Frame); } + [Theory] + [CombinatorialData] + public void HotKey_TextFormatter_Height_Correct ([CombinatorialValues ("1234", "_1234", "1_234", "____")] string text) + { + View view = new () + { + HotKeySpecifier = (Rune)'_', + Text = text, + Width = Auto (), + Height = 1 + }; + Assert.Equal (4, view.TextFormatter.ConstrainToWidth); + Assert.Equal (1, view.TextFormatter.ConstrainToHeight); + + view = new () + { + HotKeySpecifier = (Rune)'_', + TextDirection = TextDirection.TopBottom_LeftRight, + Text = text, + Width = 1, + Height = Auto () + }; + Assert.Equal (1, view.TextFormatter.ConstrainToWidth); + Assert.Equal (4, view.TextFormatter.ConstrainToHeight); + } + + [Theory] + [CombinatorialData] + public void HotKey_TextFormatter_Width_Correct ([CombinatorialValues ("1234", "_1234", "1_234", "____")] string text) + { + View view = new () + { + Text = text, + Height = 1, + Width = Auto () + }; + Assert.Equal (4, view.TextFormatter.ConstrainToWidth); + Assert.Equal (1, view.TextFormatter.ConstrainToHeight); + } + [Fact] public void NoSubViews_Does_Nothing () { @@ -158,6 +200,89 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.Equal (new (0, 0, expectedWidth, expectedHeight), superView.Frame); } + [Fact] + public void TestEquality () + { + var a = new DimAuto + { + MaximumContentDim = null, + MinimumContentDim = 1, + Style = DimAutoStyle.Auto + }; + + var b = new DimAuto + { + MaximumContentDim = null, + MinimumContentDim = 1, + Style = DimAutoStyle.Auto + }; + Assert.True (a.Equals (b)); + Assert.True (a.GetHashCode () == b.GetHashCode ()); + } + + [Fact] + public void TestEquality_Simple () + { + Dim a = Auto (); + Dim b = Auto (); + Assert.True (a.Equals (b)); + Assert.True (a.GetHashCode () == b.GetHashCode ()); + } + + [Fact] + public void TextFormatter_Settings_Change_View_Size () + { + View view = new () + { + Text = "_1234", + Width = Auto () + }; + Assert.Equal (new (4, 0), view.Frame.Size); + + view.Height = 1; + view.SetRelativeLayout (Application.Screen.Size); + Assert.Equal (new (4, 1), view.Frame.Size); + Size lastSize = view.Frame.Size; + + view.TextAlignment = Alignment.Fill; + Assert.Equal (lastSize, view.Frame.Size); + + view = new () + { + Text = "_1234", + Width = Auto (), + Height = 1 + }; + view.SetRelativeLayout (Application.Screen.Size); + + lastSize = view.Frame.Size; + view.VerticalTextAlignment = Alignment.Center; + Assert.Equal (lastSize, view.Frame.Size); + + view = new () + { + Text = "_1234", + Width = Auto (), + Height = 1 + }; + view.SetRelativeLayout (Application.Screen.Size); + lastSize = view.Frame.Size; + view.HotKeySpecifier = (Rune)'*'; + view.SetRelativeLayout (Application.Screen.Size); + Assert.NotEqual (lastSize, view.Frame.Size); + + view = new () + { + Text = "_1234", + Width = Auto (), + Height = 1 + }; + view.SetRelativeLayout (Application.Screen.Size); + lastSize = view.Frame.Size; + view.Text = "*ABCD"; + Assert.NotEqual (lastSize, view.Frame.Size); + } + // Test validation [Fact] public void ValidatePosDim_True_Throws_When_SubView_Uses_SuperView_Dims () @@ -410,46 +535,6 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.Equal (expectedWidth, superView.Frame.Width); } - [Theory] - [InlineData (0, 1, 1)] - [InlineData (1, 1, 1)] - [InlineData (9, 1, 1)] - [InlineData (10, 1, 1)] - [InlineData (0, 10, 10)] - [InlineData (1, 10, 10)] - [InlineData (9, 10, 10)] - [InlineData (10, 10, 10)] - public void Width_Auto_Text_Does_Not_Constrain_To_SuperView (int subX, int textLen, int expectedSubWidth) - { - var superView = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 1, - ValidatePosDim = true - }; - - var subView = new View - { - Text = new ('*', textLen), - X = subX, - Y = 0, - Width = Auto (DimAutoStyle.Text), - Height = 1, - ValidatePosDim = true - }; - - superView.Add (subView); - - superView.BeginInit (); - superView.EndInit (); - superView.SetRelativeLayout (superView.GetContentSize ()); - - superView.LayoutSubviews (); - Assert.Equal (expectedSubWidth, subView.Frame.Width); - } - [Theory] [InlineData (0, 1, 1)] [InlineData (1, 1, 1)] @@ -499,31 +584,69 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.Equal (expectedSubWidth, subView.Frame.Width); } - [SetupFakeDriver] - [Fact] - public void Change_To_Non_Auto_Resets_ContentSize () + [Theory] + [InlineData (0, 1, 1)] + [InlineData (1, 1, 1)] + [InlineData (9, 1, 1)] + [InlineData (10, 1, 1)] + [InlineData (0, 10, 10)] + [InlineData (1, 10, 10)] + [InlineData (9, 10, 10)] + [InlineData (10, 10, 10)] + public void Width_Auto_Text_Does_Not_Constrain_To_SuperView (int subX, int textLen, int expectedSubWidth) { - View view = new () + var superView = new View { - Width = Auto (), - Height = Auto (), - Text = "01234" + X = 0, + Y = 0, + Width = 10, + Height = 1, + ValidatePosDim = true }; - view.SetRelativeLayout (new (100, 100)); - Assert.Equal (new (0, 0, 5, 1), view.Frame); - Assert.Equal (new (5, 1), view.GetContentSize ()); - // Change text to a longer string - view.Text = "0123456789"; + var subView = new View + { + Text = new ('*', textLen), + X = subX, + Y = 0, + Width = Auto (DimAutoStyle.Text), + Height = 1, + ValidatePosDim = true + }; - Assert.Equal (new (0, 0, 10, 1), view.Frame); - Assert.Equal (new (10, 1), view.GetContentSize ()); + superView.Add (subView); - // If ContentSize was reset, these should cause it to update - view.Width = 5; - view.Height = 1; + superView.BeginInit (); + superView.EndInit (); + superView.SetRelativeLayout (superView.GetContentSize ()); - Assert.Equal (new (5, 1), view.GetContentSize ()); + superView.LayoutSubviews (); + Assert.Equal (expectedSubWidth, subView.Frame.Width); + } + + private class DimAutoTestView : View + { + public DimAutoTestView () + { + ValidatePosDim = true; + Width = Auto (); + Height = Auto (); + } + + public DimAutoTestView (Dim width, Dim height) + { + ValidatePosDim = true; + Width = width; + Height = height; + } + + public DimAutoTestView (string text, Dim width, Dim height) + { + ValidatePosDim = true; + Text = text; + Width = width; + Height = height; + } } #region DimAutoStyle.Auto tests @@ -544,7 +667,6 @@ public partial class DimAutoTests (ITestOutputHelper output) view.SetRelativeLayout (Application.Screen.Size); Assert.Equal (new (expectedW, expectedH), view.Frame.Size); - } [Fact] @@ -653,7 +775,6 @@ public partial class DimAutoTests (ITestOutputHelper output) view.SetRelativeLayout (Application.Screen.Size); Assert.Equal (new (expectedW, expectedH), view.Frame.Size); - } [Theory] @@ -665,15 +786,14 @@ public partial class DimAutoTests (ITestOutputHelper output) public void DimAutoStyle_Text_Sizes_Correctly_With_Min (string text, int minWidth, int minHeight, int expectedW, int expectedH) { var view = new View (); - view.Width = Auto (DimAutoStyle.Text, minimumContentDim: minWidth); - view.Height = Auto (DimAutoStyle.Text, minimumContentDim: minHeight); + view.Width = Auto (DimAutoStyle.Text, minWidth); + view.Height = Auto (DimAutoStyle.Text, minHeight); view.Text = text; view.SetRelativeLayout (Application.Screen.Size); Assert.Equal (new (expectedW, expectedH), view.Frame.Size); - } [Theory] @@ -699,7 +819,6 @@ public partial class DimAutoTests (ITestOutputHelper output) [InlineData ("01234", 5, 1)] [InlineData ("01234ABCDE", 10, 1)] [InlineData ("01234\nABCDE", 5, 2)] - public void DimAutoStyle_Text_NoMin_Not_Constrained_By_ContentSize (string text, int expectedW, int expectedH) { var view = new View (); @@ -711,7 +830,6 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.Equal (new (expectedW, expectedH), view.Frame.Size); } - [Theory] [InlineData ("", 0, 0)] [InlineData (" ", 1, 1)] @@ -720,7 +838,7 @@ public partial class DimAutoTests (ITestOutputHelper output) [InlineData ("01234\nABCDE", 5, 2)] public void DimAutoStyle_Text_NoMin_Not_Constrained_By_SuperView (string text, int expectedW, int expectedH) { - var superView = new View () + var superView = new View { Width = 1, Height = 1 }; @@ -870,100 +988,5 @@ public partial class DimAutoTests (ITestOutputHelper output) #endregion DimAutoStyle.Content tests - [Fact] - public void TextFormatter_Settings_Change_View_Size () - { - View view = new () - { - Text = "_1234", - Width = Auto () - }; - Assert.Equal (new (4, 0), view.Frame.Size); - - view.Height = 1; - view.SetRelativeLayout (Application.Screen.Size); - Assert.Equal (new (4, 1), view.Frame.Size); - Size lastSize = view.Frame.Size; - - view.TextAlignment = Alignment.Fill; - Assert.Equal (lastSize, view.Frame.Size); - - view = new () - { - Text = "_1234", - Width = Auto (), - Height = 1 - }; - view.SetRelativeLayout (Application.Screen.Size); - - lastSize = view.Frame.Size; - view.VerticalTextAlignment = Alignment.Center; - Assert.Equal (lastSize, view.Frame.Size); - - view = new () - { - Text = "_1234", - Width = Auto (), - Height = 1 - }; - view.SetRelativeLayout (Application.Screen.Size); - lastSize = view.Frame.Size; - view.HotKeySpecifier = (Rune)'*'; - view.SetRelativeLayout (Application.Screen.Size); - Assert.NotEqual (lastSize, view.Frame.Size); - - view = new () - { - Text = "_1234", - Width = Auto (), - Height = 1 - }; - view.SetRelativeLayout (Application.Screen.Size); - lastSize = view.Frame.Size; - view.Text = "*ABCD"; - Assert.NotEqual (lastSize, view.Frame.Size); - } - - - [Theory] - [CombinatorialData] - public void HotKey_TextFormatter_Width_Correct ([CombinatorialValues ("1234", "_1234", "1_234", "____")] string text) - { - View view = new () - { - Text = text, - Height = 1, - Width = Auto () - }; - Assert.Equal (4, view.TextFormatter.ConstrainToWidth); - Assert.Equal (1, view.TextFormatter.ConstrainToHeight); - } - - [Theory] - [CombinatorialData] - public void HotKey_TextFormatter_Height_Correct ([CombinatorialValues ("1234", "_1234", "1_234", "____")] string text) - { - View view = new () - { - HotKeySpecifier = (Rune)'_', - Text = text, - Width = Auto (), - Height = 1 - }; - Assert.Equal (4, view.TextFormatter.ConstrainToWidth); - Assert.Equal (1, view.TextFormatter.ConstrainToHeight); - - view = new () - { - HotKeySpecifier = (Rune)'_', - TextDirection = TextDirection.TopBottom_LeftRight, - Text = text, - Width = 1, - Height = Auto () - }; - Assert.Equal (1, view.TextFormatter.ConstrainToWidth); - Assert.Equal (4, view.TextFormatter.ConstrainToHeight); - } - // Test variations of Frame } diff --git a/UnitTests/View/Layout/Dim.PercentTests.cs b/UnitTests/View/Layout/Dim.PercentTests.cs index adf23b46c..443e4e96f 100644 --- a/UnitTests/View/Layout/Dim.PercentTests.cs +++ b/UnitTests/View/Layout/Dim.PercentTests.cs @@ -15,7 +15,6 @@ public class DimPercentTests Assert.Equal (50, result); } - [Fact] public void DimPercent_Equals () { @@ -63,6 +62,15 @@ public class DimPercentTests Assert.NotEqual (dim1, dim2); } + [Fact] + public void TestEquality () + { + var a = Dim.Percent (32); + var b = Dim.Percent (32); + Assert.True (a.Equals (b)); + Assert.True (a.GetHashCode () == b.GetHashCode ()); + } + [Fact] public void DimPercent_Invalid_Throws () { @@ -157,7 +165,7 @@ public class DimPercentTests } [Theory] - [InlineData(0)] + [InlineData (0)] [InlineData (1)] [InlineData (50)] [InlineData (100)] From a8f929bed929b1047e5ff379236b67a22cd1ebd2 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 13 Aug 2024 14:12:32 -0600 Subject: [PATCH 02/16] Fixed DimAuto and tests --- Terminal.Gui/View/Layout/DimAuto.cs | 29 ++++++++++++------ UnitTests/View/Layout/Dim.AutoTests.cs | 42 ++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 6bd5f4d0f..05ac21d42 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -17,25 +17,30 @@ namespace Terminal.Gui; /// public class DimAuto : Dim { - private readonly Dim? _maximumContentDim; - - private readonly Dim? _minimumContentDim; - - private readonly DimAutoStyle _style; - - /// + /// public override bool Equals (object? other) { + if (ReferenceEquals (this, other)) + { + return true; + } + if (other is not DimAuto auto) { return false; } - return auto.MinimumContentDim == MinimumContentDim && auto.MaximumContentDim == MaximumContentDim && auto.Style == Style; + return EqualityComparer.Default.Equals (MinimumContentDim, auto.MinimumContentDim) && + EqualityComparer.Default.Equals (MaximumContentDim, auto.MaximumContentDim) && + Style == auto.Style; } - /// - public override int GetHashCode () { return HashCode.Combine (MinimumContentDim, MaximumContentDim, Style); } + /// + public override int GetHashCode () + { + return HashCode.Combine (MinimumContentDim, MaximumContentDim, Style); + } + private readonly Dim? _maximumContentDim; /// /// Gets the maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED. @@ -48,6 +53,8 @@ public class DimAuto : Dim init => _maximumContentDim = value; } + private readonly Dim? _minimumContentDim; + /// /// Gets the minimum dimension the View's ContentSize will be constrained to. /// @@ -59,6 +66,8 @@ public class DimAuto : Dim init => _minimumContentDim = value; } + private readonly DimAutoStyle _style; + /// /// Gets the style of the DimAuto. /// diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index 401a6bb61..7ac704846 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -216,8 +216,50 @@ public partial class DimAutoTests (ITestOutputHelper output) MinimumContentDim = 1, Style = DimAutoStyle.Auto }; + + var c = new DimAuto + { + MaximumContentDim = 2, + MinimumContentDim = 1, + Style = DimAutoStyle.Auto + }; + + var d = new DimAuto + { + MaximumContentDim = null, + MinimumContentDim = 1, + Style = DimAutoStyle.Content + }; + + var e = new DimAuto + { + MaximumContentDim = null, + MinimumContentDim = 2, + Style = DimAutoStyle.Auto + }; + + // Test equality with same values Assert.True (a.Equals (b)); Assert.True (a.GetHashCode () == b.GetHashCode ()); + + // Test inequality with different MaximumContentDim + Assert.False (a.Equals (c)); + Assert.False (a.GetHashCode () == c.GetHashCode ()); + + // Test inequality with different Style + Assert.False (a.Equals (d)); + Assert.False (a.GetHashCode () == d.GetHashCode ()); + + // Test inequality with different MinimumContentDim + Assert.False (a.Equals (e)); + Assert.False (a.GetHashCode () == e.GetHashCode ()); + + // Test equality with self + Assert.True (a.Equals (a)); + Assert.True (a.GetHashCode () == a.GetHashCode ()); + + // Test inequality with null + Assert.False (a.Equals (null)); } [Fact] From 6ec69d76448a86412167bf1f8e6a0b5fc30b5b8b Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 13 Aug 2024 15:41:11 -0600 Subject: [PATCH 03/16] Code cleanup & doc fix --- UnitTests/View/Layout/Dim.AutoTests.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index 7ac704846..e1a742d8a 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -254,10 +254,6 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.False (a.Equals (e)); Assert.False (a.GetHashCode () == e.GetHashCode ()); - // Test equality with self - Assert.True (a.Equals (a)); - Assert.True (a.GetHashCode () == a.GetHashCode ()); - // Test inequality with null Assert.False (a.Equals (null)); } From 8edb06213ef8887fbbd26202dd02fc4565d2c8a1 Mon Sep 17 00:00:00 2001 From: Tig Date: Wed, 14 Aug 2024 09:28:47 -0600 Subject: [PATCH 04/16] class Dim -> struct Dim --- Terminal.Gui/View/Layout/Dim.cs | 2 +- Terminal.Gui/View/Layout/DimAbsolute.cs | 8 +------- Terminal.Gui/View/Layout/DimAuto.cs | 25 +------------------------ Terminal.Gui/View/Layout/DimCombine.cs | 2 +- Terminal.Gui/View/Layout/DimFill.cs | 8 +------- Terminal.Gui/View/Layout/DimFunc.cs | 5 +---- Terminal.Gui/View/Layout/DimPercent.cs | 8 +------- Terminal.Gui/View/Layout/DimView.cs | 8 +------- UnitTests/View/Layout/Dim.FuncTests.cs | 5 ++++- 9 files changed, 12 insertions(+), 59 deletions(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 3db2be5f9..45899dd78 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -78,7 +78,7 @@ namespace Terminal.Gui; /// /// /// -public abstract class Dim +public abstract record Dim { #region static Dim creation methods diff --git a/Terminal.Gui/View/Layout/DimAbsolute.cs b/Terminal.Gui/View/Layout/DimAbsolute.cs index 72d4e12f7..aa2108cc2 100644 --- a/Terminal.Gui/View/Layout/DimAbsolute.cs +++ b/Terminal.Gui/View/Layout/DimAbsolute.cs @@ -11,14 +11,8 @@ namespace Terminal.Gui; /// /// /// -public class DimAbsolute (int size) : Dim +public record DimAbsolute (int size) : Dim { - /// - public override bool Equals (object? other) { return other is DimAbsolute abs && abs.Size == Size; } - - /// - public override int GetHashCode () { return Size.GetHashCode (); } - /// /// Gets the size of the dimension. /// diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 05ac21d42..408d3c74b 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -15,31 +15,8 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -public class DimAuto : Dim +public record DimAuto : Dim { - /// - public override bool Equals (object? other) - { - if (ReferenceEquals (this, other)) - { - return true; - } - - if (other is not DimAuto auto) - { - return false; - } - - return EqualityComparer.Default.Equals (MinimumContentDim, auto.MinimumContentDim) && - EqualityComparer.Default.Equals (MaximumContentDim, auto.MaximumContentDim) && - Style == auto.Style; - } - - /// - public override int GetHashCode () - { - return HashCode.Combine (MinimumContentDim, MaximumContentDim, Style); - } private readonly Dim? _maximumContentDim; /// diff --git a/Terminal.Gui/View/Layout/DimCombine.cs b/Terminal.Gui/View/Layout/DimCombine.cs index f8b5d141c..bf2006153 100644 --- a/Terminal.Gui/View/Layout/DimCombine.cs +++ b/Terminal.Gui/View/Layout/DimCombine.cs @@ -13,7 +13,7 @@ namespace Terminal.Gui; /// /// The left dimension. /// The right dimension. -public class DimCombine (AddOrSubtract add, Dim left, Dim right) : Dim +public record DimCombine (AddOrSubtract add, Dim left, Dim right) : Dim { /// /// Gets whether the two dimensions are added or subtracted. diff --git a/Terminal.Gui/View/Layout/DimFill.cs b/Terminal.Gui/View/Layout/DimFill.cs index 03cf6f3d2..a5c964f51 100644 --- a/Terminal.Gui/View/Layout/DimFill.cs +++ b/Terminal.Gui/View/Layout/DimFill.cs @@ -9,14 +9,8 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// The margin to not fill. -public class DimFill (int margin) : Dim +public record DimFill (int margin) : Dim { - /// - public override bool Equals (object? other) { return other is DimFill fill && fill.Margin == Margin; } - - /// - public override int GetHashCode () { return Margin.GetHashCode (); } - /// /// Gets the margin to not fill. /// diff --git a/Terminal.Gui/View/Layout/DimFunc.cs b/Terminal.Gui/View/Layout/DimFunc.cs index c15e9fc8c..042f85318 100644 --- a/Terminal.Gui/View/Layout/DimFunc.cs +++ b/Terminal.Gui/View/Layout/DimFunc.cs @@ -9,11 +9,8 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -public class DimFunc (Func dim) : Dim +public record DimFunc (Func dim) : Dim { - /// - public override bool Equals (object? other) { return other is DimFunc f && f.Func () == Func (); } - /// /// Gets the function that computes the dimension. /// diff --git a/Terminal.Gui/View/Layout/DimPercent.cs b/Terminal.Gui/View/Layout/DimPercent.cs index 2ae81302a..b1bf7e7c6 100644 --- a/Terminal.Gui/View/Layout/DimPercent.cs +++ b/Terminal.Gui/View/Layout/DimPercent.cs @@ -13,14 +13,8 @@ namespace Terminal.Gui; /// If the dimension is computed using the View's position ( or /// ); otherwise, the dimension is computed using the View's . /// -public class DimPercent (int percent, DimPercentMode mode = DimPercentMode.ContentSize) : Dim +public record DimPercent (int percent, DimPercentMode mode = DimPercentMode.ContentSize) : Dim { - /// - public override bool Equals (object? other) { return other is DimPercent f && f.Percent == Percent && f.Mode == Mode; } - - /// - public override int GetHashCode () { return Percent.GetHashCode (); } - /// /// Gets the percentage. /// diff --git a/Terminal.Gui/View/Layout/DimView.cs b/Terminal.Gui/View/Layout/DimView.cs index 7a7568a95..b37f9bb7e 100644 --- a/Terminal.Gui/View/Layout/DimView.cs +++ b/Terminal.Gui/View/Layout/DimView.cs @@ -8,7 +8,7 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -public class DimView : Dim +public record DimView : Dim { /// /// Initializes a new instance of the class. @@ -26,12 +26,6 @@ public class DimView : Dim /// public Dimension Dimension { get; } - /// - public override bool Equals (object? other) { return other is DimView abs && abs.Target == Target && abs.Dimension == Dimension; } - - /// - public override int GetHashCode () { return Target!.GetHashCode (); } - /// /// Gets the View the dimension is anchored to. /// diff --git a/UnitTests/View/Layout/Dim.FuncTests.cs b/UnitTests/View/Layout/Dim.FuncTests.cs index 12b9c562a..ab40cbf85 100644 --- a/UnitTests/View/Layout/Dim.FuncTests.cs +++ b/UnitTests/View/Layout/Dim.FuncTests.cs @@ -14,9 +14,12 @@ public class DimFuncTests (ITestOutputHelper output) Func f2 = () => 0; Dim dim1 = Func (f1); - Dim dim2 = Func (f2); + Dim dim2 = Func (f1); Assert.Equal (dim1, dim2); + dim2 = Func (f2); + Assert.NotEqual (dim1, dim2); + f2 = () => 1; dim2 = Func (f2); Assert.NotEqual (dim1, dim2); From 6a13e777ffb2e220af47e21c7d42cdfa14b92098 Mon Sep 17 00:00:00 2001 From: Tig Date: Wed, 14 Aug 2024 13:02:11 -0600 Subject: [PATCH 05/16] class Pos -> record Pos --- Terminal.Gui/View/Layout/Pos.cs | 2 +- Terminal.Gui/View/Layout/PosAbsolute.cs | 8 +- Terminal.Gui/View/Layout/PosAlign.cs | 14 +--- Terminal.Gui/View/Layout/PosAnchorEnd.cs | 8 +- Terminal.Gui/View/Layout/PosCenter.cs | 2 +- Terminal.Gui/View/Layout/PosCombine.cs | 2 +- Terminal.Gui/View/Layout/PosFunc.cs | 8 +- Terminal.Gui/View/Layout/PosPercent.cs | 8 +- Terminal.Gui/View/Layout/PosView.cs | 8 +- UnitTests/View/Layout/Pos.AlignTests.cs | 92 ++++++++++----------- UnitTests/View/Layout/Pos.AnchorEndTests.cs | 9 -- UnitTests/View/Layout/Pos.CenterTests.cs | 10 --- UnitTests/View/Layout/Pos.FuncTests.cs | 2 +- UnitTests/View/Layout/Pos.Tests.cs | 15 ---- 14 files changed, 56 insertions(+), 132 deletions(-) diff --git a/Terminal.Gui/View/Layout/Pos.cs b/Terminal.Gui/View/Layout/Pos.cs index ba377fcdc..638b13b9e 100644 --- a/Terminal.Gui/View/Layout/Pos.cs +++ b/Terminal.Gui/View/Layout/Pos.cs @@ -131,7 +131,7 @@ namespace Terminal.Gui; /// /// /// -public abstract class Pos +public abstract record Pos { #region static Pos creation methods diff --git a/Terminal.Gui/View/Layout/PosAbsolute.cs b/Terminal.Gui/View/Layout/PosAbsolute.cs index 44afdac97..173d5a5b0 100644 --- a/Terminal.Gui/View/Layout/PosAbsolute.cs +++ b/Terminal.Gui/View/Layout/PosAbsolute.cs @@ -11,19 +11,13 @@ namespace Terminal.Gui; /// /// /// -public class PosAbsolute (int position) : Pos +public record PosAbsolute (int position) : Pos { /// /// The position of the in the layout. /// public int Position { get; } = position; - /// - public override bool Equals (object? other) { return other is PosAbsolute abs && abs.Position == Position; } - - /// - public override int GetHashCode () { return Position.GetHashCode (); } - /// public override string ToString () { return $"Absolute({Position})"; } diff --git a/Terminal.Gui/View/Layout/PosAlign.cs b/Terminal.Gui/View/Layout/PosAlign.cs index 79e22d410..8ec4e754b 100644 --- a/Terminal.Gui/View/Layout/PosAlign.cs +++ b/Terminal.Gui/View/Layout/PosAlign.cs @@ -24,7 +24,7 @@ namespace Terminal.Gui; /// The alignment is applied to all views with the same . /// /// -public class PosAlign : Pos +public record PosAlign : Pos { /// /// The cached location. Used to store the calculated location to minimize recalculating it. @@ -137,18 +137,6 @@ public class PosAlign : Pos private void Aligner_PropertyChanged (object? sender, PropertyChangedEventArgs e) { _cachedLocation = null; } - /// - public override bool Equals (object? other) - { - return other is PosAlign align - && GroupId == align.GroupId - && align.Aligner.Alignment == Aligner.Alignment - && align.Aligner.AlignmentModes == Aligner.AlignmentModes; - } - - /// - public override int GetHashCode () { return HashCode.Combine (Aligner, GroupId); } - /// public override string ToString () { return $"Align(alignment={Aligner.Alignment},modes={Aligner.AlignmentModes},groupId={GroupId})"; } diff --git a/Terminal.Gui/View/Layout/PosAnchorEnd.cs b/Terminal.Gui/View/Layout/PosAnchorEnd.cs index e4641c2b5..9156e2230 100644 --- a/Terminal.Gui/View/Layout/PosAnchorEnd.cs +++ b/Terminal.Gui/View/Layout/PosAnchorEnd.cs @@ -10,7 +10,7 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -public class PosAnchorEnd : Pos +public record PosAnchorEnd : Pos { /// /// Gets the offset of the position from the right/bottom. @@ -30,12 +30,6 @@ public class PosAnchorEnd : Pos /// public PosAnchorEnd (int offset) { Offset = offset; } - /// - public override bool Equals (object? other) { return other is PosAnchorEnd anchorEnd && anchorEnd.Offset == Offset; } - - /// - public override int GetHashCode () { return Offset.GetHashCode (); } - /// /// If true, the offset is the width of the view, if false, the offset is the offset value. /// diff --git a/Terminal.Gui/View/Layout/PosCenter.cs b/Terminal.Gui/View/Layout/PosCenter.cs index 8f3d700b5..1d7cdc1e1 100644 --- a/Terminal.Gui/View/Layout/PosCenter.cs +++ b/Terminal.Gui/View/Layout/PosCenter.cs @@ -4,7 +4,7 @@ namespace Terminal.Gui; /// /// Represents a position that is centered. /// -public class PosCenter : Pos +public record PosCenter : Pos { /// public override string ToString () { return "Center"; } diff --git a/Terminal.Gui/View/Layout/PosCombine.cs b/Terminal.Gui/View/Layout/PosCombine.cs index 63ff1814f..63ae05dde 100644 --- a/Terminal.Gui/View/Layout/PosCombine.cs +++ b/Terminal.Gui/View/Layout/PosCombine.cs @@ -15,7 +15,7 @@ namespace Terminal.Gui; /// /// The left position. /// The right position. -public class PosCombine (AddOrSubtract add, Pos left, Pos right) : Pos +public record PosCombine (AddOrSubtract add, Pos left, Pos right) : Pos { /// /// Gets whether the two positions are added or subtracted. diff --git a/Terminal.Gui/View/Layout/PosFunc.cs b/Terminal.Gui/View/Layout/PosFunc.cs index 24344f9a8..a46367f34 100644 --- a/Terminal.Gui/View/Layout/PosFunc.cs +++ b/Terminal.Gui/View/Layout/PosFunc.cs @@ -11,19 +11,13 @@ namespace Terminal.Gui; /// /// /// The position. -public class PosFunc (Func pos) : Pos +public record PosFunc (Func pos) : Pos { /// /// Gets the function that computes the position. /// public new Func Func { get; } = pos; - /// - public override bool Equals (object? other) { return other is PosFunc f && f.Func () == Func (); } - - /// - public override int GetHashCode () { return Func.GetHashCode (); } - /// public override string ToString () { return $"PosFunc({Func ()})"; } diff --git a/Terminal.Gui/View/Layout/PosPercent.cs b/Terminal.Gui/View/Layout/PosPercent.cs index 384ba1fda..d38b503fe 100644 --- a/Terminal.Gui/View/Layout/PosPercent.cs +++ b/Terminal.Gui/View/Layout/PosPercent.cs @@ -11,19 +11,13 @@ namespace Terminal.Gui; /// /// /// -public class PosPercent (int percent) : Pos +public record PosPercent (int percent) : Pos { /// /// Gets the percentage of the width or height of the SuperView. /// public new int Percent { get; } = percent; - /// - public override bool Equals (object? other) { return other is PosPercent i && i.Percent == Percent; } - - /// - public override int GetHashCode () { return Percent.GetHashCode (); } - /// public override string ToString () { return $"Percent({Percent})"; } diff --git a/Terminal.Gui/View/Layout/PosView.cs b/Terminal.Gui/View/Layout/PosView.cs index a46f6898a..13e2981ec 100644 --- a/Terminal.Gui/View/Layout/PosView.cs +++ b/Terminal.Gui/View/Layout/PosView.cs @@ -12,7 +12,7 @@ namespace Terminal.Gui; /// /// The View the position is anchored to. /// The side of the View the position is anchored to. -public class PosView (View? view, Side side) : Pos +public record PosView (View? view, Side side) : Pos { /// /// Gets the View the position is anchored to. @@ -24,12 +24,6 @@ public class PosView (View? view, Side side) : Pos /// public Side Side { get; } = side; - /// - public override bool Equals (object? other) { return other is PosView abs && abs.Target == Target && abs.Side == Side; } - - /// - public override int GetHashCode () { return Target!.GetHashCode (); } - /// public override string ToString () { diff --git a/UnitTests/View/Layout/Pos.AlignTests.cs b/UnitTests/View/Layout/Pos.AlignTests.cs index 216c7bdc6..05931e648 100644 --- a/UnitTests/View/Layout/Pos.AlignTests.cs +++ b/UnitTests/View/Layout/Pos.AlignTests.cs @@ -27,58 +27,58 @@ public class PosAlignTests Assert.Equal (0, posAlign.Aligner.ContainerSize); } - [Theory] - [InlineData (Alignment.Start, Alignment.Start, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, true)] - [InlineData (Alignment.Center, Alignment.Center, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, true)] - [InlineData (Alignment.Start, Alignment.Center, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, false)] - [InlineData (Alignment.Center, Alignment.Start, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, false)] - [InlineData (Alignment.Start, Alignment.Start, AlignmentModes.StartToEnd, AlignmentModes.AddSpaceBetweenItems, false)] - public void PosAlign_Equals (Alignment align1, Alignment align2, AlignmentModes mode1, AlignmentModes mode2, bool expectedEquals) - { - var posAlign1 = new PosAlign - { - Aligner = new() - { - Alignment = align1, - AlignmentModes = mode1 - } - }; + //[Theory] + //[InlineData (Alignment.Start, Alignment.Start, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, true)] + //[InlineData (Alignment.Center, Alignment.Center, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, true)] + //[InlineData (Alignment.Start, Alignment.Center, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, false)] + //[InlineData (Alignment.Center, Alignment.Start, AlignmentModes.AddSpaceBetweenItems, AlignmentModes.AddSpaceBetweenItems, false)] + //[InlineData (Alignment.Start, Alignment.Start, AlignmentModes.StartToEnd, AlignmentModes.AddSpaceBetweenItems, false)] + //public void PosAlign_Equals (Alignment align1, Alignment align2, AlignmentModes mode1, AlignmentModes mode2, bool expectedEquals) + //{ + // var posAlign1 = new PosAlign + // { + // Aligner = new () + // { + // Alignment = align1, + // AlignmentModes = mode1 + // } + // }; - var posAlign2 = new PosAlign - { - Aligner = new() - { - Alignment = align2, - AlignmentModes = mode2 - } - }; + // var posAlign2 = new PosAlign + // { + // Aligner = new () + // { + // Alignment = align2, + // AlignmentModes = mode2 + // } + // }; - Assert.Equal (expectedEquals, posAlign1.Equals (posAlign2)); - Assert.Equal (expectedEquals, posAlign2.Equals (posAlign1)); - } + // Assert.Equal (expectedEquals, posAlign1.Equals (posAlign2)); + // Assert.Equal (expectedEquals, posAlign2.Equals (posAlign1)); + //} - [Fact] - public void PosAlign_Equals_CachedLocation_Not_Used () - { - View superView = new () - { - Width = 10, - Height = 25 - }; - View view = new (); - superView.Add (view); + //[Fact] + //public void PosAlign_Equals_CachedLocation_Not_Used () + //{ + // View superView = new () + // { + // Width = 10, + // Height = 25 + // }; + // View view = new (); + // superView.Add (view); - Pos posAlign1 = Pos.Align (Alignment.Center); - view.X = posAlign1; - int pos1 = posAlign1.Calculate (10, Dim.Absolute (0)!, view, Dimension.Width); + // Pos posAlign1 = Pos.Align (Alignment.Center); + // view.X = posAlign1; + // int pos1 = posAlign1.Calculate (10, Dim.Absolute (0)!, view, Dimension.Width); - Pos posAlign2 = Pos.Align (Alignment.Center); - view.Y = posAlign2; - int pos2 = posAlign2.Calculate (25, Dim.Absolute (0)!, view, Dimension.Height); + // Pos posAlign2 = Pos.Align (Alignment.Center); + // view.Y = posAlign2; + // int pos2 = posAlign2.Calculate (25, Dim.Absolute (0)!, view, Dimension.Height); - Assert.NotEqual (pos1, pos2); - Assert.Equal (posAlign1, posAlign2); - } + // Assert.NotEqual (pos1, pos2); + // Assert.Equal (posAlign1, posAlign2); + //} [Fact] public void PosAlign_ToString () diff --git a/UnitTests/View/Layout/Pos.AnchorEndTests.cs b/UnitTests/View/Layout/Pos.AnchorEndTests.cs index 199e9e50e..b5dd8eb34 100644 --- a/UnitTests/View/Layout/Pos.AnchorEndTests.cs +++ b/UnitTests/View/Layout/Pos.AnchorEndTests.cs @@ -27,15 +27,6 @@ public class PosAnchorEndTests (ITestOutputHelper output) Assert.Equal (expectedEquals, posAnchorEnd2.Equals (posAnchorEnd1)); } - [Fact] - public void PosAnchorEnd_GetHashCode () - { - var posAnchorEnd = new PosAnchorEnd (10); - var expectedHashCode = 10.GetHashCode (); - - Assert.Equal (expectedHashCode, posAnchorEnd.GetHashCode ()); - } - [Fact] public void PosAnchorEnd_ToString () { diff --git a/UnitTests/View/Layout/Pos.CenterTests.cs b/UnitTests/View/Layout/Pos.CenterTests.cs index 7aa7a2ff9..ef7d5cc8b 100644 --- a/UnitTests/View/Layout/Pos.CenterTests.cs +++ b/UnitTests/View/Layout/Pos.CenterTests.cs @@ -15,16 +15,6 @@ public class PosCenterTests (ITestOutputHelper output) Assert.NotNull (posCenter); } - [Fact] - public void PosCenter_Equals () - { - var posCenter1 = new PosCenter (); - var posCenter2 = new PosCenter (); - - Assert.False (posCenter1.Equals (posCenter2)); - Assert.False (posCenter2.Equals (posCenter1)); - } - [Fact] public void PosCenter_ToString () { diff --git a/UnitTests/View/Layout/Pos.FuncTests.cs b/UnitTests/View/Layout/Pos.FuncTests.cs index 48b48a681..9874c9160 100644 --- a/UnitTests/View/Layout/Pos.FuncTests.cs +++ b/UnitTests/View/Layout/Pos.FuncTests.cs @@ -13,7 +13,7 @@ public class PosFuncTests (ITestOutputHelper output) Func f2 = () => 0; Pos pos1 = Pos.Func (f1); - Pos pos2 = Pos.Func (f2); + Pos pos2 = Pos.Func (f1); Assert.Equal (pos1, pos2); f2 = () => 1; diff --git a/UnitTests/View/Layout/Pos.Tests.cs b/UnitTests/View/Layout/Pos.Tests.cs index c3e6bb9a2..4b37d27ea 100644 --- a/UnitTests/View/Layout/Pos.Tests.cs +++ b/UnitTests/View/Layout/Pos.Tests.cs @@ -145,21 +145,6 @@ public class PosTests () ); } - [Fact] - public void PosFunction_Equal () - { - Func f1 = () => 0; - Func f2 = () => 0; - - Pos pos1 = Pos.Func (f1); - Pos pos2 = Pos.Func (f2); - Assert.Equal (pos1, pos2); - - f2 = () => 1; - pos2 = Pos.Func (f2); - Assert.NotEqual (pos1, pos2); - } - [Fact] public void PosFunction_SetsValue () { From 1b802d4b8fcddda576fdf8921eae8e85f97fa34a Mon Sep 17 00:00:00 2001 From: Tig Date: Wed, 14 Aug 2024 13:06:15 -0600 Subject: [PATCH 06/16] Tweaked primary constructors --- Terminal.Gui/View/Layout/DimAbsolute.cs | 6 +- Terminal.Gui/View/Layout/DimCombine.cs | 14 +- Terminal.Gui/View/Layout/DimFill.cs | 6 +- Terminal.Gui/View/Layout/DimFunc.cs | 10 +- Terminal.Gui/View/Layout/DimPercent.cs | 10 +- Terminal.Gui/View/Layout/PosAbsolute.cs | 6 +- Terminal.Gui/View/Layout/PosAlign.cs | 205 ++++++++++++------------ Terminal.Gui/View/Layout/PosCombine.cs | 14 +- Terminal.Gui/View/Layout/PosFunc.cs | 8 +- Terminal.Gui/View/Layout/PosPercent.cs | 6 +- Terminal.Gui/View/Layout/PosView.cs | 10 +- 11 files changed, 147 insertions(+), 148 deletions(-) diff --git a/Terminal.Gui/View/Layout/DimAbsolute.cs b/Terminal.Gui/View/Layout/DimAbsolute.cs index aa2108cc2..cb078a121 100644 --- a/Terminal.Gui/View/Layout/DimAbsolute.cs +++ b/Terminal.Gui/View/Layout/DimAbsolute.cs @@ -10,13 +10,13 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// -public record DimAbsolute (int size) : Dim +/// +public record DimAbsolute (int Size) : Dim { /// /// Gets the size of the dimension. /// - public int Size { get; } = size; + public int Size { get; } = Size; /// public override string ToString () { return $"Absolute({Size})"; } diff --git a/Terminal.Gui/View/Layout/DimCombine.cs b/Terminal.Gui/View/Layout/DimCombine.cs index bf2006153..7a5d23614 100644 --- a/Terminal.Gui/View/Layout/DimCombine.cs +++ b/Terminal.Gui/View/Layout/DimCombine.cs @@ -4,31 +4,31 @@ namespace Terminal.Gui; /// /// Represents a dimension that is a combination of two other dimensions. /// -/// +/// /// Indicates whether the two dimensions are added or subtracted. /// /// /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The left dimension. -/// The right dimension. -public record DimCombine (AddOrSubtract add, Dim left, Dim right) : Dim +/// The left dimension. +/// The right dimension. +public record DimCombine (AddOrSubtract Add, Dim Left, Dim Right) : Dim { /// /// Gets whether the two dimensions are added or subtracted. /// - public AddOrSubtract Add { get; } = add; + public AddOrSubtract Add { get; } = Add; /// /// Gets the left dimension. /// - public Dim Left { get; } = left; + public Dim Left { get; } = Left; /// /// Gets the right dimension. /// - public Dim Right { get; } = right; + public Dim Right { get; } = Right; /// public override string ToString () { return $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})"; } diff --git a/Terminal.Gui/View/Layout/DimFill.cs b/Terminal.Gui/View/Layout/DimFill.cs index a5c964f51..27caa6aba 100644 --- a/Terminal.Gui/View/Layout/DimFill.cs +++ b/Terminal.Gui/View/Layout/DimFill.cs @@ -8,13 +8,13 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The margin to not fill. -public record DimFill (int margin) : Dim +/// The margin to not fill. +public record DimFill (int Margin) : Dim { /// /// Gets the margin to not fill. /// - public int Margin { get; } = margin; + public int Margin { get; } = Margin; /// public override string ToString () { return $"Fill({Margin})"; } diff --git a/Terminal.Gui/View/Layout/DimFunc.cs b/Terminal.Gui/View/Layout/DimFunc.cs index 042f85318..8e110d8cd 100644 --- a/Terminal.Gui/View/Layout/DimFunc.cs +++ b/Terminal.Gui/View/Layout/DimFunc.cs @@ -2,19 +2,19 @@ namespace Terminal.Gui; /// -/// Represents a function object that computes the dimension by executing the provided function. +/// Represents a function object that computes the dimension by executing the provided function. /// /// /// This is a low-level API that is typically used internally by the layout system. Use the various static -/// methods on the class to create objects instead. +/// methods on the class to create objects instead. /// -/// -public record DimFunc (Func dim) : Dim +/// +public record DimFunc (Func Dim) : Dim { /// /// Gets the function that computes the dimension. /// - public new Func Func { get; } = dim; + public new Func Func { get; } = Dim; /// public override int GetHashCode () { return Func.GetHashCode (); } diff --git a/Terminal.Gui/View/Layout/DimPercent.cs b/Terminal.Gui/View/Layout/DimPercent.cs index b1bf7e7c6..e62e4500d 100644 --- a/Terminal.Gui/View/Layout/DimPercent.cs +++ b/Terminal.Gui/View/Layout/DimPercent.cs @@ -8,17 +8,17 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The percentage. -/// +/// The percentage. +/// /// If the dimension is computed using the View's position ( or /// ); otherwise, the dimension is computed using the View's . /// -public record DimPercent (int percent, DimPercentMode mode = DimPercentMode.ContentSize) : Dim +public record DimPercent (int Percent, DimPercentMode Mode = DimPercentMode.ContentSize) : Dim { /// /// Gets the percentage. /// - public new int Percent { get; } = percent; + public new int Percent { get; } = Percent; /// /// @@ -28,7 +28,7 @@ public record DimPercent (int percent, DimPercentMode mode = DimPercentMode.Cont /// /// Gets whether the dimension is computed using the View's position or GetContentSize (). /// - public DimPercentMode Mode { get; } = mode; + public DimPercentMode Mode { get; } = Mode; internal override int GetAnchor (int size) { return (int)(size * (Percent / 100f)); } diff --git a/Terminal.Gui/View/Layout/PosAbsolute.cs b/Terminal.Gui/View/Layout/PosAbsolute.cs index 173d5a5b0..b71da5013 100644 --- a/Terminal.Gui/View/Layout/PosAbsolute.cs +++ b/Terminal.Gui/View/Layout/PosAbsolute.cs @@ -10,13 +10,13 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// -public record PosAbsolute (int position) : Pos +/// +public record PosAbsolute (int Position) : Pos { /// /// The position of the in the layout. /// - public int Position { get; } = position; + public int Position { get; } = Position; /// public override string ToString () { return $"Absolute({Position})"; } diff --git a/Terminal.Gui/View/Layout/PosAlign.cs b/Terminal.Gui/View/Layout/PosAlign.cs index 8ec4e754b..d3873a4c0 100644 --- a/Terminal.Gui/View/Layout/PosAlign.cs +++ b/Terminal.Gui/View/Layout/PosAlign.cs @@ -1,7 +1,6 @@ #nullable enable using System.ComponentModel; -using System.Drawing; namespace Terminal.Gui; @@ -31,12 +30,6 @@ public record PosAlign : Pos /// public int? _cachedLocation; - /// - /// Gets the identifier of a set of views that should be aligned together. When only a single - /// set of views in a SuperView is aligned, setting is not needed because it defaults to 0. - /// - public int GroupId { get; init; } - private readonly Aligner? _aligner; /// @@ -57,6 +50,88 @@ public record PosAlign : Pos } } + // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. + /// + /// Returns the minimum size a group of views with the same can be. + /// + /// + /// + /// + /// + public static int CalculateMinDimension (int groupId, IList views, Dimension dimension) + { + List dimensionsList = new (); + + // PERF: If this proves a perf issue, consider caching a ref to this list in each item + List viewsInGroup = views.Where ( + v => + { + return dimension switch + { + Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, + Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, + _ => false + }; + }) + .ToList (); + + if (viewsInGroup.Count == 0) + { + return 0; + } + + // PERF: We iterate over viewsInGroup multiple times here. + + // Update the dimensionList with the sizes of the views + for (var index = 0; index < viewsInGroup.Count; index++) + { + View view = viewsInGroup [index]; + + PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign; + + if (posAlign is { }) + { + dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height); + } + } + + // Align + return dimensionsList.Sum (); + } + + /// + /// Gets the identifier of a set of views that should be aligned together. When only a single + /// set of views in a SuperView is aligned, setting is not needed because it defaults to 0. + /// + public int GroupId { get; init; } + + /// + public override string ToString () { return $"Align(alignment={Aligner.Alignment},modes={Aligner.AlignmentModes},groupId={GroupId})"; } + + internal override int Calculate (int superviewDimension, Dim dim, View us, Dimension dimension) + { + if (_cachedLocation.HasValue && Aligner.ContainerSize == superviewDimension) + { + return _cachedLocation.Value; + } + + if (us?.SuperView is null) + { + return 0; + } + + AlignAndUpdateGroup (GroupId, us.SuperView.Subviews, dimension, superviewDimension); + + if (_cachedLocation.HasValue) + { + return _cachedLocation.Value; + } + + return 0; + } + + internal override int GetAnchor (int width) { return _cachedLocation ?? 0 - width; } + /// /// Aligns the views in that have the same group ID as . /// Updates each view's cached _location. @@ -71,30 +146,30 @@ public record PosAlign : Pos // PERF: If this proves a perf issue, consider caching a ref to this list in each item List posAligns = views.Select ( - v => - { - switch (dimension) - { - case Dimension.Width when v.X.Has (typeof (PosAlign), out var pos): + v => + { + switch (dimension) + { + case Dimension.Width when v.X.Has (typeof (PosAlign), out Pos pos): - if (pos is PosAlign posAlignX && posAlignX.GroupId == groupId) - { - return posAlignX; - } + if (pos is PosAlign posAlignX && posAlignX.GroupId == groupId) + { + return posAlignX; + } - break; - case Dimension.Height when v.Y.Has (typeof (PosAlign), out var pos): - if (pos is PosAlign posAlignY && posAlignY.GroupId == groupId) - { - return posAlignY; - } + break; + case Dimension.Height when v.Y.Has (typeof (PosAlign), out Pos pos): + if (pos is PosAlign posAlignY && posAlignY.GroupId == groupId) + { + return posAlignY; + } - break; - } + break; + } - return null; - }) - .ToList (); + return null; + }) + .ToList (); // PERF: We iterate over viewsInGroup multiple times here. @@ -136,80 +211,4 @@ public record PosAlign : Pos } private void Aligner_PropertyChanged (object? sender, PropertyChangedEventArgs e) { _cachedLocation = null; } - - /// - public override string ToString () { return $"Align(alignment={Aligner.Alignment},modes={Aligner.AlignmentModes},groupId={GroupId})"; } - - internal override int GetAnchor (int width) { return _cachedLocation ?? 0 - width; } - - internal override int Calculate (int superviewDimension, Dim dim, View us, Dimension dimension) - { - if (_cachedLocation.HasValue && Aligner.ContainerSize == superviewDimension) - { - return _cachedLocation.Value; - } - - if (us?.SuperView is null) - { - return 0; - } - - AlignAndUpdateGroup (GroupId, us.SuperView.Subviews, dimension, superviewDimension); - - if (_cachedLocation.HasValue) - { - return _cachedLocation.Value; - } - - return 0; - } - - // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. - /// - /// Returns the minimum size a group of views with the same can be. - /// - /// - /// - /// - /// - public static int CalculateMinDimension (int groupId, IList views, Dimension dimension) - { - List dimensionsList = new (); - - // PERF: If this proves a perf issue, consider caching a ref to this list in each item - List viewsInGroup = views.Where ( - v => - { - return dimension switch - { - Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, - Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, - _ => false - }; - }) - .ToList (); - - if (viewsInGroup.Count == 0) - { - return 0; - } - - // PERF: We iterate over viewsInGroup multiple times here. - - // Update the dimensionList with the sizes of the views - for (var index = 0; index < viewsInGroup.Count; index++) - { - View view = viewsInGroup [index]; - - PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign; - - if (posAlign is { }) - { - dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height); - } - } - - // Align - return dimensionsList.Sum (); - } } diff --git a/Terminal.Gui/View/Layout/PosCombine.cs b/Terminal.Gui/View/Layout/PosCombine.cs index 63ae05dde..884bb2704 100644 --- a/Terminal.Gui/View/Layout/PosCombine.cs +++ b/Terminal.Gui/View/Layout/PosCombine.cs @@ -10,27 +10,27 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// +/// /// Indicates whether the two positions are added or subtracted. /// -/// The left position. -/// The right position. -public record PosCombine (AddOrSubtract add, Pos left, Pos right) : Pos +/// The left position. +/// The right position. +public record PosCombine (AddOrSubtract Add, Pos Left, Pos Right) : Pos { /// /// Gets whether the two positions are added or subtracted. /// - public AddOrSubtract Add { get; } = add; + public AddOrSubtract Add { get; } = Add; /// /// Gets the left position. /// - public new Pos Left { get; } = left; + public new Pos Left { get; } = Left; /// /// Gets the right position. /// - public new Pos Right { get; } = right; + public new Pos Right { get; } = Right; /// public override string ToString () { return $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})"; } diff --git a/Terminal.Gui/View/Layout/PosFunc.cs b/Terminal.Gui/View/Layout/PosFunc.cs index a46367f34..4b06d180c 100644 --- a/Terminal.Gui/View/Layout/PosFunc.cs +++ b/Terminal.Gui/View/Layout/PosFunc.cs @@ -7,16 +7,16 @@ namespace Terminal.Gui; /// /// /// This is a low-level API that is typically used internally by the layout system. Use the various static -/// methods on the class to create objects instead. +/// methods on the class to create objects instead. /// /// -/// The position. -public record PosFunc (Func pos) : Pos +/// The position. +public record PosFunc (Func Pos) : Pos { /// /// Gets the function that computes the position. /// - public new Func Func { get; } = pos; + public new Func Func { get; } = Pos; /// public override string ToString () { return $"PosFunc({Func ()})"; } diff --git a/Terminal.Gui/View/Layout/PosPercent.cs b/Terminal.Gui/View/Layout/PosPercent.cs index d38b503fe..17b99cb69 100644 --- a/Terminal.Gui/View/Layout/PosPercent.cs +++ b/Terminal.Gui/View/Layout/PosPercent.cs @@ -10,13 +10,13 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// -public record PosPercent (int percent) : Pos +/// +public record PosPercent (int Percent) : Pos { /// /// Gets the percentage of the width or height of the SuperView. /// - public new int Percent { get; } = percent; + public new int Percent { get; } = Percent; /// public override string ToString () { return $"Percent({Percent})"; } diff --git a/Terminal.Gui/View/Layout/PosView.cs b/Terminal.Gui/View/Layout/PosView.cs index 13e2981ec..92748d88b 100644 --- a/Terminal.Gui/View/Layout/PosView.cs +++ b/Terminal.Gui/View/Layout/PosView.cs @@ -10,19 +10,19 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// The View the position is anchored to. -/// The side of the View the position is anchored to. -public record PosView (View? view, Side side) : Pos +/// The View the position is anchored to. +/// The side of the View the position is anchored to. +public record PosView (View? View, Side Side) : Pos { /// /// Gets the View the position is anchored to. /// - public View? Target { get; } = view; + public View? Target { get; } = View; /// /// Gets the side of the View the position is anchored to. /// - public Side Side { get; } = side; + public Side Side { get; } = Side; /// public override string ToString () From 34b33e1ca46270f3f0f1d7185bacda8a84cec95f Mon Sep 17 00:00:00 2001 From: Tig Date: Sun, 18 Aug 2024 17:27:20 -0600 Subject: [PATCH 07/16] Addressed review feedback --- Terminal.Gui/View/Layout/DimFill.cs | 5 ----- Terminal.Gui/View/Layout/DimFunc.cs | 13 +++++-------- Terminal.Gui/View/Layout/DimPercent.cs | 13 ++++--------- Terminal.Gui/View/Layout/PosFunc.cs | 19 ++++--------------- 4 files changed, 13 insertions(+), 37 deletions(-) diff --git a/Terminal.Gui/View/Layout/DimFill.cs b/Terminal.Gui/View/Layout/DimFill.cs index 27caa6aba..7550b87db 100644 --- a/Terminal.Gui/View/Layout/DimFill.cs +++ b/Terminal.Gui/View/Layout/DimFill.cs @@ -11,11 +11,6 @@ namespace Terminal.Gui; /// The margin to not fill. public record DimFill (int Margin) : Dim { - /// - /// Gets the margin to not fill. - /// - public int Margin { get; } = Margin; - /// public override string ToString () { return $"Fill({Margin})"; } diff --git a/Terminal.Gui/View/Layout/DimFunc.cs b/Terminal.Gui/View/Layout/DimFunc.cs index 8e110d8cd..c51406f40 100644 --- a/Terminal.Gui/View/Layout/DimFunc.cs +++ b/Terminal.Gui/View/Layout/DimFunc.cs @@ -8,19 +8,16 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// -public record DimFunc (Func Dim) : Dim +/// The function that computes the dimension. +public record DimFunc (Func Fn) : Dim { /// /// Gets the function that computes the dimension. /// - public new Func Func { get; } = Dim; + public Func Fn { get; } = Fn; /// - public override int GetHashCode () { return Func.GetHashCode (); } + public override string ToString () { return $"DimFunc({Fn ()})"; } - /// - public override string ToString () { return $"DimFunc({Func ()})"; } - - internal override int GetAnchor (int size) { return Func (); } + internal override int GetAnchor (int size) { return Fn (); } } \ No newline at end of file diff --git a/Terminal.Gui/View/Layout/DimPercent.cs b/Terminal.Gui/View/Layout/DimPercent.cs index e62e4500d..e94be76a7 100644 --- a/Terminal.Gui/View/Layout/DimPercent.cs +++ b/Terminal.Gui/View/Layout/DimPercent.cs @@ -8,29 +8,24 @@ namespace Terminal.Gui; /// This is a low-level API that is typically used internally by the layout system. Use the various static /// methods on the class to create objects instead. /// -/// The percentage. +/// The percentage. /// /// If the dimension is computed using the View's position ( or /// ); otherwise, the dimension is computed using the View's . /// -public record DimPercent (int Percent, DimPercentMode Mode = DimPercentMode.ContentSize) : Dim +public record DimPercent (int Percentage, DimPercentMode Mode = DimPercentMode.ContentSize) : Dim { - /// - /// Gets the percentage. - /// - public new int Percent { get; } = Percent; - /// /// /// - public override string ToString () { return $"Percent({Percent},{Mode})"; } + public override string ToString () { return $"Percent({Percentage},{Mode})"; } /// /// Gets whether the dimension is computed using the View's position or GetContentSize (). /// public DimPercentMode Mode { get; } = Mode; - internal override int GetAnchor (int size) { return (int)(size * (Percent / 100f)); } + internal override int GetAnchor (int size) { return (int)(size * (Percentage / 100f)); } internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension) { diff --git a/Terminal.Gui/View/Layout/PosFunc.cs b/Terminal.Gui/View/Layout/PosFunc.cs index 4b06d180c..c449add14 100644 --- a/Terminal.Gui/View/Layout/PosFunc.cs +++ b/Terminal.Gui/View/Layout/PosFunc.cs @@ -4,22 +4,11 @@ namespace Terminal.Gui; /// /// Represents a position that is computed by executing a function that returns an integer position. /// -/// -/// -/// This is a low-level API that is typically used internally by the layout system. Use the various static -/// methods on the class to create objects instead. -/// -/// -/// The position. -public record PosFunc (Func Pos) : Pos +/// The function that computes the position. +public record PosFunc (Func Fn) : Pos { - /// - /// Gets the function that computes the position. - /// - public new Func Func { get; } = Pos; - /// - public override string ToString () { return $"PosFunc({Func ()})"; } + public override string ToString () { return $"PosFunc({Fn ()})"; } - internal override int GetAnchor (int size) { return Func (); } + internal override int GetAnchor (int size) { return Fn (); } } \ No newline at end of file From e90a115f2155a0344b391f5f5ffd10f2125c73b0 Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 17:37:05 -0700 Subject: [PATCH 08/16] Declare IEqualityOperators for Dim --- Terminal.Gui/View/Layout/Dim.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 45899dd78..da46f2b72 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -1,8 +1,8 @@ #nullable enable -using System.Diagnostics; - namespace Terminal.Gui; +using System.Numerics; + /// /// /// A Dim object describes the dimensions of a . Dim is the type of the @@ -78,7 +78,7 @@ namespace Terminal.Gui; /// /// /// -public abstract record Dim +public abstract record Dim : IEqualityOperators { #region static Dim creation methods From 730d8e31032fbc685e680d6ff2be61fb19fbf4b4 Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 17:38:56 -0700 Subject: [PATCH 09/16] Add a generic form of Dim.Has --- Terminal.Gui/View/Layout/Dim.cs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index da46f2b72..a964bb2e1 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -196,6 +196,29 @@ public abstract record Dim : IEqualityOperators return false; } + /// + /// Indicates whether the specified type is in the hierarchy of this Dim object. + /// + /// A reference to this instance. + /// + public bool Has (out Dim dim) where T : Dim + { + dim = this; + + return this switch + { + T => true, + + // INTENT: Is it intentional that, when T is already DimCombine, this won't get called? + // If not, the fix is to do this one first. + // (That's also the case in the original) + // If we are a DimCombine, we have to check the left and right + // to see if they are of the type we are looking for. + DimCombine combine => combine.Left.Has (out dim) || combine.Right.Has (out dim), + _ => false + }; + } + #region virtual methods /// From 4e2416f6de89b377d949cb19b78a21c0c4a6c662 Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 17:39:18 -0700 Subject: [PATCH 10/16] Mark non-generic Dim.Has obsolete and fix a comment --- Terminal.Gui/View/Layout/Dim.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index a964bb2e1..503bf8416 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -178,15 +178,17 @@ public abstract record Dim : IEqualityOperators /// /// /// + [Obsolete ("Not AoT-safe. Use generic form Has instead.")] public bool Has (Type type, out Dim dim) { dim = this; + if (type == GetType ()) { return true; } - // If we are a PosCombine, we have to check the left and right + // If we are a DimCombine, we have to check the left and right // to see if they are of the type we are looking for. if (this is DimCombine { } combine && (combine.Left.Has (type, out dim) || combine.Right.Has (type, out dim))) { From 8385153590d4427ec319f9a1646d83ab0a8bf5ed Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 18:16:33 -0700 Subject: [PATCH 11/16] Make GetAnchor abstract There are subtle reasons for this. Regardless, it will be abstract when it's an interface, anyway, so no harm in doing it now. --- Terminal.Gui/View/Layout/Dim.cs | 2 +- Terminal.Gui/View/Layout/DimAuto.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 503bf8416..9dfd175cc 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -233,7 +233,7 @@ public abstract record Dim : IEqualityOperators /// subclass of Dim that is used. For example, DimAbsolute returns a fixed dimension, DimFactor returns a /// dimension that is a certain percentage of the super view's size, and so on. /// - internal virtual int GetAnchor (int size) { return 0; } + internal abstract int GetAnchor (int size); /// /// Calculates and returns the dimension of a object. It takes into account the location of the diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 408d3c74b..01409f38a 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -59,6 +59,9 @@ public record DimAuto : Dim /// public override string ToString () { return $"Auto({Style},{MinimumContentDim},{MaximumContentDim})"; } + /// + internal override int GetAnchor (int size) => 0; + internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension) { var textSize = 0; From 9082d13e303c1ccf879d8ac0953260a513124f7e Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 18:18:03 -0700 Subject: [PATCH 12/16] Clamping to maximum size of the buffer Just an extra sanity check/guard --- Terminal.Gui/View/Layout/Dim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 9dfd175cc..1fa04efd9 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -253,7 +253,7 @@ public abstract record Dim : IEqualityOperators /// internal virtual int Calculate (int location, int superviewContentSize, View us, Dimension dimension) { - return Math.Max (GetAnchor (superviewContentSize - location), 0); + return Math.Clamp (GetAnchor (superviewContentSize - location), 0, short.MaxValue); } /// From e6b67f0fbf2ce785d3346f453aaff173f4b53657 Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 18:19:17 -0700 Subject: [PATCH 13/16] Reduce code by inlining these in a primary constructor Not the final form. Just showing steps. --- Terminal.Gui/View/Layout/DimAuto.cs | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 01409f38a..9bf5f00a8 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -15,46 +15,28 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -public record DimAuto : Dim +public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoStyle Style) : Dim { - private readonly Dim? _maximumContentDim; - /// /// Gets the maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED. /// // ReSharper disable once ConvertToAutoProperty - public required Dim? MaximumContentDim - { - get => _maximumContentDim; - init => _maximumContentDim = value; - } - - private readonly Dim? _minimumContentDim; + public required Dim? MaximumContentDim { get; init; } = MaximumContentDim; /// /// Gets the minimum dimension the View's ContentSize will be constrained to. /// // ReSharper disable once ConvertToAutoProperty - public required Dim? MinimumContentDim - { - get => _minimumContentDim; - init => _minimumContentDim = value; - } - - private readonly DimAutoStyle _style; + public required Dim? MinimumContentDim { get; init; } = MinimumContentDim; /// /// Gets the style of the DimAuto. /// // ReSharper disable once ConvertToAutoProperty - public required DimAutoStyle Style - { - get => _style; - init => _style = value; - } + public required DimAutoStyle Style { get; init; } = Style; /// public override string ToString () { return $"Auto({Style},{MinimumContentDim},{MaximumContentDim})"; } From 219cfb559a768d4f3ff0605593063af9f2549a06 Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 18:23:03 -0700 Subject: [PATCH 14/16] More code reduction. Put these in a primary constructor. Update uses. --- Terminal.Gui/View/Layout/Dim.cs | 10 ++--- Terminal.Gui/View/Layout/DimAuto.cs | 24 ++--------- UnitTests/View/Layout/Dim.AutoTests.cs | 57 ++++++++++++-------------- 3 files changed, 33 insertions(+), 58 deletions(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 1fa04efd9..979d83fff 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -113,12 +113,10 @@ public abstract record Dim : IEqualityOperators /// The maximum dimension the View's ContentSize will be fit to. public static Dim? Auto (DimAutoStyle style = DimAutoStyle.Auto, Dim? minimumContentDim = null, Dim? maximumContentDim = null) { - return new DimAuto () - { - MinimumContentDim = minimumContentDim, - MaximumContentDim = maximumContentDim, - Style = style - }; + return new DimAuto ( + MinimumContentDim: minimumContentDim, + MaximumContentDim: maximumContentDim, + Style: style); } /// diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 9bf5f00a8..b8b53505f 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -15,29 +15,11 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// +/// The maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED. +/// The minimum dimension the View's ContentSize will be constrained to. +/// The of the . public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoStyle Style) : Dim { - /// - /// Gets the maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED. - /// - - // ReSharper disable once ConvertToAutoProperty - public required Dim? MaximumContentDim { get; init; } = MaximumContentDim; - - /// - /// Gets the minimum dimension the View's ContentSize will be constrained to. - /// - - // ReSharper disable once ConvertToAutoProperty - public required Dim? MinimumContentDim { get; init; } = MinimumContentDim; - - /// - /// Gets the style of the DimAuto. - /// - - // ReSharper disable once ConvertToAutoProperty - public required DimAutoStyle Style { get; init; } = Style; - /// public override string ToString () { return $"Auto({Style},{MinimumContentDim},{MaximumContentDim})"; } diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index e1a742d8a..b979d1a4c 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using Xunit.Abstractions; using static Terminal.Gui.Dim; @@ -203,40 +203,35 @@ public partial class DimAutoTests (ITestOutputHelper output) [Fact] public void TestEquality () { - var a = new DimAuto - { - MaximumContentDim = null, - MinimumContentDim = 1, - Style = DimAutoStyle.Auto - }; + var a = new DimAuto ( + MaximumContentDim: null, + MinimumContentDim: 1, + Style: DimAutoStyle.Auto + ); - var b = new DimAuto - { - MaximumContentDim = null, - MinimumContentDim = 1, - Style = DimAutoStyle.Auto - }; + var b = new DimAuto ( + MaximumContentDim: null, + MinimumContentDim: 1, + Style: DimAutoStyle.Auto + ); - var c = new DimAuto - { - MaximumContentDim = 2, - MinimumContentDim = 1, - Style = DimAutoStyle.Auto - }; + var c = new DimAuto( + MaximumContentDim: 2, + MinimumContentDim: 1, + Style: DimAutoStyle.Auto + ); - var d = new DimAuto - { - MaximumContentDim = null, - MinimumContentDim = 1, - Style = DimAutoStyle.Content - }; + var d = new DimAuto ( + MaximumContentDim: null, + MinimumContentDim: 1, + Style: DimAutoStyle.Content + ); - var e = new DimAuto - { - MaximumContentDim = null, - MinimumContentDim = 2, - Style = DimAutoStyle.Auto - }; + var e = new DimAuto ( + MaximumContentDim: null, + MinimumContentDim: 2, + Style: DimAutoStyle.Auto + ); // Test equality with same values Assert.True (a.Equals (b)); From dccc06366a66cb661ea164c4786225f0637e24b4 Mon Sep 17 00:00:00 2001 From: Brandon Thetford Date: Sun, 18 Aug 2024 18:31:23 -0700 Subject: [PATCH 15/16] Categorize the test fixture --- UnitTests/View/Layout/Dim.AutoTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index b979d1a4c..5f6767310 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -1,9 +1,10 @@ -using System.Text; +using System.Text; using Xunit.Abstractions; using static Terminal.Gui.Dim; namespace Terminal.Gui.LayoutTests; +[Trait("Category", "Layout")] public partial class DimAutoTests (ITestOutputHelper output) { private readonly ITestOutputHelper _output = output; From bb85f9099a928def3d1d4ecc747127772cd8c481 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 19 Aug 2024 08:21:09 -0600 Subject: [PATCH 16/16] Accepted changed --- Terminal.Gui/View/Layout/Dim.cs | 35 ++--------------------------- Terminal.Gui/View/Layout/DimAuto.cs | 14 ++++++------ Terminal.Gui/View/Layout/PosFunc.cs | 2 +- Terminal.Gui/View/View.Layout.cs | 4 ++-- 4 files changed, 12 insertions(+), 43 deletions(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 979d83fff..cfb286b6c 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -170,31 +170,6 @@ public abstract record Dim : IEqualityOperators #endregion static Dim creation methods - /// - /// Indicates whether the specified type is in the hierarchy of this Dim object. - /// - /// - /// - /// - [Obsolete ("Not AoT-safe. Use generic form Has instead.")] - public bool Has (Type type, out Dim dim) - { - dim = this; - - if (type == GetType ()) - { - return true; - } - - // If we are a DimCombine, we have to check the left and right - // to see if they are of the type we are looking for. - if (this is DimCombine { } combine && (combine.Left.Has (type, out dim) || combine.Right.Has (type, out dim))) - { - return true; - } - - return false; - } /// /// Indicates whether the specified type is in the hierarchy of this Dim object. @@ -207,15 +182,9 @@ public abstract record Dim : IEqualityOperators return this switch { - T => true, - - // INTENT: Is it intentional that, when T is already DimCombine, this won't get called? - // If not, the fix is to do this one first. - // (That's also the case in the original) - // If we are a DimCombine, we have to check the left and right - // to see if they are of the type we are looking for. DimCombine combine => combine.Left.Has (out dim) || combine.Right.Has (out dim), - _ => false + T => true, + _ => false }; } diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index b8b53505f..e552d1028 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -15,7 +15,7 @@ namespace Terminal.Gui; /// methods on the class to create objects instead. /// /// -/// The maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED. +/// The maximum dimension the View's ContentSize will be fit to. /// The minimum dimension the View's ContentSize will be constrained to. /// The of the . public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoStyle Style) : Dim @@ -134,8 +134,8 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt && !v.X.Has (typeof (PosAnchorEnd), out _) && !v.X.Has (typeof (PosAlign), out _) && !v.X.Has (typeof (PosCenter), out _) - && !v.Width.Has (typeof (DimFill), out _) - && !v.Width.Has (typeof (DimPercent), out _) + && !v.Width.Has (out _) + && !v.Width.Has (out _) ) .ToList (); } @@ -147,8 +147,8 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt && !v.Y.Has (typeof (PosAnchorEnd), out _) && !v.Y.Has (typeof (PosAlign), out _) && !v.Y.Has (typeof (PosCenter), out _) - && !v.Height.Has (typeof (DimFill), out _) - && !v.Height.Has (typeof (DimPercent), out _) + && !v.Height.Has (out _) + && !v.Height.Has (out _) ) .ToList (); } @@ -372,11 +372,11 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt if (dimension == Dimension.Width) { - dimViewSubViews = includedSubviews.Where (v => v.Width is { } && v.Width.Has (typeof (DimView), out _)).ToList (); + dimViewSubViews = includedSubviews.Where (v => v.Width is { } && v.Width.Has (out _)).ToList (); } else { - dimViewSubViews = includedSubviews.Where (v => v.Height is { } && v.Height.Has (typeof (DimView), out _)).ToList (); + dimViewSubViews = includedSubviews.Where (v => v.Height is { } && v.Height.Has (out _)).ToList (); } for (var i = 0; i < dimViewSubViews.Count; i++) diff --git a/Terminal.Gui/View/Layout/PosFunc.cs b/Terminal.Gui/View/Layout/PosFunc.cs index c449add14..0bd819ad5 100644 --- a/Terminal.Gui/View/Layout/PosFunc.cs +++ b/Terminal.Gui/View/Layout/PosFunc.cs @@ -4,7 +4,7 @@ namespace Terminal.Gui; /// /// Represents a position that is computed by executing a function that returns an integer position. /// -/// The function that computes the position. +/// The function that computes the position. public record PosFunc (Func Fn) : Pos { /// diff --git a/Terminal.Gui/View/View.Layout.cs b/Terminal.Gui/View/View.Layout.cs index 54554eae1..d77ceba2b 100644 --- a/Terminal.Gui/View/View.Layout.cs +++ b/Terminal.Gui/View/View.Layout.cs @@ -474,7 +474,7 @@ public partial class View // Layout APIs return; } - if (_height is { } && _height.Has (typeof (DimAuto), out _)) + if (_height is { } && _height.Has (out _)) { // Reset ContentSize to Viewport _contentSize = null; @@ -523,7 +523,7 @@ public partial class View // Layout APIs return; } - if (_width is { } && _width.Has (typeof (DimAuto), out _)) + if (_width is { } && _width.Has (out _)) { // Reset ContentSize to Viewport _contentSize = null;