浏览代码

Implement corner border style mixing in LineCanvas

Thomas 2 年之前
父节点
当前提交
f716dbe596
共有 2 个文件被更改,包括 128 次插入20 次删除
  1. 65 20
      Terminal.Gui/Core/Graphs/LineCanvas.cs
  2. 63 0
      UnitTests/LineCanvasTests.cs

+ 65 - 20
Terminal.Gui/Core/Graphs/LineCanvas.cs

@@ -113,40 +113,85 @@ namespace Terminal.Gui.Graphs {
 			protected abstract Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded);
 			protected abstract Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded);
 		}
 		}
 
 
-		private class ULIntersectionRuneResolver : IntersectionRuneResolver 
-		{
+		private abstract class CornerIntersectionRuneResolver : IntersectionRuneResolver {
 			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded)
 			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded)
 			{
 			{
-				// TODO: Handle all relevant permutations of double lines into single lines
-				// to make F type borders instead.
-				return useDouble ? driver.ULDCorner : useRounded ? driver.ULRCorner : driver.ULCorner;
+				
+				bool doubleHorizontal = intersects.Any(l=>l.Line.Orientation == Orientation.Horizontal && l.Line.Style == BorderStyle.Double);
+				bool doubleVertical = intersects.Any(l=>l.Line.Orientation == Orientation.Vertical && l.Line.Style == BorderStyle.Double);
+
+				return GetRuneForIntersects(driver,useRounded,doubleHorizontal,doubleVertical);
 			}
 			}
+
+			protected abstract Rune? GetRuneForIntersects(ConsoleDriver driver, bool useRounded, bool doubleHorizontal, bool doubleVertical);
 		}
 		}
-		private class URIntersectionRuneResolver : IntersectionRuneResolver 
+
+		private class ULIntersectionRuneResolver : CornerIntersectionRuneResolver 
 		{
 		{
-			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded)
+			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, bool useRounded, bool doubleHorizontal, bool doubleVertical)
 			{
 			{
-				// TODO: Handle all relevant permutations of double lines into single lines
-				// to make F type borders instead.
-				return useDouble ? driver.URDCorner : useRounded ? driver.URRCorner : driver.URCorner;
+				if(doubleHorizontal)
+				{
+						return doubleVertical ? driver.ULDCorner : '╒';
+				}
+				
+				if(doubleVertical)
+				{
+					return '╓';
+				}
+
+				return useRounded ? driver.ULRCorner : driver.ULCorner;
 			}
 			}
 		}
 		}
-		private class LLIntersectionRuneResolver : IntersectionRuneResolver 
+		private class URIntersectionRuneResolver : CornerIntersectionRuneResolver 
 		{
 		{
-			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded)
+			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, bool useRounded, bool doubleHorizontal, bool doubleVertical)
 			{
 			{
-				// TODO: Handle all relevant permutations of double lines into single lines
-				// to make F type borders instead.
-				return useDouble ? driver.LLDCorner : useRounded ? driver.LLRCorner : driver.LLCorner;
+				if(doubleHorizontal)
+				{
+						return doubleVertical ? driver.URDCorner : '╕';
+				}
+				
+				if(doubleVertical)
+				{
+					return '╖';
+				}
+				
+				return useRounded ? driver.URRCorner : driver.URCorner;
 			}
 			}
 		}
 		}
-		private class LRIntersectionRuneResolver : IntersectionRuneResolver 
+		private class LLIntersectionRuneResolver : CornerIntersectionRuneResolver 
 		{
 		{
-			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects, bool useDouble, bool useRounded)
+			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, bool useRounded, bool doubleHorizontal, bool doubleVertical)
 			{
 			{
-				// TODO: Handle all relevant permutations of double lines into single lines
-				// to make F type borders instead.
-				return useDouble ? driver.LRDCorner : useRounded ? driver.LRRCorner : driver.LRCorner;
+				if(doubleHorizontal)
+				{
+						return doubleVertical ? driver.LLDCorner : '╘';
+				}
+				
+				if(doubleVertical)
+				{
+					return '╙';
+				}
+
+				return useRounded ? driver.LLRCorner : driver.LLCorner;
+			}
+		}
+		private class LRIntersectionRuneResolver : CornerIntersectionRuneResolver 
+		{
+			protected override Rune? GetRuneForIntersects (ConsoleDriver driver, bool useRounded, bool doubleHorizontal, bool doubleVertical)
+			{
+				if(doubleHorizontal)
+				{
+						return doubleVertical ? driver.LRDCorner : '╛';
+				}
+				
+				if(doubleVertical)
+				{
+					return '╜';
+				}
+
+				return useRounded ? driver.LRRCorner : driver.LRCorner;
 			}
 			}
 		}
 		}
 		private class TopTeeIntersectionRuneResolver : IntersectionRuneResolver 
 		private class TopTeeIntersectionRuneResolver : IntersectionRuneResolver 

+ 63 - 0
UnitTests/LineCanvasTests.cs

@@ -218,6 +218,69 @@ namespace Terminal.Gui.Core {
 			TestHelpers.AssertDriverContentsAre (looksLike, output);
 			TestHelpers.AssertDriverContentsAre (looksLike, output);
 		}
 		}
 
 
+
+		[Theory, AutoInitShutdown]
+		[InlineData(BorderStyle.Single)]
+		[InlineData(BorderStyle.Rounded)]
+		public void TestLineCanvas_Window_DoubleTop_SingleSides (BorderStyle thinStyle)
+		{
+			var v = GetCanvas (out var canvas);
+
+			// outer box
+			canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, BorderStyle.Double);
+			canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, thinStyle);
+			canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal, BorderStyle.Double);
+			canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical, thinStyle);
+
+
+			canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, BorderStyle.Double);
+			canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, BorderStyle.Double);
+
+			v.Redraw (v.Bounds);
+
+// TODO: Fix those Ts!
+			string looksLike =
+@"    
+╒════╦═══╕
+│    ║   │
+╠════╬═══╣
+│    ║   │
+╘════╩═══╛
+";
+			TestHelpers.AssertDriverContentsAre (looksLike, output);
+		}
+
+		[Theory, AutoInitShutdown]
+		[InlineData(BorderStyle.Single)]
+		[InlineData(BorderStyle.Rounded)]
+		public void TestLineCanvas_Window_SingleTop_DoubleSides (BorderStyle thinStyle)
+		{
+			var v = GetCanvas (out var canvas);
+
+			// outer box
+			canvas.AddLine (new Point (0, 0), 9, Orientation.Horizontal, thinStyle);
+			canvas.AddLine (new Point (9, 0), 4, Orientation.Vertical, BorderStyle.Double);
+			canvas.AddLine (new Point (9, 4), -9, Orientation.Horizontal,thinStyle);
+			canvas.AddLine (new Point (0, 4), -4, Orientation.Vertical,  BorderStyle.Double);
+
+
+			canvas.AddLine (new Point (5, 0), 4, Orientation.Vertical, BorderStyle.Double);
+			canvas.AddLine (new Point (0, 2), 9, Orientation.Horizontal, BorderStyle.Double);
+
+			v.Redraw (v.Bounds);
+
+// TODO: Fix those Ts!
+			string looksLike =
+@"    
+╓────╦───╖
+║    ║   ║
+╠════╬═══╣
+║    ║   ║
+╙────╩───╜
+";
+			TestHelpers.AssertDriverContentsAre (looksLike, output);
+		}
+
 		private View GetCanvas (out LineCanvas canvas)
 		private View GetCanvas (out LineCanvas canvas)
 		{
 		{
 			var v = new View {
 			var v = new View {