浏览代码

Fix titles overruning bounds in some cases

tznind 2 年之前
父节点
当前提交
3cb983271b
共有 2 个文件被更改,包括 78 次插入6 次删除
  1. 21 3
      Terminal.Gui/Views/TileView.cs
  2. 57 3
      UnitTests/TileViewTests.cs

+ 21 - 3
Terminal.Gui/Views/TileView.cs

@@ -13,6 +13,7 @@ namespace Terminal.Gui {
 
 		TileView parentTileView;
 
+
 		/// <summary>
 		/// Use this field instead of Border to create an integrated
 		/// Border in which lines connect with subviews and splitters
@@ -391,7 +392,7 @@ namespace Terminal.Gui {
 
 				// TODO: Render with focus color if focused
 
-				var title = titleToRender.Tile.Title;
+				var title = titleToRender.GetTrimmedTitle();			
 
 				for (int i = 0; i < title.Length; i++) {
 					AddRune (renderAt.X + i, renderAt.Y, title [i]);
@@ -568,7 +569,7 @@ namespace Terminal.Gui {
 					titles.AddRange (GetAllTitlesToRenderRecursively (subTileView, depth + 1));
 				} else {
 					if (sub.Title.Length > 0) {
-						titles.Add (new TileTitleToRender (sub, depth));
+						titles.Add (new TileTitleToRender (v,sub, depth));
 					}
 				}
 			}
@@ -722,12 +723,14 @@ namespace Terminal.Gui {
 		}
 
 		private class TileTitleToRender {
+			public TileView Parent { get; }
 			public Tile Tile { get; }
 
 			public int Depth { get; }
 
-			public TileTitleToRender (Tile tile, int depth)
+			public TileTitleToRender (TileView parent, Tile tile, int depth)
 			{
+				Parent = parent;
 				Tile = tile;
 				Depth = depth;
 			}
@@ -742,6 +745,21 @@ namespace Terminal.Gui {
 				screenRow--;
 				return intoCoordinateSpace.ScreenToView (screenCol, screenRow);
 			}
+
+			internal string GetTrimmedTitle ()
+			{
+				Dim spaceDim = Tile.View.Width;
+
+				var spaceAbs = spaceDim.Anchor (Parent.Bounds.Width);
+
+				var title = Tile.Title;
+
+				if(title.Length > spaceAbs) {
+					return title.Substring (0, spaceAbs);
+				}
+
+				return title;
+			}
 		}
 
 		private class TileViewLineView : LineView {

+ 57 - 3
UnitTests/TileViewTests.cs

@@ -2013,6 +2013,56 @@ namespace UnitTests {
 
 		}
 
+		[Fact, AutoInitShutdown]
+		public void TestNestedContainer3RightAnd1Down_TitleDoesNotOverspill()
+		{
+			var tileView = GetNestedContainer3Right1Down (true,true,1);
+			tileView.Redraw (tileView.Bounds);
+
+			string looksLike =
+@"
+┌T1───┬T3────┬T2───┐
+│11111│333333│22222│
+│11111│333333│22222│
+│11111│333333│22222│
+│11111│333333│22222│
+│11111├T4────┤22222│
+│11111│444444│22222│
+│11111│444444│22222│
+│11111│444444│22222│
+└─────┴──────┴─────┘";
+
+			TestHelpers.AssertDriverContentsAre (looksLike, output);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void TestNestedContainer3RightAnd1Down_TitleTriesToOverspill ()
+		{
+			var tileView = GetNestedContainer3Right1Down (true, true, 1);
+
+			tileView.Tiles.ElementAt (0).Title = new string ('x', 100);
+
+			((TileView)tileView.Tiles.ElementAt (1).View)
+				.Tiles.ElementAt(1).Title = new string ('y', 100);
+
+			tileView.Redraw (tileView.Bounds);
+
+			string looksLike =
+@"
+┌xxxxx┬T3────┬T2───┐
+│11111│333333│22222│
+│11111│333333│22222│
+│11111│333333│22222│
+│11111│333333│22222│
+│11111├yyyyyy┤22222│
+│11111│444444│22222│
+│11111│444444│22222│
+│11111│444444│22222│
+└─────┴──────┴─────┘";
+
+			TestHelpers.AssertDriverContentsAre (looksLike, output);
+		}
+
 
 		/// <summary>
 		/// Creates a vertical orientation root container with left pane split into
@@ -2039,7 +2089,7 @@ namespace UnitTests {
 		/// </summary>
 		/// <param name="withBorder"></param>
 		/// <returns></returns>
-		private TileView GetNestedContainer3Right1Down (bool withBorder, bool withTitles = false)
+		private TileView GetNestedContainer3Right1Down (bool withBorder, bool withTitles = false, int split = 2)
 		{
 			var container =
 			new TileView (3) {
@@ -2048,12 +2098,16 @@ namespace UnitTests {
 				IntegratedBorder = withBorder ? BorderStyle.Single : BorderStyle.None
 			};
 
-			Assert.True (container.TrySplitTile (2, 2, out var newContainer));
+			Assert.True (container.TrySplitTile (split, 2, out var newContainer));
 
 			newContainer.Orientation = Terminal.Gui.Graphs.Orientation.Horizontal;
 
 			int i = 0;
-			foreach (var tile in container.Tiles.Take (2).Union (newContainer.Tiles)) {
+			foreach (var tile in container.Tiles.Union (newContainer.Tiles)) {
+				
+				if(tile.View is TileView) {
+					continue;
+				}
 				i++;
 
 				if (withTitles) {