ソースを参照

IndexOf now supports recursive search

Thomas 2 年 前
コミット
933f26f122
2 ファイル変更85 行追加9 行削除
  1. 45 9
      Terminal.Gui/Views/TileView.cs
  2. 40 0
      UnitTests/TileViewTests.cs

+ 45 - 9
Terminal.Gui/Views/TileView.cs

@@ -13,9 +13,6 @@ namespace Terminal.Gui {
 
 
 		TileView parentTileView;
 		TileView parentTileView;
 
 
-		/// TODO: Might be able to make Border virtual and override here
-		/// To make this more API friendly
-
 		/// <summary>
 		/// <summary>
 		/// Use this field instead of Border to create an integrated
 		/// Use this field instead of Border to create an integrated
 		/// Border in which lines connect with subviews and splitters
 		/// Border in which lines connect with subviews and splitters
@@ -48,7 +45,7 @@ namespace Terminal.Gui {
 			/// </summary>
 			/// </summary>
 			/// <remarks>
 			/// <remarks>
 			/// Title are not rendered for root level tiles if there is no
 			/// Title are not rendered for root level tiles if there is no
-			/// <see cref="TileView.IntegratedBorder"/> render into.
+			/// <see cref="TileView.IntegratedBorder"/> to render into.
 			///</remarks>
 			///</remarks>
 			public string Title { get; set; }
 			public string Title { get; set; }
 
 
@@ -120,7 +117,6 @@ namespace Terminal.Gui {
 		public void RebuildForTileCount (int count)
 		public void RebuildForTileCount (int count)
 		{
 		{
 			tiles = new List<Tile> ();
 			tiles = new List<Tile> ();
-			// TODO: keep these if growing
 			splitterDistances = new List<Pos> ();
 			splitterDistances = new List<Pos> ();
 			splitterLines = new List<TileViewLineView> ();
 			splitterLines = new List<TileViewLineView> ();
 
 
@@ -226,12 +222,52 @@ namespace Terminal.Gui {
 
 
 		///<summary>
 		///<summary>
 		/// Returns the index of the first <see cref="Tile"/> in
 		/// Returns the index of the first <see cref="Tile"/> in
-		/// <see cref="Tiles"/> which contains <paramref name="view"/>.
+		/// <see cref="Tiles"/> which contains <paramref name="toFind"/>.
 		///</summary>
 		///</summary>
-		public int IndexOf(View view)
+		public int IndexOf(View toFind, bool recursive = false)
+		{
+			for(int i = 0 ;i < tiles.Count; i++)
+			{
+				var v = tiles[i].View;
+
+				if(v == toFind)
+				{
+					return i;
+				}
+				
+				if(v.Subviews.Contains(toFind))
+				{
+					return i;
+				}
+
+				if(recursive)
+				{
+					if(RecursiveContains(v.Subviews,toFind))
+					{
+						return i;
+					}
+				}
+			}
+
+			return -1;
+		}
+
+		private bool RecursiveContains (IEnumerable<View> haystack, View needle)
 		{
 		{
-			// TODO: Could be recursive (i.e. search nested Subviews)
-			return tiles.IndexOf((t)=>t.View == view || t.View.Subviews.Contains(view));
+			foreach(var v in haystack)
+			{
+				if(v == needle)
+				{
+					return true;
+				}
+				
+				if(RecursiveContains(v.Subviews,needle))
+				{
+					return true;
+				}
+			}
+
+			return false;
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>

+ 40 - 0
UnitTests/TileViewTests.cs

@@ -824,6 +824,46 @@ namespace UnitTests {
 			Assert.Null (tileView.RemoveTile (0));
 			Assert.Null (tileView.RemoveTile (0));
 		}
 		}
 
 
+		[Theory,AutoInitShutdown]
+		[InlineData(true)]
+		[InlineData(false)]
+		public void TestTileView_IndexOf(bool recursive)
+		{
+			var tv = new TileView();
+			var lbl1 = new Label();
+			var lbl2 = new Label();
+			var frame = new FrameView();
+			var sub = new Label();
+			frame.Add(sub);
+
+			// IndexOf returns -1 when view not found
+			Assert.Equal(-1,tv.IndexOf(lbl1, recursive));
+			Assert.Equal(-1,tv.IndexOf(lbl2, recursive));
+
+			// IndexOf supports looking for Tile.View
+			Assert.Equal(0,tv.IndexOf(tv.Tiles.ElementAt(0).View, recursive));
+			Assert.Equal(1,tv.IndexOf(tv.Tiles.ElementAt(1).View, recursive));
+
+			// IndexOf supports looking for Tile.View.Subviews
+			tv.Tiles.ElementAt(0).View.Add(lbl1);
+			Assert.Equal(0,tv.IndexOf(lbl1, recursive));
+
+			tv.Tiles.ElementAt(1).View.Add(lbl2);
+			Assert.Equal(1,tv.IndexOf(lbl2, recursive));
+
+			// IndexOf supports looking deep into subviews only when
+			// the recursive true value is passed
+			tv.Tiles.ElementAt(1).View.Add(frame);
+			if(recursive)
+			{
+				Assert.Equal(1,tv.IndexOf(sub, recursive));
+			}
+			else
+			{
+				Assert.Equal(-1,tv.IndexOf(sub, recursive));
+			}
+		}
+
 		/// <summary>
 		/// <summary>
 		/// Creates a vertical orientation root container with left pane split into
 		/// Creates a vertical orientation root container with left pane split into
 		/// two (with horizontal splitter line).
 		/// two (with horizontal splitter line).