From 3e287c4bdd992d93865827bd2071b279be274abe Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 14 May 2024 15:45:04 -0700 Subject: [PATCH] Moved PosXXX to not be nested classes --- Terminal.Gui/View/Layout/Dim.cs | 2 +- Terminal.Gui/View/Layout/Pos.cs | 372 ++++++++++++------------- Terminal.Gui/View/Layout/ViewLayout.cs | 26 +- Terminal.Gui/Views/TileView.cs | 10 +- Terminal.Gui/Views/Toplevel.cs | 4 +- UnitTests/View/Layout/Dim.AutoTests.cs | 4 +- UnitTests/View/Layout/Pos.Tests.cs | 18 +- UnitTests/Views/TileViewTests.cs | 6 +- 8 files changed, 218 insertions(+), 224 deletions(-) diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 0ff058a8e..2ebe0a477 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -417,7 +417,7 @@ public class Dim for (int i = 0; i < us.Subviews.Count; i++) { var v = us.Subviews [i]; - bool isNotPosAnchorEnd = dimension == Dim.Dimension.Width ? v.X is not Pos.PosAnchorEnd : v.Y is not Pos.PosAnchorEnd; + bool isNotPosAnchorEnd = dimension == Dim.Dimension.Width ? v.X is not PosAnchorEnd : v.Y is not PosAnchorEnd; //if (!isNotPosAnchorEnd) //{ diff --git a/Terminal.Gui/View/Layout/Pos.cs b/Terminal.Gui/View/Layout/Pos.cs index 5ad3251ba..de017bf01 100644 --- a/Terminal.Gui/View/Layout/Pos.cs +++ b/Terminal.Gui/View/Layout/Pos.cs @@ -346,225 +346,219 @@ public class Pos /// that /// is used. /// - internal virtual int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) - { - return Anchor (superviewDimension); - } + internal virtual int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) { return Anchor (superviewDimension); } /// /// Diagnostics API to determine if this Pos object references other views. /// /// - internal virtual bool ReferencesOtherViews () + internal virtual bool ReferencesOtherViews () { return false; } +} + +internal class PosAbsolute (int n) : Pos +{ + private readonly int _n = n; + public override bool Equals (object other) { return other is PosAbsolute abs && abs._n == _n; } + public override int GetHashCode () { return _n.GetHashCode (); } + public override string ToString () { return $"Absolute({_n})"; } + internal override int Anchor (int width) { return _n; } +} + +internal class PosAnchorEnd : Pos +{ + private readonly int _offset; + public PosAnchorEnd () { UseDimForOffset = true; } + 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. + /// + internal bool UseDimForOffset { get; set; } + + public override string ToString () { return UseDimForOffset ? "AnchorEnd()" : $"AnchorEnd({_offset})"; } + + internal override int Anchor (int width) { - return false; - } - - internal class PosAbsolute (int n) : Pos - { - private readonly int _n = n; - public override bool Equals (object other) { return other is PosAbsolute abs && abs._n == _n; } - public override int GetHashCode () { return _n.GetHashCode (); } - public override string ToString () { return $"Absolute({_n})"; } - internal override int Anchor (int width) { return _n; } - } - - internal class PosAnchorEnd : Pos - { - private readonly int _offset; - public PosAnchorEnd () { UseDimForOffset = true; } - 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. - /// - internal bool UseDimForOffset { get; set; } - - public override string ToString () { return UseDimForOffset ? "AnchorEnd()" : $"AnchorEnd({_offset})"; } - - internal override int Anchor (int width) + if (UseDimForOffset) { - if (UseDimForOffset) - { - return width; - } - - return width - _offset; + return width; } - internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) - { - int newLocation = Anchor (superviewDimension); - - if (UseDimForOffset) - { - newLocation -= dim.Anchor (superviewDimension); - } - - return newLocation; - } + return width - _offset; } - internal class PosCenter : Pos + internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) { - public override string ToString () { return "Center"; } - internal override int Anchor (int width) { return width / 2; } + int newLocation = Anchor (superviewDimension); - internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) + if (UseDimForOffset) { - int newDimension = Math.Max (dim.Calculate (0, superviewDimension, us, dimension), 0); - - return Anchor (superviewDimension - newDimension); + newLocation -= dim.Anchor (superviewDimension); } + + return newLocation; + } +} + +internal class PosCenter : Pos +{ + public override string ToString () { return "Center"; } + internal override int Anchor (int width) { return width / 2; } + + internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) + { + int newDimension = Math.Max (dim.Calculate (0, superviewDimension, us, dimension), 0); + + return Anchor (superviewDimension - newDimension); + } +} + +internal class PosCombine (bool add, Pos left, Pos right) : Pos +{ + internal bool _add = add; + internal Pos _left = left, _right = right; + + public override string ToString () { return $"Combine({_left}{(_add ? '+' : '-')}{_right})"; } + + internal override int Anchor (int width) + { + int la = _left.Anchor (width); + int ra = _right.Anchor (width); + + if (_add) + { + return la + ra; + } + + return la - ra; } - internal class PosCombine (bool add, Pos left, Pos right) : Pos + internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) { - internal bool _add = add; - internal Pos _left = left, _right = right; + int newDimension = dim.Calculate (0, superviewDimension, us, dimension); + int left = _left.Calculate (superviewDimension, dim, us, dimension); + int right = _right.Calculate (superviewDimension, dim, us, dimension); - public override string ToString () { return $"Combine({_left}{(_add ? '+' : '-')}{_right})"; } - - internal override int Anchor (int width) + if (_add) { - int la = _left.Anchor (width); - int ra = _right.Anchor (width); - - if (_add) - { - return la + ra; - } - - return la - ra; + return left + right; } - internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension) - { - int newDimension = dim.Calculate (0, superviewDimension, us, dimension); - int left = _left.Calculate (superviewDimension, dim, us, dimension); - int right = _right.Calculate (superviewDimension, dim, us, dimension); - - if (_add) - { - return left + right; - } - - return left - right; - } - - /// - /// Diagnostics API to determine if this Pos object references other views. - /// - /// - internal override bool ReferencesOtherViews () - { - if (_left.ReferencesOtherViews ()) - { - return true; - } - - if (_right.ReferencesOtherViews ()) - { - return true; - } - - return false; - } - } - - internal class PosFactor (float factor) : Pos - { - private readonly float _factor = factor; - public override bool Equals (object other) { return other is PosFactor f && f._factor == _factor; } - public override int GetHashCode () { return _factor.GetHashCode (); } - public override string ToString () { return $"Factor({_factor})"; } - internal override int Anchor (int width) { return (int)(width * _factor); } - } - - // Helper class to provide dynamic value by the execution of a function that returns an integer. - internal class PosFunc (Func n) : Pos - { - private readonly Func _function = n; - public override bool Equals (object other) { return other is PosFunc f && f._function () == _function (); } - public override int GetHashCode () { return _function.GetHashCode (); } - public override string ToString () { return $"PosFunc({_function ()})"; } - internal override int Anchor (int width) { return _function (); } + return left - right; } /// - /// Describes which side of the view to use for the position. + /// Diagnostics API to determine if this Pos object references other views. /// - public enum Side + /// + internal override bool ReferencesOtherViews () { - /// - /// The left (X) side of the view. - /// - Left = 0, - - /// - /// The top (Y) side of the view. - /// - Top = 1, - - /// - /// The right (X + Width) side of the view. - /// - Right = 2, - - /// - /// The bottom (Y + Height) side of the view. - /// - Bottom = 3 - } - - internal class PosView (View view, Side side) : Pos - { - public readonly View Target = view; - - public override bool Equals (object other) { return other is PosView abs && abs.Target == Target; } - public override int GetHashCode () { return Target.GetHashCode (); } - - public override string ToString () - { - string sideString = side switch - { - Side.Left => "left", - Side.Top => "top", - Side.Right => "right", - Side.Bottom => "bottom", - _ => "unknown" - }; - - if (Target == null) - { - throw new NullReferenceException (nameof (Target)); - } - - return $"View(side={sideString},target={Target})"; - } - - internal override int Anchor (int width) - { - return side switch - { - Side.Left => Target.Frame.X, - Side.Top => Target.Frame.Y, - Side.Right => Target.Frame.Right, - Side.Bottom => Target.Frame.Bottom, - _ => 0 - }; - } - - /// - /// Diagnostics API to determine if this Pos object references other views. - /// - /// - internal override bool ReferencesOtherViews () + if (_left.ReferencesOtherViews ()) { return true; } + + if (_right.ReferencesOtherViews ()) + { + return true; + } + + return false; + } +} + +internal class PosFactor (float factor) : Pos +{ + private readonly float _factor = factor; + public override bool Equals (object other) { return other is PosFactor f && f._factor == _factor; } + public override int GetHashCode () { return _factor.GetHashCode (); } + public override string ToString () { return $"Factor({_factor})"; } + internal override int Anchor (int width) { return (int)(width * _factor); } +} + +// Helper class to provide dynamic value by the execution of a function that returns an integer. +internal class PosFunc (Func n) : Pos +{ + private readonly Func _function = n; + public override bool Equals (object other) { return other is PosFunc f && f._function () == _function (); } + public override int GetHashCode () { return _function.GetHashCode (); } + public override string ToString () { return $"PosFunc({_function ()})"; } + internal override int Anchor (int width) { return _function (); } +} + +/// +/// Describes which side of the view to use for the position. +/// +public enum Side +{ + /// + /// The left (X) side of the view. + /// + Left = 0, + + /// + /// The top (Y) side of the view. + /// + Top = 1, + + /// + /// The right (X + Width) side of the view. + /// + Right = 2, + + /// + /// The bottom (Y + Height) side of the view. + /// + Bottom = 3 +} + +internal class PosView (View view, Side side) : Pos +{ + public readonly View Target = view; + + public override bool Equals (object other) { return other is PosView abs && abs.Target == Target; } + public override int GetHashCode () { return Target.GetHashCode (); } + + public override string ToString () + { + string sideString = side switch + { + Side.Left => "left", + Side.Top => "top", + Side.Right => "right", + Side.Bottom => "bottom", + _ => "unknown" + }; + + if (Target == null) + { + throw new NullReferenceException (nameof (Target)); + } + + return $"View(side={sideString},target={Target})"; + } + + internal override int Anchor (int width) + { + return side switch + { + Side.Left => Target.Frame.X, + Side.Top => Target.Frame.Y, + Side.Right => Target.Frame.Right, + Side.Bottom => Target.Frame.Bottom, + _ => 0 + }; + } + + /// + /// Diagnostics API to determine if this Pos object references other views. + /// + /// + internal override bool ReferencesOtherViews () + { + return true; } } diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs index 7247394fa..5765e148e 100644 --- a/Terminal.Gui/View/Layout/ViewLayout.cs +++ b/Terminal.Gui/View/Layout/ViewLayout.cs @@ -182,7 +182,7 @@ public partial class View /// /// /// Changing this property will cause to be updated. If the new value is not of type - /// the will change to . + /// the will change to . /// /// The default value is Pos.At (0). /// @@ -221,7 +221,7 @@ public partial class View /// /// /// Changing this property will cause to be updated. If the new value is not of type - /// the will change to . + /// the will change to . /// /// The default value is Pos.At (0). /// @@ -363,7 +363,7 @@ public partial class View /// /// Setting this property to will cause the view to use the /// method to size and position of the view. If either of the and - /// properties are `null` they will be set to using the current value + /// properties are `null` they will be set to using the current value /// of . If either of the and properties are `null` /// they will be set to using . /// @@ -373,8 +373,8 @@ public partial class View { get { - if (_x is Pos.PosAbsolute - && _y is Pos.PosAbsolute + if (_x is PosAbsolute + && _y is PosAbsolute && _width is Dim.DimAbsolute && _height is Dim.DimAbsolute) { @@ -836,12 +836,12 @@ public partial class View // the view LayoutStyle.Absolute. SetFrame (newFrame); - if (_x is Pos.PosAbsolute) + if (_x is PosAbsolute) { _x = Frame.X; } - if (_y is Pos.PosAbsolute) + if (_y is PosAbsolute) { _y = Frame.Y; } @@ -912,7 +912,7 @@ public partial class View { switch (pos) { - case Pos.PosView pv: + case PosView pv: // See #2461 //if (!from.InternalSubviews.Contains (pv.Target)) { // throw new InvalidOperationException ($"View {pv.Target} is not a subview of {from}"); @@ -923,7 +923,7 @@ public partial class View } return; - case Pos.PosCombine pc: + case PosCombine pc: CollectPos (pc._left, from, ref nNodes, ref nEdges); CollectPos (pc._right, from, ref nNodes, ref nEdges); @@ -1104,15 +1104,15 @@ public partial class View switch (checkPosDim) { - case Pos pos and not Pos.PosAbsolute and not Pos.PosView and not Pos.PosCombine: + case Pos pos and not PosAbsolute and not PosView and not PosCombine: bad = pos; break; - case Pos pos and Pos.PosCombine: + case Pos pos and PosCombine: // Recursively check for not Absolute or not View - ThrowInvalid (view, (pos as Pos.PosCombine)._left, name); - ThrowInvalid (view, (pos as Pos.PosCombine)._right, name); + ThrowInvalid (view, (pos as PosCombine)._left, name); + ThrowInvalid (view, (pos as PosCombine)._right, name); break; diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index d6d33a4f0..e3cf1aa2f 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -417,7 +417,7 @@ public class TileView : View /// public bool SetSplitterPos (int idx, Pos value) { - if (!(value is Pos.PosAbsolute) && !(value is Pos.PosFactor)) + if (!(value is PosAbsolute) && !(value is PosFactor)) { throw new ArgumentException ( $"Only Percent and Absolute values are supported. Passed value was {value.GetType ().Name}" @@ -991,11 +991,11 @@ public class TileView : View /// /// - /// Determines the absolute position of and returns a that + /// Determines the absolute position of and returns a that /// describes the percentage of that. /// /// - /// Effectively turning any into a (as if created with + /// Effectively turning any into a (as if created with /// ) /// /// @@ -1007,7 +1007,7 @@ public class TileView : View // calculate position in the 'middle' of the cell at p distance along parentLength float position = p.Anchor (parentLength) + 0.5f; - return new Pos.PosFactor (position / parentLength); + return new PosFactor (position / parentLength); } /// @@ -1025,7 +1025,7 @@ public class TileView : View /// private bool FinalisePosition (Pos oldValue, Pos newValue) { - if (oldValue is Pos.PosFactor) + if (oldValue is PosFactor) { if (Orientation == Orientation.Horizontal) { diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index 235034820..f21c40a64 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -401,13 +401,13 @@ public partial class Toplevel : View // BUGBUG: Prevously PositionToplevel required LayotuStyle.Computed && (top.Frame.X + top.Frame.Width > maxWidth || ny > top.Frame.Y) /*&& top.LayoutStyle == LayoutStyle.Computed*/) { - if ((top.X is null || top.X is Pos.PosAbsolute) && top.Frame.X != nx) + if ((top.X is null || top.X is PosAbsolute) && top.Frame.X != nx) { top.X = nx; layoutSubviews = true; } - if ((top.Y is null || top.Y is Pos.PosAbsolute) && top.Frame.Y != ny) + if ((top.Y is null || top.Y is PosAbsolute) && top.Frame.Y != ny) { top.Y = ny; layoutSubviews = true; diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index 8524f5ff6..56f929253 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -497,7 +497,7 @@ public class DimAutoTests (ITestOutputHelper output) superView.SetRelativeLayout (new (0, 0)); // no throw superView.LayoutSubviews (); // no throw - subView.X = new Pos.PosCombine (true, Pos.Right (subView2), new Pos.PosCombine (true, 7, 9)); + subView.X = new PosCombine (true, Pos.Right (subView2), new PosCombine (true, 7, 9)); superView.SetRelativeLayout (new (0, 0)); // no throw subView.X = Pos.Center () + 3; @@ -521,7 +521,7 @@ public class DimAutoTests (ITestOutputHelper output) subView.X = 0; // Tests nested Combine - subView.X = 5 + new Pos.PosCombine (true, Pos.Right (subView2), new Pos.PosCombine (true, Pos.Center (), 9)); + subView.X = 5 + new PosCombine (true, Pos.Right (subView2), new PosCombine (true, Pos.Center (), 9)); Assert.Throws (() => superView.SetRelativeLayout (new (0, 0))); subView.X = 0; } diff --git a/UnitTests/View/Layout/Pos.Tests.cs b/UnitTests/View/Layout/Pos.Tests.cs index d36506c98..b5ae383fb 100644 --- a/UnitTests/View/Layout/Pos.Tests.cs +++ b/UnitTests/View/Layout/Pos.Tests.cs @@ -212,19 +212,19 @@ public class PosTests (ITestOutputHelper output) [TestRespondersDisposed] public void Internal_Tests () { - var posFactor = new Pos.PosFactor (0.10F); + var posFactor = new PosFactor (0.10F); Assert.Equal (10, posFactor.Anchor (100)); - var posAnchorEnd = new Pos.PosAnchorEnd (1); + var posAnchorEnd = new PosAnchorEnd (1); Assert.Equal (99, posAnchorEnd.Anchor (100)); - var posCenter = new Pos.PosCenter (); + var posCenter = new PosCenter (); Assert.Equal (50, posCenter.Anchor (100)); - var posAbsolute = new Pos.PosAbsolute (10); + var posAbsolute = new PosAbsolute (10); Assert.Equal (10, posAbsolute.Anchor (0)); - var posCombine = new Pos.PosCombine (true, posFactor, posAbsolute); + var posCombine = new PosCombine (true, posFactor, posAbsolute); Assert.Equal (posCombine._left, posFactor); Assert.Equal (posCombine._right, posAbsolute); Assert.Equal (20, posCombine.Anchor (100)); @@ -235,13 +235,13 @@ public class PosTests (ITestOutputHelper output) Assert.Equal (20, posCombine.Anchor (100)); var view = new View { Frame = new (20, 10, 20, 1) }; - var posViewX = new Pos.PosView (view, Pos.Side.Left); + var posViewX = new PosView (view, Side.Left); Assert.Equal (20, posViewX.Anchor (0)); - var posViewY = new Pos.PosView (view, Pos.Side.Top); + var posViewY = new PosView (view, Side.Top); Assert.Equal (10, posViewY.Anchor (0)); - var posRight = new Pos.PosView (view, Pos.Side.Right); + var posRight = new PosView (view, Side.Right); Assert.Equal (40, posRight.Anchor (0)); - var posViewBottom = new Pos.PosView (view, Pos.Side.Bottom); + var posViewBottom = new PosView (view, Side.Bottom); Assert.Equal (11, posViewBottom.Anchor (0)); view.Dispose (); diff --git a/UnitTests/Views/TileViewTests.cs b/UnitTests/Views/TileViewTests.cs index 30a0c206d..a6fc6948d 100644 --- a/UnitTests/Views/TileViewTests.cs +++ b/UnitTests/Views/TileViewTests.cs @@ -1959,7 +1959,7 @@ public class TileViewTests { TileView tileView = Get11By3TileView (out LineView line); tileView.SetSplitterPos (0, Pos.Percent (50)); - Assert.IsType (tileView.SplitterDistances.ElementAt (0)); + Assert.IsType (tileView.SplitterDistances.ElementAt (0)); tileView.NewKeyDownEvent (new Key (tileView.ToggleResizable)); tileView.Draw (); @@ -1983,7 +1983,7 @@ public class TileViewTests TestHelpers.AssertDriverContentsAre (looksLike, _output); // Even when moving the splitter location it should stay a Percentage based one - Assert.IsType (tileView.SplitterDistances.ElementAt (0)); + Assert.IsType (tileView.SplitterDistances.ElementAt (0)); // and 2 to the left line.NewKeyDownEvent (Key.CursorLeft); @@ -1998,7 +1998,7 @@ public class TileViewTests TestHelpers.AssertDriverContentsAre (looksLike, _output); // Even when moving the splitter location it should stay a Percentage based one - Assert.IsType (tileView.SplitterDistances.ElementAt (0)); + Assert.IsType (tileView.SplitterDistances.ElementAt (0)); } [Fact]