Selaa lähdekoodia

Added AllowLetterBasedNavigation - press S to go to next node beginning with 'S'

tznind 4 vuotta sitten
vanhempi
commit
d1a3b4807e
1 muutettua tiedostoa jossa 59 lisäystä ja 0 poistoa
  1. 59 0
      Terminal.Gui/Views/TreeView.cs

+ 59 - 0
Terminal.Gui/Views/TreeView.cs

@@ -318,6 +318,13 @@ namespace Terminal.Gui {
 		/// <value></value>
 		public bool MultiSelect {get;set;} = true;
 
+
+		/// <summary>
+		/// True makes a letter key press navigate to the next visible branch that begins with that letter/digit
+		/// </summary>
+		/// <value></value>
+		public bool AllowLetterBasedNavigation {get;set;} = true;
+
 		/// <summary>
 		/// The currently selected object in the tree.  When <see cref="MultiSelect"/> is true this is the object at which the cursor is at
 		/// </summary>
@@ -670,6 +677,21 @@ namespace Terminal.Gui {
 					return true;
 				 }				
 			}
+			
+			
+			var character = (char)keyEvent.KeyValue;
+
+			// if it is a singl character pressed without any control keys
+			if(char.IsLetterOrDigit(character) && AllowLetterBasedNavigation && !keyEvent.IsShift && !keyEvent.IsAlt && !keyEvent.IsCtrl)
+			{				
+				// search for next branch that begins with that letter
+				var characterAsStr = character.ToString();
+				AdjustSelectionToNext(b=>AspectGetter(b.Model).StartsWith(characterAsStr,StringComparison.CurrentCultureIgnoreCase));
+
+				PositionCursor ();
+				return true;
+			}
+			
 
 			switch (keyEvent.Key) {
 				
@@ -1023,6 +1045,43 @@ namespace Terminal.Gui {
 			GoToEnd();
 		}
 
+
+		/// <summary>
+		/// Sets the selection to the next branch that matches the <paramref name="predicate"/>
+		/// </summary>
+		/// <param name="predicate"></param>
+		private void AdjustSelectionToNext (Func<Branch<T>, bool> predicate)
+		{
+			var map = BuildLineMap();
+
+			// empty map means we can't select anything anyway
+			if(map.Length == 0)
+				return;
+			
+			// Start searching from the first element in the map
+			var idxStart = 0;
+			
+			// or the current selected branch
+			if(SelectedObject !=null)
+				idxStart = Array.FindIndex(map,b=>Equals(b.Model,SelectedObject));
+
+			// if currently selected object mysteriously vanished, search from beginning
+			if(idxStart == -1)
+				idxStart = 0;
+
+			// loop around all indexes and back to first index
+			for(int idxCur = (idxStart+1)%map.Length;idxCur != idxStart;idxCur = (idxCur+1) % map.Length)
+			{
+				if(predicate(map[idxCur]))
+				{
+					SelectedObject = map[idxCur].Model;
+					EnsureVisible(map[idxCur].Model);
+					SetNeedsDisplay();
+					return;
+				}
+			}
+		}
+
 		/// <summary>
 		/// Adjusts the <see cref="ScrollOffsetVertical"/> to ensure the given <paramref name="model"/> is visible.  Has no effect if already visible
 		/// </summary>