2
0
Эх сурвалжийг харах

test for multi select, mouse fix and collapse selection fix

tznind 4 жил өмнө
parent
commit
01b899fb37

+ 22 - 19
Terminal.Gui/Views/TreeView.cs

@@ -714,25 +714,14 @@ namespace Terminal.Gui {
 						clickedBranch.Expand();
 					else {
 						SelectedObject = clickedBranch.Model; // It is a leaf node
+						_multiSelectedRegions.Clear();
 					}
 				}
 				else {
 
-
-					// The previously selected object
-					var oldBranch = SelectedObject == null ? null : ObjectToBranch(SelectedObject);
-					var oldIdx = oldBranch == null ? -1 : Array.IndexOf(map,oldBranch);
-
-					if(me.Flags.HasFlag(MouseFlags.ButtonShift))
-					{
-						// Expand current selection
-						AdjustSelection(1,true);
-					}
-					else{
-						// It is a first click somewhere in the current line that doesn't look like an expansion/collapse attempt
-						SelectedObject = clickedBranch.Model;
-						_multiSelectedRegions.Clear();
-					}
+					// It is a first click somewhere in the current line that doesn't look like an expansion/collapse attempt
+					SelectedObject = clickedBranch.Model;
+					_multiSelectedRegions.Clear();
 				}
 
 				SetNeedsDisplay();
@@ -914,7 +903,20 @@ namespace Terminal.Gui {
 			if(toCollapse == null)
 				return;
 
-			ObjectToBranch(toCollapse)?.Collapse();
+			var branch = ObjectToBranch(toCollapse);
+			
+			// Nothing to collapse
+			if(branch == null)
+				return;
+			
+			branch.Collapse();
+
+			if(SelectedObject != null && ObjectToBranch(SelectedObject) == null)
+			{
+				// If the old selection suddenly became invalid then clear it
+				SelectedObject = null;
+			}	
+			
 			SetNeedsDisplay();
 		}
 
@@ -929,7 +931,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Returns true if the <paramref name="model"/> is either the <see cref="SelectedObject"/> or part of a <see cref="MultiSelectedObjects"/>
+		/// Returns true if the <paramref name="model"/> is either the <see cref="SelectedObject"/> or part of a <see cref="MultiSelect"/>
 		/// </summary>
 		/// <param name="model"></param>
 		/// <returns></returns>
@@ -945,12 +947,14 @@ namespace Terminal.Gui {
 		/// <returns></returns>
 		public IEnumerable<T> GetAllSelectedObjects()
 		{
+			var map = BuildLineMap();
+
 			if(SelectedObject != null)
 				yield return SelectedObject;
 
 			// To determine multi selected objects, start with the line map, that avoids yielding hidden nodes that were selected then the parent collapsed e.g. programmatically or with mouse click
 			if(MultiSelect){
-				foreach(var m in BuildLineMap().Select(b=>b.Model).Where(IsSelected)){
+				foreach(var m in map.Select(b=>b.Model).Where(IsSelected)){
 					if(m != SelectedObject){
 						yield return m;
 					}
@@ -1377,7 +1381,6 @@ namespace Terminal.Gui {
 
 			return false;
 		}
-
 	}
 
 	/// <summary>

+ 49 - 0
UnitTests/TreeViewTests.cs

@@ -425,6 +425,55 @@ namespace UnitTests {
 		}
 
 
+		[Fact]
+		public void MultiSelect_GetAllSelectedObjects()
+		{
+			var tree = new TreeView();
+
+			TreeNode l1;
+			TreeNode l2;
+			TreeNode l3;
+			TreeNode l4;
+
+			var root = new TreeNode("Root");
+			root.Children.Add(l1 = new TreeNode("Leaf1"));
+			root.Children.Add(l2 = new TreeNode("Leaf2"));
+			root.Children.Add(l3 = new TreeNode("Leaf3"));
+			root.Children.Add(l4 = new TreeNode("Leaf4"));
+
+			tree.AddObject(root);
+			tree.MultiSelect = true;
+
+			tree.Expand(root);
+			Assert.Empty(tree.GetAllSelectedObjects());
+
+			tree.SelectedObject = root;
+
+			Assert.Equal(1,tree.GetAllSelectedObjects().Count());
+			Assert.Contains(root,tree.GetAllSelectedObjects());
+
+			// move selection down 1
+			tree.AdjustSelection(1,false);
+
+			Assert.Equal(1,tree.GetAllSelectedObjects().Count());
+			Assert.Contains(l1,tree.GetAllSelectedObjects());
+
+			// expand selection down 2 (e.g. shift down twice)
+			tree.AdjustSelection(1,true);
+			tree.AdjustSelection(1,true);
+
+			Assert.Equal(3,tree.GetAllSelectedObjects().Count());
+			Assert.Contains(l1,tree.GetAllSelectedObjects());
+			Assert.Contains(l2,tree.GetAllSelectedObjects());
+			Assert.Contains(l3,tree.GetAllSelectedObjects());
+
+			tree.Collapse(root);
+			
+			// No selected objects since the root was collapsed
+			Assert.Empty(tree.GetAllSelectedObjects());
+		}
+
+
 		/// <summary>
 		/// Simulates behind the scenes changes to an object (which children it has) and how to sync that into the tree using <see cref="TreeView.RefreshObject(object, bool)"/>
 		/// </summary>