diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 9a8612542..1ea820ee0 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -180,9 +180,7 @@ public class DimAuto : Dim && (v.X is PosAbsolute or PosFunc || v.Width is DimAuto or DimAbsolute or DimFunc) && !v.X.Has (typeof (PosAnchorEnd), out _) && !v.X.Has (typeof (PosAlign), out _) - && !v.X.Has (typeof (PosView), out _) && !v.X.Has (typeof (PosCenter), out _) - && !v.Width.Has (typeof (DimView), out _) && !v.Width.Has (typeof (DimFill), out _) && !v.Width.Has (typeof (DimPercent), out _) ) @@ -195,9 +193,7 @@ public class DimAuto : Dim && (v.Y is PosAbsolute or PosFunc || v.Height is DimAuto or DimAbsolute or DimFunc) && !v.Y.Has (typeof (PosAnchorEnd), out _) && !v.Y.Has (typeof (PosAlign), out _) - && !v.Y.Has (typeof (PosView), out _) && !v.Y.Has (typeof (PosCenter), out _) - && !v.Height.Has (typeof (DimView), out _) && !v.Height.Has (typeof (DimFill), out _) && !v.Height.Has (typeof (DimPercent), out _) ) @@ -218,7 +214,7 @@ public class DimAuto : Dim else { int height = v.Height!.Calculate (0, superviewContentSize, v, dimension); - size = v.Y.GetAnchor (0) + height; + size = v.Y!.GetAnchor (0) + height; } if (size > maxCalculatedSize) @@ -310,13 +306,13 @@ public class DimAuto : Dim 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 - }; + { + Dimension.Width when v.X is PosAlign alignX => alignX.GroupId + == groupId, + Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId + == groupId, + _ => false + }; }) .Select (v => dimension == Dimension.Width ? v.X as PosAlign : v.Y as PosAlign) .ToList (); @@ -470,12 +466,12 @@ public class DimAuto : Dim Thickness thickness = us.GetAdornmentsThickness (); int adornmentThickness = dimension switch - { - Dimension.Width => thickness.Horizontal, - Dimension.Height => thickness.Vertical, - Dimension.None => 0, - _ => throw new ArgumentOutOfRangeException (nameof (dimension), dimension, null) - }; + { + Dimension.Width => thickness.Horizontal, + Dimension.Height => thickness.Vertical, + Dimension.None => 0, + _ => throw new ArgumentOutOfRangeException (nameof (dimension), dimension, null) + }; max += adornmentThickness; diff --git a/UICatalog/Scenarios/DimAutoDemo.cs b/UICatalog/Scenarios/DimAutoDemo.cs index 83f749199..9b8efbc48 100644 --- a/UICatalog/Scenarios/DimAutoDemo.cs +++ b/UICatalog/Scenarios/DimAutoDemo.cs @@ -163,6 +163,16 @@ public class DimAutoDemo : Scenario }; dimAutoFrameView.Add (resetButton); + + var radioGroup = new RadioGroup () + { + RadioLabels = ["One", "Two", "Three"], + X = 0, + Y = Pos.AnchorEnd (), + Title = "Radios", + BorderStyle = LineStyle.Dotted + }; + dimAutoFrameView.Add (radioGroup); return dimAutoFrameView; } diff --git a/UICatalog/Scenarios/MarginEditor.cs b/UICatalog/Scenarios/MarginEditor.cs index 5705a01f8..d764eff1d 100644 --- a/UICatalog/Scenarios/MarginEditor.cs +++ b/UICatalog/Scenarios/MarginEditor.cs @@ -28,9 +28,7 @@ public class MarginEditor : AdornmentEditor _rgShadow = new RadioGroup { X = 0, - //Y = Pos.AnchorEnd (), - // BUGBUG: Hack until Dim.Auto and Pos.AnchorEnd where this view's Dim is also Dim.Auto - Y = Pos.Bottom (Subviews [^1]), + Y = Pos.AnchorEnd (), SuperViewRendersLineCanvas = true, Title = "_Shadow", diff --git a/UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs b/UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs index c7f4bc980..0e7da8559 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs @@ -303,6 +303,239 @@ public partial class DimAutoTests Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y); } + + [Theory] + [InlineData (0, 0, 0, 0, 0, 0)] + [InlineData (0, 19, 0, 9, 19, 9)] + [InlineData (0, 18, 0, 8, 18, 8)] + [InlineData (0, 20, 0, 10, 20, 10)] + [InlineData (0, 21, 0, 11, 21, 11)] + [InlineData (1, 21, 1, 11, 21, 11)] + [InlineData (21, 21, 11, 11, 21, 11)] + [InlineData (0, 30, 0, 20, 25, 15)] + public void With_Subview_And_Subview_Using_PosAnchorEnd (int minWidth, int maxWidth, int minHeight, int maxHeight, int expectedWidth, int expectedHeight) + { + var view = new View + { + Width = Dim.Auto (minimumContentDim: minWidth, maximumContentDim: maxWidth), + Height = Dim.Auto (minimumContentDim: minHeight, maximumContentDim: maxHeight) + }; + + var otherView = new View + { + Width = 5, + Height = 5 + }; + view.Add (otherView); + + var subview = new View + { + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), + Width = 20, + Height = 10 + }; + view.Add (subview); + + // Assuming the calculation is done after layout + int calculatedX = view.X.Calculate (100, view.Width, view, Dimension.Width); + int calculatedY = view.Y.Calculate (100, view.Height, view, Dimension.Height); + int calculatedWidth = view.Width.Calculate (0, 100, view, Dimension.Width); + int calculatedHeight = view.Height.Calculate (0, 100, view, Dimension.Height); + + Assert.Equal (expectedWidth, calculatedWidth); + Assert.Equal (expectedHeight, calculatedHeight); + + Assert.Equal (0, calculatedX); + Assert.Equal (0, calculatedY); + + view.BeginInit (); + view.EndInit (); + + // subview should be at the end of the view + Assert.Equal (view.Viewport.Width - subview.Frame.Width, subview.Frame.X); + Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y); + } + + [Theory] + [InlineData (0, 0, 0, 0, 0, 0)] + [InlineData (0, 19, 0, 9, 19, 9)] + [InlineData (0, 18, 0, 8, 18, 8)] + [InlineData (0, 20, 0, 10, 20, 10)] + [InlineData (0, 21, 0, 11, 21, 11)] + [InlineData (1, 21, 1, 11, 21, 11)] + [InlineData (21, 21, 11, 11, 21, 11)] + [InlineData (0, 30, 0, 20, 25, 15)] + public void With_DimAutoSubview_And_Subview_Using_PosAnchorEnd (int minWidth, int maxWidth, int minHeight, int maxHeight, int expectedWidth, int expectedHeight) + { + var view = new View + { + Width = Dim.Auto (minimumContentDim: minWidth, maximumContentDim: maxWidth), + Height = Dim.Auto (minimumContentDim: minHeight, maximumContentDim: maxHeight) + }; + + var otherView = new View + { + Text = "01234\n01234\n01234\n01234\n01234", + Width = Dim.Auto(), + Height = Dim.Auto () + }; + view.Add (otherView); + + var subview = new View + { + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), + Width = 20, + Height = 10 + }; + view.Add (subview); + + // Assuming the calculation is done after layout + int calculatedX = view.X.Calculate (100, view.Width, view, Dimension.Width); + int calculatedY = view.Y.Calculate (100, view.Height, view, Dimension.Height); + int calculatedWidth = view.Width.Calculate (0, 100, view, Dimension.Width); + int calculatedHeight = view.Height.Calculate (0, 100, view, Dimension.Height); + + Assert.Equal (expectedWidth, calculatedWidth); + Assert.Equal (expectedHeight, calculatedHeight); + + Assert.Equal (0, calculatedX); + Assert.Equal (0, calculatedY); + + view.BeginInit (); + view.EndInit (); + + // subview should be at the end of the view + Assert.Equal (view.Viewport.Width - subview.Frame.Width, subview.Frame.X); + Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y); + } + + [Theory] + [InlineData (0, 0, 0, 0, 0, 0)] + [InlineData (0, 19, 0, 9, 19, 9)] + [InlineData (0, 18, 0, 8, 18, 8)] + [InlineData (0, 20, 0, 10, 20, 10)] + [InlineData (0, 21, 0, 11, 21, 11)] + [InlineData (1, 21, 1, 11, 21, 11)] + [InlineData (21, 21, 11, 11, 21, 11)] + [InlineData (0, 30, 0, 20, 26, 16)] + public void With_PosViewSubview_And_Subview_Using_PosAnchorEnd (int minWidth, int maxWidth, int minHeight, int maxHeight, int expectedWidth, int expectedHeight) + { + var view = new View + { + Width = Dim.Auto (minimumContentDim: minWidth, maximumContentDim: maxWidth), + Height = Dim.Auto (minimumContentDim: minHeight, maximumContentDim: maxHeight) + }; + + var otherView = new View + { + Width = 1, + Height = 1, + }; + view.Add (otherView); + + var posViewView = new View + { + X = Pos.Bottom(otherView), + Y = Pos.Right(otherView), + Width = 5, + Height = 5, + }; + view.Add (posViewView); + + var subview = new View + { + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), + Width = 20, + Height = 10 + }; + view.Add (subview); + + // Assuming the calculation is done after layout + int calculatedX = view.X.Calculate (100, view.Width, view, Dimension.Width); + int calculatedY = view.Y.Calculate (100, view.Height, view, Dimension.Height); + int calculatedWidth = view.Width.Calculate (0, 100, view, Dimension.Width); + int calculatedHeight = view.Height.Calculate (0, 100, view, Dimension.Height); + + Assert.Equal (expectedWidth, calculatedWidth); + Assert.Equal (expectedHeight, calculatedHeight); + + Assert.Equal (0, calculatedX); + Assert.Equal (0, calculatedY); + + view.BeginInit (); + view.EndInit (); + + // subview should be at the end of the view + Assert.Equal (view.Viewport.Width - subview.Frame.Width, subview.Frame.X); + Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y); + } + + + [Theory] + [InlineData (0, 0, 0, 0, 0, 0)] + [InlineData (0, 19, 0, 9, 19, 9)] + [InlineData (0, 18, 0, 8, 18, 8)] + [InlineData (0, 20, 0, 10, 20, 10)] + [InlineData (0, 21, 0, 11, 21, 11)] + [InlineData (1, 21, 1, 11, 21, 11)] + [InlineData (21, 21, 11, 11, 21, 11)] + [InlineData (0, 30, 0, 20, 22, 12)] + public void With_DimViewSubview_And_Subview_Using_PosAnchorEnd (int minWidth, int maxWidth, int minHeight, int maxHeight, int expectedWidth, int expectedHeight) + { + var view = new View + { + Width = Dim.Auto (minimumContentDim: minWidth, maximumContentDim: maxWidth), + Height = Dim.Auto (minimumContentDim: minHeight, maximumContentDim: maxHeight) + }; + + var otherView = new View + { + Width = 1, + Height = 1, + }; + view.Add (otherView); + + var dimViewView = new View + { + Id = "dimViewView", + X = 1, + Y = 1, + Width = Dim.Width (otherView), + Height = Dim.Height (otherView), + }; + view.Add (dimViewView); + + var subview = new View + { + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), + Width = 20, + Height = 10 + }; + view.Add (subview); + + // Assuming the calculation is done after layout + int calculatedX = view.X.Calculate (100, view.Width, view, Dimension.Width); + int calculatedY = view.Y.Calculate (100, view.Height, view, Dimension.Height); + int calculatedWidth = view.Width.Calculate (0, 100, view, Dimension.Width); + int calculatedHeight = view.Height.Calculate (0, 100, view, Dimension.Height); + + Assert.Equal (expectedWidth, calculatedWidth); + Assert.Equal (expectedHeight, calculatedHeight); + + Assert.Equal (0, calculatedX); + Assert.Equal (0, calculatedY); + + view.BeginInit (); + view.EndInit (); + + // subview should be at the end of the view + Assert.Equal (view.Viewport.Width - subview.Frame.Width, subview.Frame.X); + Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y); + } [Theory] [InlineData (0, 10, 0, 10, 10, 2)] [InlineData (0, 5, 0, 5, 5, 3)] // max width of 5 should cause wordwrap at 5 giving a height of 2 + 1