Răsfoiți Sursa

Made ScrollOffset setter public and added helper method and tests

tznind 4 ani în urmă
părinte
comite
148b4d2784
2 a modificat fișierele cu 111 adăugiri și 2 ștergeri
  1. 29 2
      Terminal.Gui/Views/TreeView.cs
  2. 82 0
      UnitTests/TreeViewTests.cs

+ 29 - 2
Terminal.Gui/Views/TreeView.cs

@@ -26,6 +26,7 @@ namespace Terminal.Gui {
 	
 	
 		private ChildrenGetterDelegate childrenGetter;
 		private ChildrenGetterDelegate childrenGetter;
 		private CanExpandGetterDelegate canExpandGetter;
 		private CanExpandGetterDelegate canExpandGetter;
+		private int scrollOffset;
 
 
 		/// <summary>
 		/// <summary>
 		/// Optional delegate where <see cref="ChildrenGetter"/> is expensive.  This should quickly return true/false for whether an object is expandable.  (e.g. indicating to a user that all folders can be expanded because they are folders without having to calculate contents)
 		/// Optional delegate where <see cref="ChildrenGetter"/> is expensive.  This should quickly return true/false for whether an object is expandable.  (e.g. indicating to a user that all folders can be expanded because they are folders without having to calculate contents)
@@ -51,7 +52,7 @@ namespace Terminal.Gui {
 				selectedObject = value; 
 				selectedObject = value; 
 
 
 				if(!ReferenceEquals(oldValue,value))
 				if(!ReferenceEquals(oldValue,value))
-				SelectionChanged?.Invoke(this,new SelectionChangedEventArgs(this,oldValue,value));
+					SelectionChanged?.Invoke(this,new SelectionChangedEventArgs(this,oldValue,value));
 			}
 			}
 		}
 		}
 		
 		
@@ -74,7 +75,14 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// <summary>
 		/// The amount of tree view that has been scrolled off the top of the screen (by the user scrolling down)
 		/// The amount of tree view that has been scrolled off the top of the screen (by the user scrolling down)
 		/// </summary>
 		/// </summary>
-		public int ScrollOffset {get; private set;}
+		/// <remarks>Setting a value of less than 0 will result in a ScrollOffset of 0.  To see changes in the UI call <see cref="View.SetNeedsDisplay()"/></remarks>
+		public int ScrollOffset { 
+			get => scrollOffset;
+			set {
+				scrollOffset = Math.Max(0,value); 
+			}
+		}
+
 
 
 		/// <summary>
 		/// <summary>
 		/// Creates a new tree view with absolute positioning.  Use <see cref="AddObjects(IEnumerable{object})"/> to set set root objects for the tree
 		/// Creates a new tree view with absolute positioning.  Use <see cref="AddObjects(IEnumerable{object})"/> to set set root objects for the tree
@@ -173,6 +181,25 @@ namespace Terminal.Gui {
 					
 					
 			}
 			}
 		}
 		}
+		
+		/// <summary>
+		/// Returns the index of the object <paramref name="o"/> if it is currently exposed (it's parent(s) have been expanded).  This can be used with <see cref="ScrollOffset"/> and <see cref="View.SetNeedsDisplay()"/> to scroll to a specific object
+		/// </summary>
+		/// <remarks>Uses the Equals method and returns the first index at which the object is found or -1 if it is not found</remarks>
+		/// <param name="o">An object that appears in your tree and is currently exposed</param>
+		/// <returns>The index the object was found at or -1 if it is not currently revealed or not in the tree at all</returns>
+		public int GetScrollOffsetOf(object o)
+		{
+			var map = BuildLineMap();
+			for (int i = 0; i < map.Length; i++)
+			{
+				if (map[i].Model.Equals(o))
+					return i;
+			}
+
+			//object not found
+			return -1;
+		}
 
 
 		/// <summary>
 		/// <summary>
 		/// Calculates all currently visible/expanded branches (including leafs) and outputs them by index from the top of the screen
 		/// Calculates all currently visible/expanded branches (including leafs) and outputs them by index from the top of the screen

+ 82 - 0
UnitTests/TreeViewTests.cs

@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terminal.Gui;
+using Xunit;
+
+namespace UnitTests {
+	public class TreeViewTests 
+	{
+		#region Test Setup Methods
+		class Factory
+		{
+			public Car[] Cars {get;set;}
+		};
+		class Car {
+
+		};
+		
+		private TreeView CreateTree()
+		{
+			return CreateTree(out _, out _, out _);
+		}
+
+		private TreeView CreateTree(out Factory factory1, out Car car1, out Car car2)
+		{
+			car1 = new Car();
+			car2 = new Car();
+
+			factory1 = new Factory()
+			{
+				Cars = new []{car1 ,car2}
+			};
+			
+			var tree = new TreeView();
+			tree.ChildrenGetter = (s)=> s is Factory f ? f.Cars: null;
+			tree.AddObject(factory1);
+
+			return tree;
+		}
+		#endregion
+
+		[Fact]
+		public void ScrollOffset_CannotBeNegative()
+		{
+			var tree = CreateTree();
+
+			Assert.Equal(0,tree.ScrollOffset);
+
+			tree.ScrollOffset = -100;
+			Assert.Equal(0,tree.ScrollOffset);
+			
+			tree.ScrollOffset = 10;
+			Assert.Equal(10,tree.ScrollOffset);
+		}
+
+
+		[Fact]
+		public void GetScrollOffsetOf_MinusOneForUnRevealed()
+		{
+			var tree = CreateTree(out Factory f, out Car c1, out Car c2);
+			
+			Assert.Equal(0,tree.GetScrollOffsetOf(f));
+			Assert.Equal(-1,tree.GetScrollOffsetOf(c1));
+			Assert.Equal(-1,tree.GetScrollOffsetOf(c2));
+
+			//reveal it by expanding the root object
+			tree.Expand(f);
+			
+			Assert.Equal(0,tree.GetScrollOffsetOf(f));
+			Assert.Equal(1,tree.GetScrollOffsetOf(c1));
+			Assert.Equal(2,tree.GetScrollOffsetOf(c2));
+
+			tree.Collapse(f);
+			
+			Assert.Equal(0,tree.GetScrollOffsetOf(f));
+			Assert.Equal(-1,tree.GetScrollOffsetOf(c1));
+			Assert.Equal(-1,tree.GetScrollOffsetOf(c2));
+		}
+	}
+}