diff --git a/Terminal.Gui/ViewBase/Layout/DimAuto.cs b/Terminal.Gui/ViewBase/Layout/DimAuto.cs index 038b3b1448..bb1598bf75 100644 --- a/Terminal.Gui/ViewBase/Layout/DimAuto.cs +++ b/Terminal.Gui/ViewBase/Layout/DimAuto.cs @@ -58,7 +58,7 @@ private readonly struct ViewCategories /// Categorizes views in a single pass to reduce iterations and allocations. /// Phase 1 and 2 Performance Optimization. /// - private static ViewCategories CategorizeViews (IList subViews, Dimension dimension, int superviewContentSize) + private static ViewCategories CategorizeViews (IList subViews, Dimension dimension) { ViewCategories categories = new () { @@ -191,7 +191,11 @@ internal override int Calculate (int location, int superviewContentSize, View us if (us.TextFormatter.ConstrainToWidth is null) { - width = us.TextFormatter.FormatAndGetSize (new Size (us.Viewport.Width, screenX4)).Width; + // Use Viewport.Width if available; fall back to the max-based width when + // the view hasn't been laid out yet (Viewport.Width == 0) to avoid + // constraining the text to zero width which produces height = 0. + int constrainWidth = us.Viewport.Width > 0 ? us.Viewport.Width : width; + width = us.TextFormatter.FormatAndGetSize (new Size (constrainWidth, screenX4)).Width; } textSize = us.TextFormatter.FormatAndGetSize (new Size (us.TextFormatter.ConstrainToWidth ?? width, screenX4)).Height; @@ -219,7 +223,7 @@ internal override int Calculate (int location, int superviewContentSize, View us // Work directly with the collection to avoid unnecessary ToList() allocation // Categorize views in a single pass - ViewCategories categories = CategorizeViews (us.InternalSubViews, dimension, superviewContentSize); + ViewCategories categories = CategorizeViews (us.InternalSubViews, dimension); // Process not-dependent views foreach (View notDependentSubView in categories.NotDependent) diff --git a/Terminal.Gui/ViewBase/View.Content.cs b/Terminal.Gui/ViewBase/View.Content.cs index 18f9ffacc8..c0d1e4d633 100644 --- a/Terminal.Gui/ViewBase/View.Content.cs +++ b/Terminal.Gui/ViewBase/View.Content.cs @@ -99,7 +99,31 @@ public int GetWidthRequiredForSubViews () => // DimAuto.Calculate adds the Adornments thickness, so we need to subtract it here since // we want the content size only. - Dim.Auto ().Calculate (0, GetContainerSize ().Width, this, Dimension.Width) - GetAdornmentsThickness ().Horizontal; + GetAutoWidth () - GetAdornmentsThickness ().Horizontal; + + /// + /// Gets the natural (auto-size) width of the view as calculated by . + /// + /// + /// The returned width is the full auto-calculated width for the view, including adornment thickness. + /// Unlike , this value is not content-only. + /// The calculation may also respect minimum and maximum content constraints applied by the auto dimension logic + /// before adornments are added. + /// + /// + public int GetAutoWidth () => Dim.Auto ().Calculate (0, GetContainerSize ().Width, this, Dimension.Width); + + /// + /// Gets the natural (auto-size) height of the view as calculated by . + /// + /// + /// The returned height is the full auto-calculated height for the view, including adornment thickness. + /// Unlike , this value is not content-only. + /// The calculation may also respect minimum and maximum content constraints applied by the auto dimension logic + /// before adornments are added. + /// + /// + public int GetAutoHeight () => Dim.Auto ().Calculate (0, GetContainerSize ().Height, this, Dimension.Height); /// /// Gets the minimum number of rows required for all the View's SubViews to fit in the content area. @@ -109,7 +133,7 @@ public int GetHeightRequiredForSubViews () => // DimAuto.Calculate adds the Adornments thickness, so we need to subtract it here since // we want the content size only. - Dim.Auto ().Calculate (0, GetContainerSize ().Height, this, Dimension.Height) - GetAdornmentsThickness ().Vertical; + GetAutoHeight () - GetAdornmentsThickness ().Vertical; /// /// Gets or sets a value indicating whether the view's content size tracks the 's @@ -243,22 +267,6 @@ public Point ContentToScreen (in Point location) return ViewportToScreen (contentRelativeToViewport); } - /// Converts a Screen-relative coordinate to a Content-relative coordinate. - /// - /// Content-relative means relative to the top-left corner of the view's Content, which is - /// always at 0, 0. - /// - /// The Screen-relative location. - /// The coordinate relative to this view's Content. - public Point ScreenToContent (in Point location) - { - Point viewportOffset = GetViewportOffsetFromFrame (); - Point screen = ScreenToFrame (location); - screen.Offset (Viewport.X - viewportOffset.X, Viewport.Y - viewportOffset.Y); - - return screen; - } - #endregion Content Area #region Viewport diff --git a/Terminal.Gui/Views/Color/AttributePicker.cs b/Terminal.Gui/Views/Color/AttributePicker.cs index 9337eb0528..02a60a1c31 100644 --- a/Terminal.Gui/Views/Color/AttributePicker.cs +++ b/Terminal.Gui/Views/Color/AttributePicker.cs @@ -1,7 +1,3 @@ -// Claude - Opus 4.5 - -using System.Diagnostics; - namespace Terminal.Gui.Views; /// @@ -35,7 +31,6 @@ public Attribute? Value out _); } - /// /// Raised when is about to change. /// Set to to cancel the change. @@ -47,7 +42,7 @@ public Attribute? Value /// public event EventHandler>? ValueChanged; - /// + /// public event EventHandler>? ValueChangedUntyped; private ColorPicker? _foregroundPicker; @@ -65,11 +60,12 @@ public string SampleText get => _sampleText; set { - if (_sampleText != value) + if (_sampleText == value) { - _sampleText = value; - UpdateSampleLabel (); + return; } + _sampleText = value; + UpdateSampleLabel (); } } @@ -81,26 +77,19 @@ public AttributePicker () CanFocus = true; TabStop = TabBehavior.TabStop; Height = Dim.Auto (); - Width = Dim.Fill (0, minimumContentDim: 64); + Width = Dim.Fill (0, 64); CommandsToBubbleUp = [Command.Accept]; SetupSubViews (); } private void SetupSubViews () { - ColorPickerStyle colorPickerStyle = new () - { - ShowTextFields = true, - ShowColorName = true - }; + ColorPickerStyle colorPickerStyle = new () { ShowTextFields = true, ShowColorName = true }; // Create foreground picker - offset X = -1 for border auto-joining with parent _foregroundPicker = new ColorPicker { - Title = "Foreground", - BorderStyle = LineStyle.Single, - SuperViewRendersLineCanvas = true, - Style = colorPickerStyle, + Title = "Foreground", BorderStyle = LineStyle.Single, SuperViewRendersLineCanvas = true, Style = colorPickerStyle }; _foregroundPicker.ValueChanged += OnForegroundColorChanged; _foregroundPicker.ApplyStyleChanges (); @@ -130,7 +119,7 @@ private void SetupSubViews () Width = Dim.Auto (), Height = Dim.Height (_foregroundPicker) + Dim.Height (_backgroundPicker) - 1 }; - _styleSelector.Width = _styleSelector.GetWidthRequiredForSubViews () + _styleSelector.GetAdornmentsThickness ().Horizontal; + _styleSelector.Width = _styleSelector.GetAutoWidth (); _styleSelector.ValueChanged += OnStyleChanged; // Set color picker widths relative to style selector @@ -155,16 +144,6 @@ private void SetupSubViews () UpdateSampleLabel (); } - /// - /// Performs the work after value change is confirmed (sync subviews, update sample). - /// - private void DoValueChanged (Attribute? newValue) - { - _value = newValue; - SyncSubViewsToValue (); - UpdateSampleLabel (); - } - /// /// Called before changes. Return to cancel the change. /// @@ -173,7 +152,8 @@ private void DoValueChanged (Attribute? newValue) /// /// Called after has changed. /// - protected virtual void OnValueChanged (ValueChangedEventArgs args) => ValueChangedUntyped?.Invoke (this, new ValueChangedEventArgs (args.OldValue, args.NewValue)); + protected virtual void OnValueChanged (ValueChangedEventArgs args) => + ValueChangedUntyped?.Invoke (this, new ValueChangedEventArgs (args.OldValue, args.NewValue)); private void OnForegroundColorChanged (object? sender, ValueChangedEventArgs e) => UpdateValueFromSubViews (); diff --git a/Tests/UnitTestsParallelizable/ViewBase/Layout/Dim.AutoTests.cs b/Tests/UnitTestsParallelizable/ViewBase/Layout/Dim.AutoTests.cs index ab7c44318a..4b31d0057c 100644 --- a/Tests/UnitTestsParallelizable/ViewBase/Layout/Dim.AutoTests.cs +++ b/Tests/UnitTestsParallelizable/ViewBase/Layout/Dim.AutoTests.cs @@ -11,29 +11,24 @@ public partial class DimAutoTests (ITestOutputHelper output) [Fact] public void Change_To_Non_Auto_Resets_ContentSize () { - View view = new () - { - 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 ()); + View view = new () { Width = Auto (), Height = Auto (), Text = "01234" }; + view.SetRelativeLayout (new Size (100, 100)); + Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame); + Assert.Equal (new Size (5, 1), view.GetContentSize ()); // Change text to a longer string view.Text = "0123456789"; - view.Layout (new (100, 100)); - Assert.Equal (new (0, 0, 10, 1), view.Frame); - Assert.Equal (new (10, 1), view.GetContentSize ()); + view.Layout (new Size (100, 100)); + Assert.Equal (new Rectangle (0, 0, 10, 1), view.Frame); + Assert.Equal (new Size (10, 1), view.GetContentSize ()); // If ContentSize was reset, these should cause it to update view.Width = 5; view.Height = 1; - view.SetRelativeLayout (new (100, 100)); - Assert.Equal (new (5, 1), view.GetContentSize ()); + view.SetRelativeLayout (new Size (100, 100)); + Assert.Equal (new Size (5, 1), view.GetContentSize ()); } [Theory] @@ -73,26 +68,20 @@ public void Height_Auto_Width_Absolute_NotChanged (int subX, int subY, int subWi superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, 10, expectedHeight), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (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 - }; + View view = new () { HotKeySpecifier = (Rune)'_', Text = text, Width = Auto (), Height = 1 }; view.Layout (); Assert.Equal (4, view.TextFormatter.ConstrainToWidth); Assert.Equal (1, view.TextFormatter.ConstrainToHeight); - view = new () + view = new View { HotKeySpecifier = (Rune)'_', TextDirection = TextDirection.TopBottom_LeftRight, @@ -109,12 +98,7 @@ public void HotKey_TextFormatter_Height_Correct ([CombinatorialValues ("1234", " [CombinatorialData] public void HotKey_TextFormatter_Width_Correct ([CombinatorialValues ("1234", "_1234", "1_234", "____")] string text) { - View view = new () - { - Text = text, - Height = 1, - Width = Auto () - }; + View view = new () { Text = text, Height = 1, Width = Auto () }; view.Layout (); Assert.Equal (4, view.TextFormatter.ConstrainToWidth); Assert.Equal (1, view.TextFormatter.ConstrainToHeight); @@ -134,11 +118,11 @@ public void NoSubViews_Does_Nothing () superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, 0, 0), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, 0, 0), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame); } [Fact] @@ -156,11 +140,11 @@ public void NoSubViews_Does_Nothing_Vertical () superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, 0, 0), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, 0, 0), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (0, 0, 0, 0), superView.Frame); } [Theory] @@ -200,42 +184,22 @@ public void SubView_Changes_SuperView_Size (int subX, int subY, int subWidth, in superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, expectedWidth, expectedHeight), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (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 - ); - - 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 - ); + var a = new DimAuto (null, 1, DimAutoStyle.Auto); + + var b = new DimAuto (null, 1, DimAutoStyle.Auto); + + var c = new DimAuto (2, 1, DimAutoStyle.Auto); + + var d = new DimAuto (null, 1, DimAutoStyle.Content); + + var e = new DimAuto (null, 2, DimAutoStyle.Auto); // Test equality with same values Assert.True (a.Equals (b)); @@ -269,55 +233,36 @@ public void TestEquality_Simple () [Fact] public void TextFormatter_Settings_Change_View_Size () { - View view = new () - { - Text = "_1234", - Width = Auto () - }; + View view = new () { Text = "_1234", Width = Auto () }; view.Layout (); - Assert.Equal (new (4, 0), view.Frame.Size); + Assert.Equal (new Size (4, 0), view.Frame.Size); view.Height = 1; view.Layout (); - Assert.Equal (new (4, 1), view.Frame.Size); + Assert.Equal (new Size (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 = new View { Text = "_1234", Width = Auto (), Height = 1 }; view.Layout (); lastSize = view.Frame.Size; view.VerticalTextAlignment = Alignment.Center; Assert.Equal (lastSize, view.Frame.Size); - view = new () - { - Text = "_1234", - Width = Auto (), - Height = 1 - }; - view.SetRelativeLayout (new (100, 100)); + view = new View { Text = "_1234", Width = Auto (), Height = 1 }; + view.SetRelativeLayout (new Size (100, 100)); lastSize = view.Frame.Size; view.HotKeySpecifier = (Rune)'*'; - view.SetRelativeLayout (new (100, 100)); + view.SetRelativeLayout (new Size (100, 100)); Assert.NotEqual (lastSize, view.Frame.Size); - view = new () - { - Text = "_1234", - Width = Auto (), - Height = 1 - }; - view.SetRelativeLayout (new (100, 100)); + view = new View { Text = "_1234", Width = Auto (), Height = 1 }; + view.SetRelativeLayout (new Size (100, 100)); lastSize = view.Frame.Size; view.Text = "*ABCD"; - view.SetRelativeLayout (new (100, 100)); + view.SetRelativeLayout (new Size (100, 100)); Assert.NotEqual (lastSize, view.Frame.Size); } @@ -348,34 +293,34 @@ public void ValidatePosDim_True_Throws_When_SubView_Uses_SuperView_Dims () superView.Add (subView); subView.Width = 10; - superView.SetRelativeLayout (new (10, 10)); + superView.SetRelativeLayout (new Size (10, 10)); superView.LayoutSubViews (); // no throw subView.Width = Fill (); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); subView.Width = 10; subView.Height = Fill (); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); subView.Height = 10; subView.Height = Percent (50); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.Height = 10; subView.X = Pos.Center (); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; subView.Y = Pos.Center (); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.Y = 0; subView.Width = 10; subView.Height = 10; subView.X = 0; subView.Y = 0; - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); superView.LayoutSubViews (); } @@ -392,47 +337,35 @@ public void ValidatePosDim_True_Throws_When_SubView_Uses_SuperView_Dims_Combine ValidatePosDim = true }; - var subView = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10 - }; + var subView = new View { X = 0, Y = 0, Width = 10, Height = 10 }; - var subView2 = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10 - }; + var subView2 = new View { X = 0, Y = 0, Width = 10, Height = 10 }; superView.Add (subView, subView2); superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); superView.LayoutSubViews (); // no throw subView.Height = Fill () + 3; - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); subView.Height = 0; subView.Height = 3 + Fill (); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); subView.Height = 0; subView.Height = 3 + 5 + Fill (); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); subView.Height = 0; subView.Height = 3 + 5 + Percent (10); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.Height = 0; // Tests nested Combine subView.Height = 5 + new DimCombine (AddOrSubtract.Add, 3, new DimCombine (AddOrSubtract.Add, Percent (10), 9)); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); } [Fact] @@ -447,62 +380,50 @@ public void ValidatePosDim_True_Throws_When_SubView_Uses_SuperView_Pos_Combine ( ValidatePosDim = true }; - var subView = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10 - }; + var subView = new View { X = 0, Y = 0, Width = 10, Height = 10 }; - var subView2 = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10 - }; + var subView2 = new View { X = 0, Y = 0, Width = 10, Height = 10 }; superView.Add (subView, subView2); superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); superView.LayoutSubViews (); // no throw subView.X = Pos.Right (subView2); - superView.SetRelativeLayout (new (0, 0)); + superView.SetRelativeLayout (new Size (0, 0)); superView.LayoutSubViews (); // no throw subView.X = Pos.Right (subView2) + 3; - superView.SetRelativeLayout (new (0, 0)); // no throw + superView.SetRelativeLayout (new Size (0, 0)); // no throw superView.LayoutSubViews (); // no throw subView.X = new PosCombine (AddOrSubtract.Add, Pos.Right (subView2), new PosCombine (AddOrSubtract.Add, 7, 9)); - superView.SetRelativeLayout (new (0, 0)); // no throw + superView.SetRelativeLayout (new Size (0, 0)); // no throw subView.X = Pos.Center () + 3; - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; subView.X = 3 + Pos.Center (); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; subView.X = 3 + 5 + Pos.Center (); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; subView.X = 3 + 5 + Pos.Percent (10); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; subView.X = Pos.Percent (10) + Pos.Center (); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; // Tests nested Combine subView.X = 5 + new PosCombine (AddOrSubtract.Add, Pos.Right (subView2), new PosCombine (AddOrSubtract.Add, Pos.Center (), 9)); - Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); + Assert.Throws (() => superView.SetRelativeLayout (new Size (0, 0))); subView.X = 0; } @@ -543,8 +464,8 @@ public void Width_Auto_Height_Absolute_NotChanged (int subX, int subY, int subWi superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (0, 0, expectedWidth, 10), superView.Frame); + superView.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Rectangle (0, 0, expectedWidth, 10), superView.Frame); } // Test that when a view has Width set to DimAuto (min: x) @@ -568,7 +489,7 @@ public void Width_Auto_Min_Honored (int min, int expectedWidth) superView.BeginInit (); superView.EndInit (); - superView.SetRelativeLayout (new (4, 1)); + superView.SetRelativeLayout (new Size (4, 1)); Assert.Equal (expectedWidth, superView.Frame.Width); } @@ -643,7 +564,7 @@ public void Width_Auto_Text_Does_Not_Constrain_To_SuperView (int subX, int textL var subView = new View { - Text = new ('*', textLen), + Text = new string ('*', textLen), X = subX, Y = 0, Width = Auto (DimAutoStyle.Text), @@ -680,7 +601,7 @@ public DimAutoTestView (Dim width, Dim height) public DimAutoTestView (string text, Dim width, Dim height) { ValidatePosDim = true; - Text = text; + base.Text = text; Width = width; Height = height; } @@ -701,39 +622,29 @@ public void DimAutoStyle_Auto_JustText_Sizes_Correctly (string text, int expecte view.Text = text; - view.SetRelativeLayout (new (100, 100)); + view.SetRelativeLayout (new Size (100, 100)); - Assert.Equal (new (expectedW, expectedH), view.Frame.Size); + Assert.Equal (new Size (expectedW, expectedH), view.Frame.Size); } [Fact] public void DimAutoStyle_Auto_Text_Size_Is_Used () { - var view = new View - { - Text = "0123\n4567", - Width = Auto (), - Height = Auto () - }; + var view = new View { Text = "0123\n4567", Width = Auto (), Height = Auto () }; - view.SetRelativeLayout (new (100, 100)); - Assert.Equal (new (4, 2), view.Frame.Size); + view.SetRelativeLayout (new Size (100, 100)); + Assert.Equal (new Size (4, 2), view.Frame.Size); - var subView = new View - { - Text = "ABCD", - Width = Auto (), - Height = Auto () - }; + var subView = new View { Text = "ABCD", Width = Auto (), Height = Auto () }; view.Add (subView); - view.SetRelativeLayout (new (100, 100)); - Assert.Equal (new (4, 2), view.Frame.Size); + view.SetRelativeLayout (new Size (100, 100)); + Assert.Equal (new Size (4, 2), view.Frame.Size); subView.Text = "ABCDE"; - view.SetRelativeLayout (new (100, 100)); - Assert.Equal (new (5, 2), view.Frame.Size); + view.SetRelativeLayout (new Size (100, 100)); + Assert.Equal (new Size (5, 2), view.Frame.Size); } [Theory] @@ -745,21 +656,12 @@ public void DimAutoStyle_Auto_Text_Size_Is_Used () [InlineData ("", 0, 0)] public void DimAutoStyle_Auto_Larger_Wins (string text, int dimension, int expected) { - View view = new () - { - Width = Auto (), - Height = 1, - Text = text - }; + View view = new () { Width = Auto (), Height = 1, Text = text }; - View subView = new () - { - Width = dimension, - Height = 1 - }; + View subView = new () { Width = dimension, Height = 1 }; view.Add (subView); - view.SetRelativeLayout (new (10, 10)); + view.SetRelativeLayout (new Size (10, 10)); Assert.Equal (expected, view.Frame.Width); } @@ -770,18 +672,9 @@ public void DimAutoStyle_Auto_Larger_Wins (string text, int dimension, int expec [Fact] public void DimAutoStyle_Text_Viewport_Stays_Set () { - var super = new View - { - Width = Fill (), - Height = Fill () - }; + var super = new View { Width = Fill (), Height = Fill () }; - var view = new View - { - Text = "01234567", - Width = Auto (DimAutoStyle.Text), - Height = Auto (DimAutoStyle.Text) - }; + var view = new View { Text = "01234567", Width = Auto (DimAutoStyle.Text), Height = Auto (DimAutoStyle.Text) }; super.Add (view); super.Layout (); @@ -810,9 +703,9 @@ public void DimAutoStyle_Text_Sizes_Correctly (string text, int expectedW, int e view.Text = text; - view.SetRelativeLayout (new (100, 100)); + view.SetRelativeLayout (new Size (100, 100)); - Assert.Equal (new (expectedW, expectedH), view.Frame.Size); + Assert.Equal (new Size (expectedW, expectedH), view.Frame.Size); } [Theory] @@ -829,9 +722,9 @@ public void DimAutoStyle_Text_Sizes_Correctly_With_Min (string text, int minWidt view.Text = text; - view.SetRelativeLayout (new (100, 100)); + view.SetRelativeLayout (new Size (100, 100)); - Assert.Equal (new (expectedW, expectedH), view.Frame.Size); + Assert.Equal (new Size (expectedW, expectedH), view.Frame.Size); } [Theory] @@ -849,7 +742,7 @@ public void DimAutoStyle_Text_Sizes_Correctly_With_Max_Width (string text, int m view.Text = text; view.Layout (); - Assert.Equal (new (expectedW, expectedH), view.Frame.Size); + Assert.Equal (new Size (expectedW, expectedH), view.Frame.Size); } [Theory] @@ -863,10 +756,10 @@ public void DimAutoStyle_Text_NoMin_Not_Constrained_By_ContentSize (string text, var view = new View (); view.Width = Auto (DimAutoStyle.Text); view.Height = Auto (DimAutoStyle.Text); - view.SetContentSize (new (1, 1)); + view.SetContentSize (new Size (1, 1)); view.Text = text; view.Layout (); - Assert.Equal (new (expectedW, expectedH), view.Frame.Size); + Assert.Equal (new Size (expectedW, expectedH), view.Frame.Size); } [Theory] @@ -877,10 +770,7 @@ public void DimAutoStyle_Text_NoMin_Not_Constrained_By_ContentSize (string text, [InlineData ("01234\nABCDE", 5, 2)] public void DimAutoStyle_Text_NoMin_Not_Constrained_By_SuperView (string text, int expectedW, int expectedH) { - var superView = new View - { - Width = 1, Height = 1 - }; + var superView = new View { Width = 1, Height = 1 }; var view = new View (); @@ -890,7 +780,7 @@ public void DimAutoStyle_Text_NoMin_Not_Constrained_By_SuperView (string text, i superView.Add (view); superView.Layout (); - Assert.Equal (new (expectedW, expectedH), view.Frame.Size); + Assert.Equal (new Size (expectedW, expectedH), view.Frame.Size); } [Fact] @@ -898,26 +788,26 @@ public void DimAutoStyle_Text_Pos_AnchorEnd_Locates_Correctly () { DimAutoTestView view = new ("01234", Auto (DimAutoStyle.Text), Auto (DimAutoStyle.Text)); - view.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 0), view.Frame.Location); + view.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Size (5, 1), view.Frame.Size); + Assert.Equal (new Point (0, 0), view.Frame.Location); view.X = 0; view.Y = Pos.AnchorEnd (1); - view.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 9), view.Frame.Location); + view.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Size (5, 1), view.Frame.Size); + Assert.Equal (new Point (0, 9), view.Frame.Location); view.Y = Pos.AnchorEnd (); - view.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 9), view.Frame.Location); + view.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Size (5, 1), view.Frame.Size); + Assert.Equal (new Point (0, 9), view.Frame.Location); view.Y = Pos.AnchorEnd () - 1; - view.SetRelativeLayout (new (10, 10)); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 8), view.Frame.Location); + view.SetRelativeLayout (new Size (10, 10)); + Assert.Equal (new Size (5, 1), view.Frame.Size); + Assert.Equal (new Point (0, 8), view.Frame.Location); } #endregion DimAutoStyle.Text tests @@ -943,10 +833,7 @@ public void DimAutoStyle_Content_WithSubViews_IgnoresContentSize_WhenSet () { var view = new View (); - var subview = new View - { - Frame = new Rectangle (50, 50, 1, 1) - }; + var subview = new View { Frame = new Rectangle (50, 50, 1, 1) }; view.Add (subview); view.SetContentSize (new Size (10, 5)); @@ -963,10 +850,7 @@ public void DimAutoStyle_Content_WithSubViews_IgnoresContentSize_WhenNotSet () { var view = new View (); - var subview = new View - { - Frame = new Rectangle (50, 50, 1, 1) - }; + var subview = new View { Frame = new Rectangle (50, 50, 1, 1) }; view.Add (subview); Dim dim = Auto (DimAutoStyle.Content); @@ -991,8 +875,8 @@ public void DimAutoStyle_Content_IgnoresText_WhenContentSizeNotSet () public void DimAutoStyle_Content_UsesLargestSubView_WhenContentSizeNotSet () { var view = new View { Id = "view" }; - view.Add (new View { Id = "smaller", Frame = new (0, 0, 5, 5) }); // Smaller subview - view.Add (new View { Id = "larger", Frame = new (0, 0, 10, 10) }); // Larger subview + view.Add (new View { Id = "smaller", Frame = new Rectangle (0, 0, 5, 5) }); // Smaller subview + view.Add (new View { Id = "larger", Frame = new Rectangle (0, 0, 10, 10) }); // Larger subview Dim dim = Auto (DimAutoStyle.Content); @@ -1005,14 +889,131 @@ public void DimAutoStyle_Content_UsesLargestSubView_WhenContentSizeNotSet () public void DimAutoStyle_Content_UsesContentSize_If_No_SubViews () { DimAutoTestView view = new (Auto (DimAutoStyle.Content), Auto (DimAutoStyle.Content)); - view.SetContentSize (new (5, 5)); - view.SetRelativeLayout (new (10, 10)); + view.SetContentSize (new Size (5, 5)); + view.SetRelativeLayout (new Size (10, 10)); - Assert.Equal (new (5, 5), view.Frame.Size); + Assert.Equal (new Size (5, 5), view.Frame.Size); } - #endregion DimAutoStyle.Content tests // Test variations of Frame + + #region GetAutoWidth / GetAutoHeight + + // Claude - Opus 4.6 + + [Fact] + public void GetAutoWidth_Horizontal_ReturnsCorrectWidth () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Hello" }; + + int width = view.GetAutoWidth (); + + // "Hello" = 5 columns, no border/margin/padding + Assert.Equal (5, width); + + view.Dispose (); + } + + [Fact] + public void GetAutoHeight_Horizontal_ReturnsCorrectHeight () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Hello" }; + + int height = view.GetAutoHeight (); + + // Single-line text = 1 row, no border/margin/padding + Assert.Equal (1, height); + + view.Dispose (); + } + + [Fact] + public void GetAutoWidth_WithBorder_IncludesAdornments () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Hi", BorderStyle = LineStyle.Single }; + + int width = view.GetAutoWidth (); + + // "Hi" = 2 columns + border left (1) + border right (1) = 4 + Assert.Equal (4, width); + + view.Dispose (); + } + + [Fact] + public void GetAutoHeight_WithBorder_IncludesAdornments () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Hi", BorderStyle = LineStyle.Single }; + + int height = view.GetAutoHeight (); + + // 1 row + border top (1) + border bottom (1) = 3 + Assert.Equal (3, height); + + view.Dispose (); + } + + [Fact] + public void GetAutoHeight_VerticalText_BeforeLayout_ReturnsCorrectHeight () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Tab" }; + + view.TextFormatter.Direction = TextDirection.TopBottom_LeftRight; + + int height = view.GetAutoHeight (); + + // Vertical "Tab" = 3 rows tall, no border + Assert.Equal (3, height); + + view.Dispose (); + } + + [Fact] + public void GetAutoHeight_VerticalText_WithBorder_BeforeLayout_ReturnsCorrectHeight () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Tab", BorderStyle = LineStyle.Single }; + + view.TextFormatter.Direction = TextDirection.TopBottom_LeftRight; + + int height = view.GetAutoHeight (); + + // Vertical "Tab" = 3 rows + border top (1) + border bottom (1) = 5 + Assert.Equal (5, height); + + view.Dispose (); + } + + [Fact] + public void GetAutoWidth_VerticalText_BeforeLayout_ReturnsCorrectWidth () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Tab" }; + + view.TextFormatter.Direction = TextDirection.TopBottom_LeftRight; + + int width = view.GetAutoWidth (); + + // Vertical single-column text = 1 column, no border + Assert.Equal (1, width); + + view.Dispose (); + } + + [Fact] + public void GetAutoHeight_VerticalText_MultiLine_BeforeLayout () + { + View view = new () { Width = Auto (), Height = Auto (), Text = "Hello" }; + + view.TextFormatter.Direction = TextDirection.TopBottom_LeftRight; + + int height = view.GetAutoHeight (); + + // Vertical "Hello" = 5 rows + Assert.Equal (5, height); + + view.Dispose (); + } + + #endregion GetAutoWidth / GetAutoHeight }