From dd298d0e2e09682557a15db8e00bd36a9f53b4fd Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 6 Apr 2023 23:42:13 +0100 Subject: [PATCH] Fix more issue in the layout. --- Terminal.Gui/View/View.cs | 30 ++++++++++++++++---------- UICatalog/Scenarios/ColorPicker.cs | 15 ++++++------- UICatalog/Scenarios/ViewExperiments.cs | 5 ++--- UnitTests/View/Layout/DimTests.cs | 16 +++++++------- UnitTests/View/Layout/PosTests.cs | 28 ++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs index 85e69b59f..bdeaf4b83 100644 --- a/Terminal.Gui/View/View.cs +++ b/Terminal.Gui/View/View.cs @@ -2656,12 +2656,21 @@ namespace Terminal.Gui { } if (edges.Any ()) { - (var from, var to) = edges.First (); - if (from != superView?.GetTopSuperView (to, from) && !ReferenceEquals (from, to)) { - if (ReferenceEquals (from.SuperView, to)) { - throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{to}\" references a SubView (\"{from}\")."); - } else { - throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{from}\" linked with \"{to}\" was not found. Did you forget to add it to {superView}?"); + foreach ((var from, var to) in edges) { + if (from == to || from?.SuperView == to?.SuperView) { + // if not yet added to the result, add it and remove from edge + if (result.Find (v => v == from) == null) { + result.Add (from); + } else if (result.Find (v => v == to) == null) { + result.Add (to); + } + edges.Remove ((from, to)); + } else if (from != superView?.GetTopSuperView (to, from) && !ReferenceEquals (from, to)) { + if (ReferenceEquals (from.SuperView, to)) { + throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{to}\" references a SubView (\"{from}\")."); + } else { + throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{from}\" linked with \"{to}\" was not found. Did you forget to add it to {superView}?"); + } } } } @@ -2740,11 +2749,10 @@ namespace Terminal.Gui { // If the 'to' is rooted to 'from' and the layoutstyle is Computed it's a special-case. // Use LayoutSubview with the Frame of the 'from' - if (SuperView != null && GetTopSuperView () != null && LayoutNeeded - && ordered.Count == 0 && edges.Count > 0 && LayoutStyle == LayoutStyle.Computed) { - - (var from, var to) = edges.First (); - LayoutSubview (to, from.Frame); + if (SuperView != null && GetTopSuperView () != null && LayoutNeeded && edges.Count > 0) { + foreach ((var from, var to) in edges) { + LayoutSubview (to, from.Frame); + } } LayoutNeeded = false; diff --git a/UICatalog/Scenarios/ColorPicker.cs b/UICatalog/Scenarios/ColorPicker.cs index 290dd7899..496d2017d 100644 --- a/UICatalog/Scenarios/ColorPicker.cs +++ b/UICatalog/Scenarios/ColorPicker.cs @@ -39,23 +39,20 @@ namespace UICatalog.Scenarios { // Scenario Window's. Win.Title = this.GetName (); - // Forground ColorPicker. + // Foreground ColorPicker. foregroundColorPicker = new ColorPicker ("Foreground Color"); - foregroundColorPicker.X = 0; - foregroundColorPicker.Y = 0; foregroundColorPicker.ColorChanged += ForegroundColor_ColorChanged; Win.Add (foregroundColorPicker); - foregroundColorLabel = new Label (); - foregroundColorLabel.X = Pos.Left(foregroundColorPicker); - foregroundColorLabel.Y = Pos.Bottom (foregroundColorPicker) + 1; + foregroundColorLabel = new Label { + X = Pos.Left (foregroundColorPicker), + Y = Pos.Bottom (foregroundColorPicker) + 1 + }; Win.Add (foregroundColorLabel); // Background ColorPicker. - backgroundColorPicker = new ColorPicker (); - backgroundColorPicker.Text = "Background Color"; + backgroundColorPicker = new ColorPicker ("Background Color"); backgroundColorPicker.X = Pos.AnchorEnd () - (Pos.Right (backgroundColorPicker) - Pos.Left (backgroundColorPicker)); - backgroundColorPicker.Y = 0; backgroundColorPicker.ColorChanged += BackgroundColor_ColorChanged; Win.Add (backgroundColorPicker); diff --git a/UICatalog/Scenarios/ViewExperiments.cs b/UICatalog/Scenarios/ViewExperiments.cs index 3a809dd4e..7b9d73429 100644 --- a/UICatalog/Scenarios/ViewExperiments.cs +++ b/UICatalog/Scenarios/ViewExperiments.cs @@ -120,7 +120,7 @@ namespace UICatalog.Scenarios { }; Add (copyTop); - LayoutSubviews (); + //LayoutSubviews (); Height = Margin.Thickness.Vertical + BorderFrame.Thickness.Vertical + Padding.Thickness.Vertical + 4; Width = 20; } @@ -234,7 +234,7 @@ namespace UICatalog.Scenarios { //}; //Add (rbBorderBrush); - Height = 8; + Height = 8; Title = title; } } @@ -242,7 +242,6 @@ namespace UICatalog.Scenarios { public override void Init () { Application.Init (); - //Application.Init (); ConfigurationManager.Themes.Theme = Theme; ConfigurationManager.Apply (); Application.Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme]; diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index f3ca6f626..135261d67 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -544,12 +544,11 @@ namespace Terminal.Gui.ViewTests { // Assert.Throws (() => super.LayoutSubviews ()); //} - /// /// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461 /// [Fact] - public void DimCombine_ObtuseScenario_Does_Not_Throw () + public void DimCombine_ObtuseScenario_Throw () { var t = new View ("top") { Width = 80, Height = 25 }; @@ -571,11 +570,12 @@ namespace Terminal.Gui.ViewTests { w.Add (f); t.Add (w); - // BUGBUG: v2 - f references t here; t is f's super-superview. This is not supported! + // BUGBUG: v2 - f references t here; t is f's super-superview. This is supported! + // BUGBUG: v2 - f references v2 here; v2 is f's subview. This is not supported! f.Width = Dim.Width (t) - Dim.Width (v2); // 80 - 74 = 6 f.Height = Dim.Height (t) - Dim.Height (v2); // 25 - 19 = 6 - t.LayoutSubviews (); + Assert.Throws (t.LayoutSubviews); Assert.Equal (80, t.Frame.Width); Assert.Equal (25, t.Frame.Height); Assert.Equal (78, w.Frame.Width); @@ -583,10 +583,10 @@ namespace Terminal.Gui.ViewTests { // BUGBUG: v2 - this no longer works - see above //Assert.Equal (6, f.Frame.Width); //Assert.Equal (6, f.Frame.Height); - Assert.Equal (76, v1.Frame.Width); - Assert.Equal (21, v1.Frame.Height); - Assert.Equal (74, v2.Frame.Width); - Assert.Equal (19, v2.Frame.Height); + //Assert.Equal (76, v1.Frame.Width); + //Assert.Equal (21, v1.Frame.Height); + //Assert.Equal (74, v2.Frame.Width); + //Assert.Equal (19, v2.Frame.Height); } [Fact] diff --git a/UnitTests/View/Layout/PosTests.cs b/UnitTests/View/Layout/PosTests.cs index 1088d10d9..cab3227b7 100644 --- a/UnitTests/View/Layout/PosTests.cs +++ b/UnitTests/View/Layout/PosTests.cs @@ -1039,5 +1039,33 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (61, label.Frame.Y); } } + + [Fact] + public void PosCombine_Referencing_Same_View () + { + var super = new View ("super") { + Width = 10, + Height = 10 + }; + var view1 = new View ("view1") { + Width = 2, + Height = 2, + }; + var view2 = new View ("view2") { + Width = 2, + Height = 2, + }; + view2.X = Pos.AnchorEnd () - (Pos.Right (view2) - Pos.Left (view2)); + + super.Add (view1, view2); + super.BeginInit (); + super.EndInit (); + + var exception = Record.Exception (super.LayoutSubviews); + Assert.Null (exception); + Assert.Equal (new Rect (0, 0, 10, 10), super.Frame); + Assert.Equal (new Rect (0, 0, 2, 2), view1.Frame); + Assert.Equal (new Rect (8, 0, 2, 2), view2.Frame); + } } }