Browse Source

Implemented DimAuto(min)

Tig Kindel 1 year ago
parent
commit
a367e4d326

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

@@ -619,9 +619,9 @@ public class Dim {
 		if (style == DimAutoStyle.Text) {
 			throw new NotImplementedException (@"DimAutoStyle.Text is not implemented.");
 		}
-		if (min != null) {
-			throw new NotImplementedException (@"min is not implemented");
-		}
+		//if (min != null) {
+		//	throw new NotImplementedException (@"min is not implemented");
+		//}
 		if (max != null) {
 			throw new NotImplementedException (@"max is not implemented");
 		}

+ 10 - 5
Terminal.Gui/View/ViewLayout.cs

@@ -581,6 +581,11 @@ namespace Terminal.Gui {
 				SetNeedsLayout ();
 				SetNeedsDisplay ();
 			}
+
+			if (LayoutStyle == LayoutStyle.Computed && (SuperView?.Height is Dim.DimAuto || (SuperView?.Width is Dim.DimAuto))) {
+				// DimAuto is in play, force a layout.
+				SuperView.LayoutSubviews ();
+			}
 		}
 
 		internal bool LayoutNeeded { get; private set; } = true;
@@ -783,16 +788,16 @@ namespace Terminal.Gui {
 					newDimension = AutoSize && autosize > newDimension ? autosize : newDimension;
 					break;
 
-				case Dim.DimAuto:
+				case Dim.DimAuto auto:
 					var thickness = GetFramesThickness ();
 					if (width) {
 						var furthestRight = Subviews.Count == 0 ? 0 : Subviews.Max (v => v.Frame.X + v.Frame.Width);
-						newDimension = furthestRight + thickness.Left + thickness.Right;
+						//newDimension = furthestRight + thickness.Left + thickness.Right;
+						newDimension = int.Max (furthestRight + thickness.Left + thickness.Right, auto._min?.Anchor (0) ?? 0);
 					} else {
 						var furthestBottom = Subviews.Count == 0 ? 0 : Subviews.Max (v => v.Frame.Y + v.Frame.Height);
-						// TODO: GethashCode is a hack. 
-						//newDimension = int.Max(furthestBottom + thickness.Top + thickness.Bottom, ((Dim.DimAuto)d)._min.GetHashCode());
-						newDimension = furthestBottom + thickness.Top + thickness.Bottom;
+						newDimension = int.Max (furthestBottom + thickness.Top + thickness.Bottom, auto._min?.Anchor (0) ?? 0);
+						//newDimension = furthestBottom + thickness.Top + thickness.Bottom;
 					}
 					break;
 

+ 20 - 7
UICatalog/Scenarios/DimAutoSize.cs

@@ -21,30 +21,43 @@ public class DimAutoSize : Scenario {
 			X = Pos.Left (textField),
 			Y = Pos.Bottom (textField),
 			AutoSize = true,
+			ColorScheme = Colors.Error
 		};
 
 		textField.TextChanged += (s, e) => {
 			label.Text = textField.Text;
 		};
 
-		var button = new Button () { Text = "Press to make button move down.", 
+		var resetButton = new Button () {
+			Text = "P_ut Button Back",
+			X = 0,
+			Y = Pos.Bottom(label)
+		};
+
+		var movingButton = new Button () { Text = "Press to make button move down.", 
 			X = 0, 
-			Y = Pos.Bottom (label), 
+			Y = Pos.Bottom (resetButton), 
 			Width = 10
 		};
-		button.Clicked += (s, e) => {
-			button.Y = button.Frame.Y + 1;
+		movingButton.Clicked += (s, e) => {
+			movingButton.Y = movingButton.Frame.Y + 1;
+		};
+
+		resetButton.Clicked += (s, e) => {
+			movingButton.Y = Pos.Bottom (resetButton);
+			// BUGBUG: Should this be required? I don't thinks so.
+			//movingButton.SuperView.LayoutSubviews ();
 		};
 
 		var view = new FrameView () {
-			Title = "Type in the TextField to make it grow.",
+			Title = "Type in the TextField to make View grow.",
 			X = 3,
 			Y = 3,
 			Width = Dim.Auto (),
-			Height = Dim.Auto ()
+			Height = Dim.Auto (min: 10)
 		};
 		view.ValidatePosDim = true;
-		view.Add (textField, label, button);
+		view.Add (textField, label, resetButton, movingButton);
 
 		Application.Top.Add (view);
 	}

+ 111 - 0
UnitTests/View/Layout/DimAutoTests.cs

@@ -355,6 +355,117 @@ public class DimAutoTests {
 
 	}
 
+	// Test min - ensure that if min is specified in the DimAuto constructor it is honored
+	[Fact]
+	public void DimAuto_Min ()
+	{
+		var superView = new View () {
+			X = 0,
+			Y = 0,
+			Width = Dim.Auto (min: 10),
+			Height = Dim.Auto (min: 10),
+			ValidatePosDim = true,
+		};
+
+		var subView = new View () {
+			X = 0,
+			Y = 0,
+			Width = 5,
+			Height = 5
+		};
+
+		superView.Add (subView);
+		superView.BeginInit ();
+		superView.EndInit ();
+
+		superView.SetRelativeLayout (new Rect (0, 0, 0, 0));
+		superView.LayoutSubviews (); // no throw
+
+		Assert.Equal (10, superView.Frame.Width);
+		Assert.Equal (10, superView.Frame.Height);
+	}
+
+	[Fact]
+	public void DimAuto_Min_Resets_If_Subview_Shrinks ()
+	{
+		var superView = new View () {
+			X = 0,
+			Y = 0,
+			Width = Dim.Auto (min: 10),
+			Height = Dim.Auto (min: 10),
+			ValidatePosDim = true,
+		};
+
+		var subView = new View () {
+			X = 0,
+			Y = 0,
+			Width = 5,
+			Height = 5
+		};
+
+		superView.Add (subView);
+		superView.BeginInit ();
+		superView.EndInit ();
+
+		superView.SetRelativeLayout (new Rect (0, 0, 0, 0));
+		superView.LayoutSubviews (); // no throw
+
+		Assert.Equal (10, superView.Frame.Width);
+		Assert.Equal (10, superView.Frame.Height);
+
+		subView.Width = 3;
+		subView.Height = 3;
+		superView.SetRelativeLayout (new Rect (0, 0, 0, 0));
+		superView.LayoutSubviews (); // no throw
+
+		Assert.Equal (3, subView.Frame.Width);
+		Assert.Equal (3, subView.Frame.Height);
+
+		Assert.Equal (10, superView.Frame.Width);
+		Assert.Equal (10, superView.Frame.Height);
+	}
+
+	// what happens if DimAuto (min: 10) and the subview moves to a negative coord?
+	[Fact]
+	public void DimAuto_Min_Resets_If_Subview_Moves_Negative ()
+	{
+		var superView = new View () {
+			X = 0,
+			Y = 0,
+			Width = Dim.Auto (min: 10),
+			Height = Dim.Auto (min: 10),
+			ValidatePosDim = true,
+		};
+
+		var subView = new View () {
+			X = 0,
+			Y = 0,
+			Width = 5,
+			Height = 5
+		};
+
+		superView.Add (subView);
+		superView.BeginInit ();
+		superView.EndInit ();
+
+		superView.SetRelativeLayout (new Rect (0, 0, 0, 0));
+		superView.LayoutSubviews (); // no throw
+
+		Assert.Equal (10, superView.Frame.Width);
+		Assert.Equal (10, superView.Frame.Height);
+
+		subView.X = -1;
+		subView.Y = -1;
+		superView.SetRelativeLayout (new Rect (0, 0, 0, 0));
+		superView.LayoutSubviews (); // no throw
+
+		Assert.Equal (5, subView.Frame.Width);
+		Assert.Equal (5, subView.Frame.Height);
+
+		Assert.Equal (10, superView.Frame.Width);
+		Assert.Equal (10, superView.Frame.Height);
+	}
+
 	// Test variations of Frame
 
 }