فهرست منبع

Fixes #1291. Combining two PosAbsolute or two DimAbsolute result on a PosAbsolute or DimAbsolute. (#1292)

BDisp 4 سال پیش
والد
کامیت
a492a52d79
3فایلهای تغییر یافته به همراه250 افزوده شده و 10 حذف شده
  1. 43 10
      Terminal.Gui/Core/PosDim.cs
  2. 104 0
      UnitTests/DimTests.cs
  3. 103 0
      UnitTests/PosTests.cs

+ 43 - 10
Terminal.Gui/Core/PosDim.cs

@@ -242,13 +242,12 @@ namespace Terminal.Gui {
 		/// <returns>The <see cref="Pos"/> that is the sum of the values of <c>left</c> and <c>right</c>.</returns>
 		public static Pos operator + (Pos left, Pos right)
 		{
-			PosCombine newPos = new PosCombine (true, left, right);
-			if (posCombine?.ToString () != newPos.ToString ()) {
-				var view = left as PosView;
-				if (view != null) {
-					view.Target.SetNeedsLayout ();
-				}
+			if (left is PosAbsolute && right is PosAbsolute) {
+				posCombine = null;
+				return new PosAbsolute (left.Anchor (0) + right.Anchor (0));
 			}
+			PosCombine newPos = new PosCombine (true, left, right);
+			SetPosCombine (left, newPos);
 			return posCombine = newPos;
 		}
 
@@ -260,13 +259,23 @@ namespace Terminal.Gui {
 		/// <returns>The <see cref="Pos"/> that is the <c>left</c> minus <c>right</c>.</returns>
 		public static Pos operator - (Pos left, Pos right)
 		{
+			if (left is PosAbsolute && right is PosAbsolute) {
+				posCombine = null;
+				return new PosAbsolute (left.Anchor (0) - right.Anchor (0));
+			}
 			PosCombine newPos = new PosCombine (false, left, right);
+			SetPosCombine (left, newPos);
+			return posCombine = newPos;
+		}
+
+		static void SetPosCombine (Pos left, PosCombine newPos)
+		{
 			if (posCombine?.ToString () != newPos.ToString ()) {
 				var view = left as PosView;
-				if (view != null)
+				if (view != null) {
 					view.Target.SetNeedsLayout ();
+				}
 			}
-			return posCombine = newPos;
 		}
 
 		internal class PosView : Pos {
@@ -526,6 +535,8 @@ namespace Terminal.Gui {
 
 		}
 
+		static DimCombine dimCombine;
+
 		/// <summary>
 		/// Adds a <see cref="Terminal.Gui.Dim"/> to a <see cref="Terminal.Gui.Dim"/>, yielding a new <see cref="Dim"/>.
 		/// </summary>
@@ -534,7 +545,13 @@ namespace Terminal.Gui {
 		/// <returns>The <see cref="Dim"/> that is the sum of the values of <c>left</c> and <c>right</c>.</returns>
 		public static Dim operator + (Dim left, Dim right)
 		{
-			return new DimCombine (true, left, right);
+			if (left is DimAbsolute && right is DimAbsolute) {
+				dimCombine = null;
+				return new DimAbsolute (left.Anchor (0) + right.Anchor (0));
+			}
+			DimCombine newDim = new DimCombine (true, left, right);
+			SetDimCombine (left, newDim);
+			return dimCombine = newDim;
 		}
 
 		/// <summary>
@@ -545,7 +562,23 @@ namespace Terminal.Gui {
 		/// <returns>The <see cref="Dim"/> that is the <c>left</c> minus <c>right</c>.</returns>
 		public static Dim operator - (Dim left, Dim right)
 		{
-			return new DimCombine (false, left, right);
+			if (left is DimAbsolute && right is DimAbsolute) {
+				dimCombine = null;
+				return new DimAbsolute (left.Anchor (0) - right.Anchor (0));
+			}
+			DimCombine newDim = new DimCombine (false, left, right);
+			SetDimCombine (left, newDim);
+			return dimCombine = newDim;
+		}
+
+		static void SetDimCombine (Dim left, DimCombine newPos)
+		{
+			if (dimCombine?.ToString () != newPos.ToString ()) {
+				var view = left as DimView;
+				if (view != null) {
+					view.Target.SetNeedsLayout ();
+				}
+			}
 		}
 
 		internal class DimView : Dim {

+ 104 - 0
UnitTests/DimTests.cs

@@ -590,5 +590,109 @@ namespace Terminal.Gui.Core {
 			Assert.Throws<InvalidOperationException> (() => Application.Run ());
 			Application.Shutdown ();
 		}
+
+
+		[Fact]
+		public void Dim_Add_Operator ()
+		{
+
+			Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
+
+			var top = Application.Top;
+
+			var view = new View () { X = 0, Y = 0, Width = 20, Height = 0 };
+			var field = new TextField () { X = 0, Y = Pos.Bottom (view), Width = 20 };
+			var count = 0;
+
+			field.KeyDown += (k) => {
+				if (k.KeyEvent.Key == Key.Enter) {
+					field.Text = $"Label {count}";
+					var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 };
+					view.Add (label);
+					Assert.Equal ($"Label {count}", label.Text);
+					Assert.Equal ($"Pos.Absolute({count})", label.Y.ToString ());
+
+					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+					view.Height += 1;
+					count++;
+					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+				}
+			};
+
+			Application.Iteration += () => {
+				while (count < 20) {
+					field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ()));
+				}
+
+				Application.RequestStop ();
+			};
+
+			var win = new Window ();
+			win.Add (view);
+			win.Add (field);
+
+			top.Add (win);
+
+			Application.Run (top);
+
+			Assert.Equal (20, count);
+		}
+
+		[Fact]
+		public void Dim_Subtract_Operator ()
+		{
+
+			Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
+
+			var top = Application.Top;
+
+			var view = new View () { X = 0, Y = 0, Width = 20, Height = 0 };
+			var field = new TextField () { X = 0, Y = Pos.Bottom (view), Width = 20 };
+			var count = 20;
+			var listLabels = new List<Label> ();
+
+			for (int i = 0; i < count; i++) {
+				field.Text = $"Label {i}";
+				var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 };
+				view.Add (label);
+				Assert.Equal ($"Label {i}", label.Text);
+				Assert.Equal ($"Pos.Absolute({i})", label.Y.ToString ());
+				listLabels.Add (label);
+
+				Assert.Equal ($"Dim.Absolute({i})", view.Height.ToString ());
+				view.Height += 1;
+				Assert.Equal ($"Dim.Absolute({i + 1})", view.Height.ToString ());
+			}
+
+			field.KeyDown += (k) => {
+				if (k.KeyEvent.Key == Key.Enter) {
+					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
+					view.Remove (listLabels [count - 1]);
+
+					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+					view.Height -= 1;
+					count--;
+					Assert.Equal ($"Dim.Absolute({count})", view.Height.ToString ());
+				}
+			};
+
+			Application.Iteration += () => {
+				while (count > 0) {
+					field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ()));
+				}
+
+				Application.RequestStop ();
+			};
+
+			var win = new Window ();
+			win.Add (view);
+			win.Add (field);
+
+			top.Add (win);
+
+			Application.Run (top);
+
+			Assert.Equal (0, count);
+		}
 	}
 }

+ 103 - 0
UnitTests/PosTests.cs

@@ -536,5 +536,108 @@ namespace Terminal.Gui.Core {
 			Assert.Throws<InvalidOperationException> (() => Application.Run ());
 			Application.Shutdown ();
 		}
+
+		[Fact]
+		public void Pos_Add_Operator ()
+		{
+
+			Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
+
+			var top = Application.Top;
+
+			var view = new View () { X = 0, Y = 0, Width = 20, Height = 20 };
+			var field = new TextField () { X = 0, Y = 0, Width = 20 };
+			var count = 0;
+
+			field.KeyDown += (k) => {
+				if (k.KeyEvent.Key == Key.Enter) {
+					field.Text = $"Label {count}";
+					var label = new Label (field.Text) { X = 0, Y = field.Y, Width = 20 };
+					view.Add (label);
+					Assert.Equal ($"Label {count}", label.Text);
+					Assert.Equal ($"Pos.Absolute({count})", label.Y.ToString ());
+
+					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+					field.Y += 1;
+					count++;
+					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+				}
+			};
+
+			Application.Iteration += () => {
+				while (count < 20) {
+					field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ()));
+				}
+
+				Application.RequestStop ();
+			};
+
+			var win = new Window ();
+			win.Add (view);
+			win.Add (field);
+
+			top.Add (win);
+
+			Application.Run (top);
+
+			Assert.Equal (20, count);
+		}
+
+		[Fact]
+		public void Pos_Subtract_Operator ()
+		{
+
+			Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
+
+			var top = Application.Top;
+
+			var view = new View () { X = 0, Y = 0, Width = 20, Height = 20 };
+			var field = new TextField () { X = 0, Y = 0, Width = 20 };
+			var count = 20;
+			var listLabels = new List<Label> ();
+
+			for (int i = 0; i < count; i++) {
+				field.Text = $"Label {i}";
+				var label = new Label (field.Text) { X = 0, Y = field.Y, Width = 20 };
+				view.Add (label);
+				Assert.Equal ($"Label {i}", label.Text);
+				Assert.Equal ($"Pos.Absolute({i})", field.Y.ToString ());
+				listLabels.Add (label);
+
+				Assert.Equal ($"Pos.Absolute({i})", field.Y.ToString ());
+				field.Y += 1;
+				Assert.Equal ($"Pos.Absolute({i + 1})", field.Y.ToString ());
+			}
+
+			field.KeyDown += (k) => {
+				if (k.KeyEvent.Key == Key.Enter) {
+					Assert.Equal ($"Label {count - 1}", listLabels [count - 1].Text);
+					view.Remove (listLabels [count - 1]);
+
+					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+					field.Y -= 1;
+					count--;
+					Assert.Equal ($"Pos.Absolute({count})", field.Y.ToString ());
+				}
+			};
+
+			Application.Iteration += () => {
+				while (count > 0) {
+					field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ()));
+				}
+
+				Application.RequestStop ();
+			};
+
+			var win = new Window ();
+			win.Add (view);
+			win.Add (field);
+
+			top.Add (win);
+
+			Application.Run (top);
+
+			Assert.Equal (0, count);
+		}
 	}
 }