Browse Source

Progress on low level unit tess

Tig Kindel 1 year ago
parent
commit
f48ff99628

+ 3 - 3
Terminal.Gui/View/Layout/PosDim.cs

@@ -62,7 +62,7 @@ namespace Terminal.Gui;
 ///	  </description>
 ///	</item>
 ///	<item>
-///	  <term><see cref="Pos.Left(int)"/></term>
+///	  <term><see cref="Pos.Left"/></term>
 ///	  <description>
 ///	  Creates a <see cref="Pos"/> object that tracks the Left (X) position of the specified <see cref="View"/>.
 ///	  </description>
@@ -450,7 +450,7 @@ public class Pos {
 ///	  </description>
 ///	</item>
 ///	<item>
-///	  <term><see cref="Auto()"/></term>
+///	  <term><see cref="Dim.Auto"/></term>
 ///	  <description>
 ///	  Creates a <see cref="Dim"/> object that automatically sizes the view to fit all of the view's SubViews.
 ///	  </description>
@@ -596,7 +596,7 @@ public class Dim {
 	/// <returns>The AutoSize <see cref="Dim"/> object.</returns>
 	/// <param name="style">Specifies how <see cref="DimAuto"/> will compute the dimension. The default is <see cref="DimAutoStyle.Text"/>. NOT CURRENTLY SUPPORTED.</param>
 	/// <param name="min">Specifies the minimum dimension that view will be automatically sized to. NOT CURRENTLY SUPPORTED.</param>
-	/// <param name="min">Specifies the maximum dimension that view will be automatically sized to. NOT CURRENTLY SUPPORTED.</param>
+	/// <param name="max">Specifies the maximum dimension that view will be automatically sized to. NOT CURRENTLY SUPPORTED.</param>
 	public static Dim Auto (DimAutoStyle style = DimAutoStyle.Subviews, Dim min = null, Dim max = null)
 	{
 		if (style == DimAutoStyle.Text) {

+ 10 - 18
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -697,7 +697,7 @@ public partial class View {
 			//   dimension: the current dimension (width or height)
 			//   autosize: the size to use if autosize = true
 			// This mehod is recursive if d is Dim.DimCombine
-			int GetNewDimension  (Dim d, int location, int dimension, int autosize)
+			int GetNewDimension (Dim d, int location, int dimension, int autosize)
 			{
 				int newDimension;
 				switch (d) {
@@ -724,9 +724,9 @@ public partial class View {
 
 				case Dim.DimAuto auto:
 					var thickness = GetFramesThickness ();
-					newDimension = GetNewDimension (auto._min, location, dimension, autosize);
+					//newDimension = GetNewDimension (auto._min, location, dimension, autosize);
 					if (width) {
-						int furthestRight = Subviews.Count == 0 ? 0 : Subviews.Max (v => v.Frame.X + v.Frame.Width);
+						int furthestRight = Subviews.Count == 0 ? 0 : Subviews.Where (v => v.X is not Pos.PosAnchorEnd).Max (v => v.Frame.X + v.Frame.Width);
 						//Debug.Assert(superviewBounds.Width == (SuperView?.Bounds.Width ?? 0));
 						newDimension = int.Max (furthestRight + thickness.Left + thickness.Right, auto._min?.Anchor (superviewBounds.Width) ?? 0);
 					} else {
@@ -752,20 +752,11 @@ public partial class View {
 			// Determine new location
 			switch (pos) {
 			case Pos.PosCenter posCenter:
-				if (dim == null) {
-					// BUGBUG: In what situation is dim == null here? None that I can find.
-					// dim == null is the same as dim == Dim.FIll (0)
-					throw new ArgumentException ();
-					newDimension = AutoSize ? autosizeDimension : superviewDimension;
-					newLocation = posCenter.Anchor (superviewDimension - newDimension);
-				} else {
-					//newLocation = posCenter?.Anchor (superviewDimension) ?? 0;
-					//newDimension = Math.Max (GetNewDimension (dim, newLocation, superviewDimension, autosizeDimension), 0);
-
-					newDimension = posCenter.Anchor (superviewDimension);
-					newDimension = AutoSize && autosizeDimension > newDimension ? autosizeDimension : newDimension;
-					newLocation = posCenter.Anchor (superviewDimension - newDimension);
-				}
+				// For Center, the dimension is dependent on location, but we need to force getting the dimension first
+				// using a location of 0
+				newDimension = Math.Max (GetNewDimension (dim, 0, superviewDimension, autosizeDimension), 0);
+				newLocation = posCenter.Anchor (superviewDimension - newDimension);
+				newDimension = Math.Max (GetNewDimension (dim, newLocation, superviewDimension, autosizeDimension), 0);
 				break;
 
 			case Pos.PosCombine combine:
@@ -786,7 +777,7 @@ public partial class View {
 			case Pos.PosFactor:
 			case Pos.PosFunc:
 			case Pos.PosView:
-			default: 
+			default:
 				newLocation = pos?.Anchor (superviewDimension) ?? 0;
 				newDimension = Math.Max (GetNewDimension (dim, newLocation, superviewDimension, autosizeDimension), 0);
 				break;
@@ -1046,6 +1037,7 @@ public partial class View {
 			if (v.Width is Dim.DimAuto || v.Height is Dim.DimAuto) {
 				// If the view is auto-sized...
 				var f = v.Frame;
+				v._frame = new Rect (v.Frame.X, v.Frame.Y, 0, 0);
 				LayoutSubview (v, new Rect (GetBoundsOffset (), Bounds.Size));
 				if (v.Frame != f) {
 					// The subviews changed; do it again

+ 13 - 0
UICatalog/Scenarios/ComputedLayout.cs

@@ -163,6 +163,19 @@ namespace UICatalog.Scenarios {
 			};
 			Application.Top.Add (oddballButton);
 
+			oddballButton = new Button ("Center - 1") {
+				X = Pos.Center () - 1,
+				Y = Pos.Bottom (oddballButton)
+			};
+			Application.Top.Add (oddballButton);
+
+			// Won't be visible:
+			//oddballButton = new Button ("1 - Center") {
+			//	X = 1 - Pos.Center (),
+			//	Y = Pos.Bottom (oddballButton)
+			//};
+			//Application.Top.Add (oddballButton);
+
 			// This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
 			// The `- Pos.Percent(5)` is there so at least something is visible
 			oddballButton = new Button ("Center + Center - Percent(50)") {

+ 17 - 7
UICatalog/Scenarios/DimAutoDemo.cs

@@ -30,9 +30,9 @@ public class DimAutoDemo : Scenario {
 
 		var resetButton = new Button () {
 			Text = "P_ut Button Back",
-			X = Pos.Center (),
 			Y = Pos.Bottom (label)
 		};
+		resetButton.X = Pos.AnchorEnd () - 19;
 
 		var movingButton = new Button () {
 			Text = "Press to make button move down.",
@@ -44,9 +44,6 @@ public class DimAutoDemo : Scenario {
 			movingButton.Y = movingButton.Frame.Y + 1;
 		};
 
-		resetButton.Clicked += (s, e) => {
-			movingButton.Y = Pos.Bottom (resetButton);
-		};
 
 		var view = new FrameView () {
 			Title = "Type in the TextField to make View grow.",
@@ -58,6 +55,10 @@ public class DimAutoDemo : Scenario {
 		view.ValidatePosDim = true;
 		view.Add (textField, label, resetButton, movingButton);
 
+		resetButton.Clicked += (s, e) => {
+			movingButton.Y = Pos.Bottom (resetButton);
+		};
+
 		var dlgButton = new Button () {
 			Text = "Open Test _Dialog",
 			X = Pos.Right (view),
@@ -82,22 +83,31 @@ public class DimAutoDemo : Scenario {
 		//cancel.Clicked += (s, _) => Application.RequestStop (dlg);
 		//dlg.AddButton (cancel);
 
-		var label = new Label ("This is a label (AutoSize = false; Dim.Auto(3/20). Press Esc to close.") {
+		var label = new Label ("This is a label (AutoSize = false; Dim.Auto(3/20). Press Esc to close. Even more text.") {
 			AutoSize = false,
-			X = Pos.Center(),
+			X = Pos.Center (),
 			Y = 0,
 			Height = Dim.Auto (min: 3),
 			Width = Dim.Auto (min: 20),
 			ColorScheme = Colors.Menu
 		};
 
+		var text = new TextField () {
+			Text = "TextField... X = 1; Y = Pos.Bottom (label), Width = Dim.Fill (1); Height = Dim.Fill(1)",
+			TextFormatter = new TextFormatter () { WordWrap = true },
+			X = 20,
+			Y = Pos.Bottom (label),
+			Width = Dim.Fill (20),
+			Height = Dim.Fill (10)
+		};
 		var btn = new Button ("AnchorEnd") {
 			Y = Pos.AnchorEnd (1)
 		};
 		// TODO: We should really fix AnchorEnd to do this automatically. 
 		btn.X = Pos.AnchorEnd () - (Pos.Right (btn) - Pos.Left (btn));
-		dlg.Add (btn);
 		dlg.Add (label);
+		dlg.Add (text);
+		dlg.Add (btn);
 		Application.Run (dlg);
 	}
 }

+ 192 - 22
UnitTests/View/Layout/SetRelativeLayoutTests.cs

@@ -20,18 +20,18 @@ public class SetRelativeLayoutTests {
 		};
 
 		// Default layout style is Computed
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.Null (view.X);
 		Assert.Null (view.Y);
 
 		view.BeginInit(); view.EndInit();
 
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.Null (view.X);
 		Assert.Null (view.Y);
 
-		view.SetRelativeLayout(new Rect(5, 5, 10, 10));
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		view.SetRelativeLayout (new Rect (5, 5, 10, 10));
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.Null (view.X);
 		Assert.Null (view.Y);
 
@@ -50,18 +50,18 @@ public class SetRelativeLayoutTests {
 		};
 
 		// Default layout style is Computed
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.NotNull (view.X);
 		Assert.NotNull (view.Y);
 
 		view.BeginInit (); view.EndInit ();
 
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.NotNull (view.X);
 		Assert.NotNull (view.Y);
 
 		view.SetRelativeLayout (new Rect (5, 5, 10, 10));
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.NotNull (view.X);
 		Assert.NotNull (view.Y);
 
@@ -78,17 +78,17 @@ public class SetRelativeLayoutTests {
 		};
 
 		// Default layout style is Computed
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.Null (view.Width);
 		Assert.Null (view.Height);
 		view.BeginInit (); view.EndInit ();
 
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.Null (view.Width);
 		Assert.Null (view.Height);
 
 		view.SetRelativeLayout (new Rect (5, 5, 10, 10));
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.Null (view.Width);
 		Assert.Null (view.Height);
 		
@@ -118,17 +118,17 @@ public class SetRelativeLayoutTests {
 		};
 
 		// Default layout style is Computed
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.NotNull (view.Width);
 		Assert.NotNull (view.Height);
 		view.BeginInit (); view.EndInit ();
 
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.NotNull (view.Width);
 		Assert.NotNull (view.Height);
 
 		view.SetRelativeLayout (new Rect (5, 5, 10, 10));
-		Assert.Equal (view.LayoutStyle, LayoutStyle.Computed);
+		Assert.Equal (LayoutStyle.Computed, view.LayoutStyle);
 		Assert.NotNull (view.Width);
 		Assert.NotNull (view.Height);
 		
@@ -139,6 +139,93 @@ public class SetRelativeLayoutTests {
 		Assert.Equal (expectedDim, view.Frame.Height);
 	}
 
+	[Fact]
+	public void Fill_Pos_Within_Bounds ()
+	{
+		var screen = new Rect (0, 0, 80, 25);
+		var view = new View () {
+			X = 1,
+			Y = 1,
+			Width = 5,
+			Height = 4
+		};
+
+		view.SetRelativeLayout (screen);
+		Assert.Equal (1, view.Frame.X);
+		Assert.Equal (1, view.Frame.Y);
+		Assert.Equal (5, view.Frame.Width);
+		Assert.Equal (4, view.Frame.Height);
+
+		view.Width = 80;
+		view.Height = 25;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (1, view.Frame.X);
+		Assert.Equal (1, view.Frame.Y);
+		Assert.Equal (80, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.Width = Dim.Fill ();
+		view.Height = Dim.Fill ();
+		view.SetRelativeLayout (screen);
+		Assert.Equal (1, view.Frame.X);
+		Assert.Equal (1, view.Frame.Y);
+		Assert.Equal (79, view.Frame.Width); // proof (80 - 1)
+		Assert.Equal (24, view.Frame.Height); // proof (25 - 1)
+
+		view.X = 79;
+		view.Width = Dim.Fill ();
+		view.Height = Dim.Fill ();
+		view.SetRelativeLayout (screen);
+		Assert.Equal (79, view.Frame.X);
+		Assert.Equal (1, view.Frame.Y);
+		Assert.Equal (1, view.Frame.Width); // proof (80 - 79)
+		Assert.Equal (24, view.Frame.Height);
+
+		view.X = 80;
+		view.Width = Dim.Fill ();
+		view.Height = Dim.Fill ();
+		view.SetRelativeLayout (screen);
+		Assert.Equal (80, view.Frame.X);
+		Assert.Equal (1, view.Frame.Y);
+		Assert.Equal (0, view.Frame.Width);  // proof (80 - 80)
+		Assert.Equal (24, view.Frame.Height);
+	}
+
+	[Fact]
+	public void FIll_Pos_Outside_Bounds ()
+	{
+		var screen = new Rect (0, 0, 80, 25);
+		var view = new View () {
+			X = 90,  // outside of screen +10
+			Y = -10,   // outside of screen -10
+			Width = 15,
+			Height = 15
+		};
+
+		view.SetRelativeLayout (screen);
+		Assert.Equal (90, view.Frame.X);
+		Assert.Equal (-10, view.Frame.Y);
+		Assert.Equal (15, view.Frame.Width);
+		Assert.Equal (15, view.Frame.Height);
+
+		// prove Width=Height= same as screen size
+		view.Width = 80;
+		view.Height = 25;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (90, view.Frame.X);
+		Assert.Equal (-10, view.Frame.Y);
+		Assert.Equal (80, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.Width = Dim.Fill ();
+		view.Height = Dim.Fill ();
+		view.SetRelativeLayout (screen);
+		Assert.Equal (90, view.Frame.X);
+		Assert.Equal (-10, view.Frame.Y);
+		Assert.Equal (0, view.Frame.Width);    // proof: 15x15 view is placed beyond right side of screen, so fill width is 0
+		Assert.Equal (35, view.Frame.Height);  // proof: 15x15 view is placed beyond top of screen 10 rows, screen is 25 rows. so fill height is 25 + 10 = 35
+	}
+
 	[Fact]
 	public void PosCombine_PosCenter_Minus_Absolute ()
 	{
@@ -148,31 +235,114 @@ public class SetRelativeLayoutTests {
 
 		var screen = new Rect (0, 0, 80, 25);
 		var view = new View () {
-			X = Pos.Center () - 41,  // ((80 / 2) - (5 / 2)) - 41 = (40 - 2 - 41) = -3
-			Y = Pos.Center () - 13,  // ((25 / 2) - (4 / 2)) - 13 = (12 - 2 - 13) = -3
-			Width = 5,
-			Height = 4
+			X = Pos.Center () - 41,  // -2 off left edge of screen
+			Y = Pos.Center () - 13,  // -1 off top edge of screen
+			Width = 1,
+			Height = 1
 		};
 
 		view.SetRelativeLayout (screen);
-		Assert.Equal (-21, view.Frame.X); // BUGBUG: Should be -3
-		Assert.Equal (-7, view.Frame.Y);  // BUGBUG: Should be -3
+		Assert.Equal (-2, view.Frame.X); // proof: 1x1 view centered in 80x25 screen has x of 39, so -41 is -2
+		Assert.Equal (-1, view.Frame.Y); // proof: 1x1 view centered in 80x25 screen has y of 12, so -13 is -1
+
+		view.Width = 80;
+		view.Height = 25;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (-41, view.Frame.X);
+		Assert.Equal (-13, view.Frame.Y);
+		Assert.Equal (80, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.Width = Dim.Fill (); 
+		view.Height = Dim.Fill ();
+		view.SetRelativeLayout (screen);
+		Assert.Equal (-41, view.Frame.X); 
+		Assert.Equal (-13, view.Frame.Y);
+		Assert.Equal (121, view.Frame.Width);  // 121 = screen.Width - (-Center - 41)
+		Assert.Equal (38, view.Frame.Height);
 	}
 
+	[Fact]
+	public void FIll_And_PosCenter ()
+	{
+		var screen = new Rect (0, 0, 80, 25);
+		var view = new View () {
+			X = Pos.Center (),
+			Y = Pos.Center (),
+			Width = Dim.Fill(),
+			Height = Dim.Fill()
+		};
+
+		view.SetRelativeLayout (screen);
+		Assert.Equal (0, view.Frame.X); 
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (80, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () + 1;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (1, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (79, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () + 79;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (79, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (1, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () + 80;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (80, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (0, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () - 1;
+		view.SetRelativeLayout (screen);
+		Assert.Equal (-1, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (81, view.Frame.Width); 
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () - 2; // Fill means all the way to right. So width will be 82. (dim gets calc'd before pos).
+		view.SetRelativeLayout (screen);
+		Assert.Equal (-2, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (82, view.Frame.Width); 
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () - 3; // Fill means all the way to right. So width will be 83. (dim gets calc'd before pos).
+		view.SetRelativeLayout (screen);
+		Assert.Equal (-3, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (83, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+		view.X = Pos.Center () - 41; // Fill means all the way to right. So width will be . (dim gets calc'd before pos).
+		view.SetRelativeLayout (screen);
+		Assert.Equal (-41, view.Frame.X);
+		Assert.Equal (0, view.Frame.Y);
+		Assert.Equal (121, view.Frame.Width);
+		Assert.Equal (25, view.Frame.Height);
+
+	}
 	[Fact]
 	public void PosCombine_PosCenter_Plus_Absolute ()
 	{
 		var screen = new Rect (0, 0, 80, 25);
 		var view = new View () {
-			X = Pos.Center () + 41,  // ((80 / 2) - (5 / 2)) + 41 = (40 - 2 + 41) = 79
+			X = Pos.Center () + 41,  // ((80 / 2) - (5 / 2)) + 41 = (40 - 3 + 41) = 78
 			Y = Pos.Center () + 13,  // ((25 / 2) - (4 / 2)) + 13 = (12 - 2 + 13) = 23
 			Width = 5,
 			Height = 4
 		};
 
 		view.SetRelativeLayout (screen);
-		Assert.Equal (79, view.Frame.X); // BUGBUG: Should be 79
-		Assert.Equal (23, view.Frame.Y);  // BUGBUG: Should be 23
+		Assert.Equal (78, view.Frame.X);
+		Assert.Equal (23, view.Frame.Y);
 	}
 
 	[Fact] [TestRespondersDisposed]

+ 7 - 7
UnitTests/View/ViewTests.cs

@@ -547,13 +547,13 @@ namespace Terminal.Gui.ViewTests {
 			// This test has been moved to SetRlativeLayoutTests because it is testing
 			// SetRelativeLayout. In addition, the old test was bogus because it was testing the wrong thing (and 
 			// because in v1 Pos.Center was broken in this regard!
-			//view.X = Pos.Center () - 41;
-			//view.Y = Pos.Center () - 13;
-			//view.SetRelativeLayout (top.Bounds);
-			//top.LayoutSubviews (); // BUGBUG: v2 - ??
-			//view.BoundsToScreen (0, 0, out rcol, out rrow);
-			//Assert.Equal (-41, rcol);
-			//Assert.Equal (-13, rrow);
+			view.X = Pos.Center () - 41;
+			view.Y = Pos.Center () - 13;
+			view.SetRelativeLayout (top.Bounds);
+			top.LayoutSubviews (); // BUGBUG: v2 - ??
+			view.BoundsToScreen (0, 0, out rcol, out rrow);
+			Assert.Equal (-41, rcol);
+			Assert.Equal (-13, rrow);
 
 			Application.End (runState);
 		}