|
@@ -1,5 +1,5 @@
|
|
|
// This code is based on http://objectlistview.sourceforge.net (GPLv3 tree/list controls
|
|
|
-// by [email protected]). Phillip has explicitly granted permission for his design
|
|
|
+// by [email protected]). Phillip has explicitly granted permission for his design
|
|
|
// and code to be used in this library under the MIT license.
|
|
|
|
|
|
using NStack;
|
|
@@ -12,18 +12,18 @@ using Terminal.Gui.Trees;
|
|
|
namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Interface for all non generic members of <see cref="TreeView{T}"/>
|
|
|
+ /// Interface for all non generic members of <see cref="TreeView{T}"/>.
|
|
|
///
|
|
|
/// <a href="https://gui-cs.github.io/Terminal.Gui/articles/treeview.html">See TreeView Deep Dive for more information</a>.
|
|
|
/// </summary>
|
|
|
public interface ITreeView {
|
|
|
/// <summary>
|
|
|
- /// Contains options for changing how the tree is rendered
|
|
|
+ /// Contains options for changing how the tree is rendered.
|
|
|
/// </summary>
|
|
|
TreeStyle Style { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Removes all objects from the tree and clears selection
|
|
|
+ /// Removes all objects from the tree and clears selection.
|
|
|
/// </summary>
|
|
|
void ClearObjects ();
|
|
|
|
|
@@ -43,7 +43,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Creates a new instance of the tree control with absolute positioning and initialises
|
|
|
- /// <see cref="TreeBuilder{T}"/> with default <see cref="ITreeNode"/> based builder
|
|
|
+ /// <see cref="TreeBuilder{T}"/> with default <see cref="ITreeNode"/> based builder.
|
|
|
/// </summary>
|
|
|
public TreeView ()
|
|
|
{
|
|
@@ -53,8 +53,8 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Hierarchical tree view with expandable branches. Branch objects are dynamically determined
|
|
|
- /// when expanded using a user defined <see cref="ITreeBuilder{T}"/>
|
|
|
+ /// Hierarchical tree view with expandable branches. Branch objects are dynamically determined
|
|
|
+ /// when expanded using a user defined <see cref="ITreeBuilder{T}"/>.
|
|
|
///
|
|
|
/// <a href="https://gui-cs.github.io/Terminal.Gui/articles/treeview.html">See TreeView Deep Dive for more information</a>.
|
|
|
/// </summary>
|
|
@@ -64,7 +64,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Determines how sub branches of the tree are dynamically built at runtime as the user
|
|
|
- /// expands root nodes
|
|
|
+ /// expands root nodes.
|
|
|
/// </summary>
|
|
|
/// <value></value>
|
|
|
public ITreeBuilder<T> TreeBuilder { get; set; }
|
|
@@ -74,30 +74,27 @@ namespace Terminal.Gui {
|
|
|
/// </summary>
|
|
|
T selectedObject;
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// Contains options for changing how the tree is rendered
|
|
|
+ /// Contains options for changing how the tree is rendered.
|
|
|
/// </summary>
|
|
|
public TreeStyle Style { get; set; } = new TreeStyle ();
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// True to allow multiple objects to be selected at once
|
|
|
+ /// True to allow multiple objects to be selected at once.
|
|
|
/// </summary>
|
|
|
/// <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
|
|
|
+ /// 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
|
|
|
+ /// The currently selected object in the tree. When <see cref="MultiSelect"/> is true this
|
|
|
+ /// is the object at which the cursor is at.
|
|
|
/// </summary>
|
|
|
public T SelectedObject {
|
|
|
get => selectedObject;
|
|
@@ -111,16 +108,15 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// This event is raised when an object is activated e.g. by double clicking or
|
|
|
- /// pressing <see cref="ObjectActivationKey"/>
|
|
|
+ /// pressing <see cref="ObjectActivationKey"/>.
|
|
|
/// </summary>
|
|
|
public event Action<ObjectActivatedEventArgs<T>> ObjectActivated;
|
|
|
|
|
|
/// <summary>
|
|
|
/// Key which when pressed triggers <see cref="TreeView{T}.ObjectActivated"/>.
|
|
|
- /// Defaults to Enter
|
|
|
+ /// Defaults to Enter.
|
|
|
/// </summary>
|
|
|
public Key ObjectActivationKey {
|
|
|
get => objectActivationKey;
|
|
@@ -140,15 +136,14 @@ namespace Terminal.Gui {
|
|
|
/// <value></value>
|
|
|
public MouseFlags? ObjectActivationButton { get; set; } = MouseFlags.Button1DoubleClicked;
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// Delegate for multi colored tree views. Return the <see cref="ColorScheme"/> to use
|
|
|
+ /// Delegate for multi colored tree views. Return the <see cref="ColorScheme"/> to use
|
|
|
/// for each passed object or null to use the default.
|
|
|
/// </summary>
|
|
|
public Func<T, ColorScheme> ColorGetter { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Secondary selected regions of tree when <see cref="MultiSelect"/> is true
|
|
|
+ /// Secondary selected regions of tree when <see cref="MultiSelect"/> is true.
|
|
|
/// </summary>
|
|
|
private Stack<TreeSelection<T>> multiSelectedRegions = new Stack<TreeSelection<T>> ();
|
|
|
|
|
@@ -157,36 +152,35 @@ namespace Terminal.Gui {
|
|
|
/// </summary>
|
|
|
private IReadOnlyCollection<Branch<T>> cachedLineMap;
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// Error message to display when the control is not properly initialized at draw time
|
|
|
- /// (nodes added but no tree builder set)
|
|
|
+ /// (nodes added but no tree builder set).
|
|
|
/// </summary>
|
|
|
public static ustring NoBuilderError = "ERROR: TreeBuilder Not Set";
|
|
|
private Key objectActivationKey = Key.Enter;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Called when the <see cref="SelectedObject"/> changes
|
|
|
+ /// Called when the <see cref="SelectedObject"/> changes.
|
|
|
/// </summary>
|
|
|
public event EventHandler<SelectionChangedEventArgs<T>> SelectionChanged;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// The root objects in the tree, note that this collection is of root objects only
|
|
|
+ /// The root objects in the tree, note that this collection is of root objects only.
|
|
|
/// </summary>
|
|
|
public IEnumerable<T> Objects { get => roots.Keys; }
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Map of root objects to the branches under them. All objects have
|
|
|
- /// a <see cref="Branch{T}"/> even if that branch has no children
|
|
|
+ /// Map of root objects to the branches under them. All objects have
|
|
|
+ /// a <see cref="Branch{T}"/> even if that branch has no children.
|
|
|
/// </summary>
|
|
|
internal Dictionary<T, Branch<T>> roots { get; set; } = new Dictionary<T, Branch<T>> ();
|
|
|
|
|
|
/// <summary>
|
|
|
/// The amount of tree view that has been scrolled off the top of the screen (by the user
|
|
|
- /// scrolling down)
|
|
|
+ /// scrolling down).
|
|
|
/// </summary>
|
|
|
- /// <remarks>Setting a value of less than 0 will result in a offset of 0. To see changes
|
|
|
- /// in the UI call <see cref="View.SetNeedsDisplay()"/></remarks>
|
|
|
+ /// <remarks>Setting a value of less than 0 will result in a offset of 0. To see changes
|
|
|
+ /// in the UI call <see cref="View.SetNeedsDisplay()"/>.</remarks>
|
|
|
public int ScrollOffsetVertical {
|
|
|
get => scrollOffsetVertical;
|
|
|
set {
|
|
@@ -194,12 +188,11 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// The amount of tree view that has been scrolled to the right (horizontally)
|
|
|
+ /// The amount of tree view that has been scrolled to the right (horizontally).
|
|
|
/// </summary>
|
|
|
- /// <remarks>Setting a value of less than 0 will result in a offset of 0. To see changes
|
|
|
- /// in the UI call <see cref="View.SetNeedsDisplay()"/></remarks>
|
|
|
+ /// <remarks>Setting a value of less than 0 will result in a offset of 0. To see changes
|
|
|
+ /// in the UI call <see cref="View.SetNeedsDisplay()"/>.</remarks>
|
|
|
public int ScrollOffsetHorizontal {
|
|
|
get => scrollOffsetHorizontal;
|
|
|
set {
|
|
@@ -208,13 +201,13 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// The current number of rows in the tree (ignoring the controls bounds)
|
|
|
+ /// The current number of rows in the tree (ignoring the controls bounds).
|
|
|
/// </summary>
|
|
|
public int ContentHeight => BuildLineMap ().Count ();
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Returns the string representation of model objects hosted in the tree. Default
|
|
|
- /// implementation is to call <see cref="object.ToString"/>
|
|
|
+ /// Returns the string representation of model objects hosted in the tree. Default
|
|
|
+ /// implementation is to call <see cref="object.ToString"/>.
|
|
|
/// </summary>
|
|
|
/// <value></value>
|
|
|
public AspectGetterDelegate<T> AspectGetter { get; set; } = (o) => o.ToString () ?? "";
|
|
@@ -224,7 +217,7 @@ namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// Get / Set the wished cursor when the tree is focused.
|
|
|
/// Only applies when <see cref="MultiSelect"/> is true.
|
|
|
- /// Defaults to <see cref="CursorVisibility.Invisible"/>
|
|
|
+ /// Defaults to <see cref="CursorVisibility.Invisible"/>.
|
|
|
/// </summary>
|
|
|
public CursorVisibility DesiredCursorVisibility {
|
|
|
get {
|
|
@@ -241,9 +234,9 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Creates a new tree view with absolute positioning.
|
|
|
+ /// Creates a new tree view with absolute positioning.
|
|
|
/// Use <see cref="AddObjects(IEnumerable{T})"/> to set set root objects for the tree.
|
|
|
- /// Children will not be rendered until you set <see cref="TreeBuilder"/>
|
|
|
+ /// Children will not be rendered until you set <see cref="TreeBuilder"/>.
|
|
|
/// </summary>
|
|
|
public TreeView () : base ()
|
|
|
{
|
|
@@ -300,7 +293,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Initialises <see cref="TreeBuilder"/>.Creates a new tree view with absolute
|
|
|
- /// positioning. Use <see cref="AddObjects(IEnumerable{T})"/> to set set root
|
|
|
+ /// positioning. Use <see cref="AddObjects(IEnumerable{T})"/> to set set root
|
|
|
/// objects for the tree.
|
|
|
/// </summary>
|
|
|
public TreeView (ITreeBuilder<T> builder) : this ()
|
|
@@ -317,7 +310,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Adds a new root level object unless it is already a root of the tree
|
|
|
+ /// Adds a new root level object unless it is already a root of the tree.
|
|
|
/// </summary>
|
|
|
/// <param name="o"></param>
|
|
|
public void AddObject (T o)
|
|
@@ -329,9 +322,8 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// Removes all objects from the tree and clears <see cref="SelectedObject"/>
|
|
|
+ /// Removes all objects from the tree and clears <see cref="SelectedObject"/>.
|
|
|
/// </summary>
|
|
|
public void ClearObjects ()
|
|
|
{
|
|
@@ -346,7 +338,7 @@ namespace Terminal.Gui {
|
|
|
/// Removes the given root object from the tree
|
|
|
/// </summary>
|
|
|
/// <remarks>If <paramref name="o"/> is the currently <see cref="SelectedObject"/> then the
|
|
|
- /// selection is cleared</remarks>
|
|
|
+ /// selection is cleared</remarks>.
|
|
|
/// <param name="o"></param>
|
|
|
public void Remove (T o)
|
|
|
{
|
|
@@ -362,9 +354,9 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Adds many new root level objects. Objects that are already root objects are ignored
|
|
|
+ /// Adds many new root level objects. Objects that are already root objects are ignored.
|
|
|
/// </summary>
|
|
|
- /// <param name="collection">Objects to add as new root level objects</param>
|
|
|
+ /// <param name="collection">Objects to add as new root level objects.</param>.\
|
|
|
public void AddObjects (IEnumerable<T> collection)
|
|
|
{
|
|
|
bool objectsAdded = false;
|
|
@@ -383,13 +375,13 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Refreshes the state of the object <paramref name="o"/> in the tree. This will
|
|
|
- /// recompute children, string representation etc
|
|
|
+ /// Refreshes the state of the object <paramref name="o"/> in the tree. This will
|
|
|
+ /// recompute children, string representation etc.
|
|
|
/// </summary>
|
|
|
/// <remarks>This has no effect if the object is not exposed in the tree.</remarks>
|
|
|
/// <param name="o"></param>
|
|
|
/// <param name="startAtTop">True to also refresh all ancestors of the objects branch
|
|
|
- /// (starting with the root). False to refresh only the passed node</param>
|
|
|
+ /// (starting with the root). False to refresh only the passed node.</param>
|
|
|
public void RefreshObject (T o, bool startAtTop = false)
|
|
|
{
|
|
|
var branch = ObjectToBranch (o);
|
|
@@ -404,7 +396,7 @@ namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// Rebuilds the tree structure for all exposed objects starting with the root objects.
|
|
|
/// Call this method when you know there are changes to the tree but don't know which
|
|
|
- /// objects have changed (otherwise use <see cref="RefreshObject(T, bool)"/>)
|
|
|
+ /// objects have changed (otherwise use <see cref="RefreshObject(T, bool)"/>).
|
|
|
/// </summary>
|
|
|
public void RebuildTree ()
|
|
|
{
|
|
@@ -417,10 +409,10 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Returns the currently expanded children of the passed object. Returns an empty
|
|
|
- /// collection if the branch is not exposed or not expanded
|
|
|
+ /// Returns the currently expanded children of the passed object. Returns an empty
|
|
|
+ /// collection if the branch is not exposed or not expanded.
|
|
|
/// </summary>
|
|
|
- /// <param name="o">An object in the tree</param>
|
|
|
+ /// <param name="o">An object in the tree.</param>
|
|
|
/// <returns></returns>
|
|
|
public IEnumerable<T> GetChildren (T o)
|
|
|
{
|
|
@@ -433,10 +425,10 @@ namespace Terminal.Gui {
|
|
|
return branch.ChildBranches?.Values?.Select (b => b.Model)?.ToArray () ?? new T [0];
|
|
|
}
|
|
|
/// <summary>
|
|
|
- /// Returns the parent object of <paramref name="o"/> in the tree. Returns null if
|
|
|
- /// the object is not exposed in the tree
|
|
|
+ /// Returns the parent object of <paramref name="o"/> in the tree. Returns null if
|
|
|
+ /// the object is not exposed in the tree.
|
|
|
/// </summary>
|
|
|
- /// <param name="o">An object in the tree</param>
|
|
|
+ /// <param name="o">An object in the tree.</param>
|
|
|
/// <returns></returns>
|
|
|
public T GetParent (T o)
|
|
|
{
|
|
@@ -473,20 +465,19 @@ namespace Terminal.Gui {
|
|
|
Driver.SetAttribute (GetNormalColor ());
|
|
|
Driver.AddStr (new string (' ', bounds.Width));
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <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="ScrollOffsetVertical"/>
|
|
|
- /// and <see cref="View.SetNeedsDisplay()"/> to scroll to a specific object
|
|
|
+ /// parent(s) have been expanded). This can be used with <see cref="ScrollOffsetVertical"/>
|
|
|
+ /// 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>
|
|
|
+ /// 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>
|
|
|
+ /// not in the tree at all.</returns>
|
|
|
public int GetScrollOffsetOf (T o)
|
|
|
{
|
|
|
var map = BuildLineMap ();
|
|
@@ -501,11 +492,11 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Returns the maximum width line in the tree including prefix and expansion symbols
|
|
|
+ /// Returns the maximum width line in the tree including prefix and expansion symbols.
|
|
|
/// </summary>
|
|
|
/// <param name="visible">True to consider only rows currently visible (based on window
|
|
|
- /// bounds and <see cref="ScrollOffsetVertical"/>. False to calculate the width of
|
|
|
- /// every exposed branch in the tree</param>
|
|
|
+ /// bounds and <see cref="ScrollOffsetVertical"/>. False to calculate the width of
|
|
|
+ /// every exposed branch in the tree.</param>
|
|
|
/// <returns></returns>
|
|
|
public int GetContentWidth (bool visible)
|
|
|
{
|
|
@@ -536,7 +527,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Calculates all currently visible/expanded branches (including leafs) and outputs them
|
|
|
- /// by index from the top of the screen
|
|
|
+ /// by index from the top of the screen.
|
|
|
/// </summary>
|
|
|
/// <remarks>Index 0 of the returned array is the first item that should be visible in the
|
|
|
/// top of the control, index 1 is the next etc.</remarks>
|
|
@@ -553,7 +544,11 @@ namespace Terminal.Gui {
|
|
|
toReturn.AddRange (AddToLineMap (root));
|
|
|
}
|
|
|
|
|
|
- return cachedLineMap = new ReadOnlyCollection<Branch<T>> (toReturn);
|
|
|
+ cachedLineMap = new ReadOnlyCollection<Branch<T>> (toReturn);
|
|
|
+
|
|
|
+ // Update the collection used for search-typing
|
|
|
+ KeystrokeNavigator.Collection = cachedLineMap.Select (b => AspectGetter (b.Model)).ToArray ();
|
|
|
+ return cachedLineMap;
|
|
|
}
|
|
|
|
|
|
private IEnumerable<Branch<T>> AddToLineMap (Branch<T> currentBranch)
|
|
@@ -561,7 +556,6 @@ namespace Terminal.Gui {
|
|
|
yield return currentBranch;
|
|
|
|
|
|
if (currentBranch.IsExpanded) {
|
|
|
-
|
|
|
foreach (var subBranch in currentBranch.ChildBranches.Values) {
|
|
|
foreach (var sub in AddToLineMap (subBranch)) {
|
|
|
yield return sub;
|
|
@@ -570,6 +564,12 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Gets the <see cref="CollectionNavigator"/> that searches the <see cref="Objects"/> collection as
|
|
|
+ /// the user types.
|
|
|
+ /// </summary>
|
|
|
+ public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator ();
|
|
|
+
|
|
|
/// <inheritdoc/>
|
|
|
public override bool ProcessKey (KeyEvent keyEvent)
|
|
|
{
|
|
@@ -577,21 +577,33 @@ namespace Terminal.Gui {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- // if it is a single character pressed without any control keys
|
|
|
- if (keyEvent.KeyValue > 0 && keyEvent.KeyValue < 0xFFFF) {
|
|
|
-
|
|
|
- if (char.IsLetterOrDigit ((char)keyEvent.KeyValue) && AllowLetterBasedNavigation && !keyEvent.IsShift && !keyEvent.IsAlt && !keyEvent.IsCtrl) {
|
|
|
- AdjustSelectionToNextItemBeginningWith ((char)keyEvent.KeyValue);
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
try {
|
|
|
+ // First of all deal with any registered keybindings
|
|
|
var result = InvokeKeybindings (keyEvent);
|
|
|
- if (result != null)
|
|
|
+ if (result != null) {
|
|
|
return (bool)result;
|
|
|
- } finally {
|
|
|
+ }
|
|
|
|
|
|
+ // If not a keybinding, is the key a searchable key press?
|
|
|
+ if (CollectionNavigator.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation) {
|
|
|
+ IReadOnlyCollection<Branch<T>> map;
|
|
|
+
|
|
|
+ // If there has been a call to InvalidateMap since the last time
|
|
|
+ // we need a new one to reflect the new exposed tree state
|
|
|
+ map = BuildLineMap ();
|
|
|
+
|
|
|
+ // Find the current selected object within the tree
|
|
|
+ var current = map.IndexOf (b => b.Model == SelectedObject);
|
|
|
+ var newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent.KeyValue);
|
|
|
+
|
|
|
+ if (newIndex is int && newIndex != -1) {
|
|
|
+ SelectedObject = map.ElementAt ((int)newIndex).Model;
|
|
|
+ EnsureVisible (selectedObject);
|
|
|
+ SetNeedsDisplay ();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
PositionCursor ();
|
|
|
}
|
|
|
|
|
@@ -602,7 +614,7 @@ namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// <para>Triggers the <see cref="ObjectActivated"/> event with the <see cref="SelectedObject"/>.</para>
|
|
|
///
|
|
|
- /// <para>This method also ensures that the selected object is visible</para>
|
|
|
+ /// <para>This method also ensures that the selected object is visible.</para>
|
|
|
/// </summary>
|
|
|
public void ActivateSelectedObjectIfAny ()
|
|
|
{
|
|
@@ -638,11 +650,11 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// <para>Moves the <see cref="SelectedObject"/> to the next item that begins with <paramref name="character"/></para>
|
|
|
- /// <para>This method will loop back to the start of the tree if reaching the end without finding a match</para>
|
|
|
+ /// <para>Moves the <see cref="SelectedObject"/> to the next item that begins with <paramref name="character"/>.</para>
|
|
|
+ /// <para>This method will loop back to the start of the tree if reaching the end without finding a match.</para>
|
|
|
/// </summary>
|
|
|
- /// <param name="character">The first character of the next item you want selected</param>
|
|
|
- /// <param name="caseSensitivity">Case sensitivity of the search</param>
|
|
|
+ /// <param name="character">The first character of the next item you want selected.</param>
|
|
|
+ /// <param name="caseSensitivity">Case sensitivity of the search.</param>
|
|
|
public void AdjustSelectionToNextItemBeginningWith (char character, StringComparison caseSensitivity = StringComparison.CurrentCultureIgnoreCase)
|
|
|
{
|
|
|
// search for next branch that begins with that letter
|
|
@@ -655,7 +667,7 @@ namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// Moves the selection up by the height of the control (1 page).
|
|
|
/// </summary>
|
|
|
- /// <param name="expandSelection">True if the navigation should add the covered nodes to the selected current selection</param>
|
|
|
+ /// <param name="expandSelection">True if the navigation should add the covered nodes to the selected current selection.</param>
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
public void MovePageUp (bool expandSelection = false)
|
|
|
{
|
|
@@ -665,7 +677,7 @@ namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// Moves the selection down by the height of the control (1 page).
|
|
|
/// </summary>
|
|
|
- /// <param name="expandSelection">True if the navigation should add the covered nodes to the selected current selection</param>
|
|
|
+ /// <param name="expandSelection">True if the navigation should add the covered nodes to the selected current selection.</param>
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
public void MovePageDown (bool expandSelection = false)
|
|
|
{
|
|
@@ -673,7 +685,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Scrolls the view area down a single line without changing the current selection
|
|
|
+ /// Scrolls the view area down a single line without changing the current selection.
|
|
|
/// </summary>
|
|
|
public void ScrollDown ()
|
|
|
{
|
|
@@ -682,7 +694,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Scrolls the view area up a single line without changing the current selection
|
|
|
+ /// Scrolls the view area up a single line without changing the current selection.
|
|
|
/// </summary>
|
|
|
public void ScrollUp ()
|
|
|
{
|
|
@@ -691,7 +703,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Raises the <see cref="ObjectActivated"/> event
|
|
|
+ /// Raises the <see cref="ObjectActivated"/> event.
|
|
|
/// </summary>
|
|
|
/// <param name="e"></param>
|
|
|
protected virtual void OnObjectActivated (ObjectActivatedEventArgs<T> e)
|
|
@@ -700,15 +712,15 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Returns the object in the tree list that is currently visible
|
|
|
- /// at the provided row. Returns null if no object is at that location.
|
|
|
+ /// Returns the object in the tree list that is currently visible.
|
|
|
+ /// at the provided row. Returns null if no object is at that location.
|
|
|
/// <remarks>
|
|
|
/// </remarks>
|
|
|
/// If you have screen coordinates then use <see cref="View.ScreenToView(int, int)"/>
|
|
|
/// to translate these into the client area of the <see cref="TreeView{T}"/>.
|
|
|
/// </summary>
|
|
|
- /// <param name="row">The row of the <see cref="View.Bounds"/> of the <see cref="TreeView{T}"/></param>
|
|
|
- /// <returns>The object currently displayed on this row or null</returns>
|
|
|
+ /// <param name="row">The row of the <see cref="View.Bounds"/> of the <see cref="TreeView{T}"/>.</param>
|
|
|
+ /// <returns>The object currently displayed on this row or null.</returns>
|
|
|
public T GetObjectOnRow (int row)
|
|
|
{
|
|
|
return HitTest (row)?.Model;
|
|
@@ -733,7 +745,6 @@ namespace Terminal.Gui {
|
|
|
SetFocus ();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
if (me.Flags == MouseFlags.WheeledDown) {
|
|
|
|
|
|
ScrollDown ();
|
|
@@ -789,7 +800,6 @@ namespace Terminal.Gui {
|
|
|
multiSelectedRegions.Clear ();
|
|
|
}
|
|
|
} 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 ();
|
|
@@ -819,16 +829,15 @@ namespace Terminal.Gui {
|
|
|
// mouse event is handled.
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns the branch at the given <paramref name="y"/> client
|
|
|
- /// coordinate e.g. following a click event
|
|
|
+ /// coordinate e.g. following a click event.
|
|
|
/// </summary>
|
|
|
- /// <param name="y">Client Y position in the controls bounds</param>
|
|
|
- /// <returns>The clicked branch or null if outside of tree region</returns>
|
|
|
+ /// <param name="y">Client Y position in the controls bounds.</param>
|
|
|
+ /// <returns>The clicked branch or null if outside of tree region.</returns>
|
|
|
private Branch<T> HitTest (int y)
|
|
|
{
|
|
|
var map = BuildLineMap ();
|
|
@@ -845,7 +854,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Positions the cursor at the start of the selected objects line (if visible)
|
|
|
+ /// Positions the cursor at the start of the selected objects line (if visible).
|
|
|
/// </summary>
|
|
|
public override void PositionCursor ()
|
|
|
{
|
|
@@ -866,11 +875,10 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// Determines systems behaviour when the left arrow key is pressed. Default behaviour is
|
|
|
+ /// Determines systems behaviour when the left arrow key is pressed. Default behaviour is
|
|
|
/// to collapse the current tree node if possible otherwise changes selection to current
|
|
|
- /// branches parent
|
|
|
+ /// branches parent.
|
|
|
/// </summary>
|
|
|
protected virtual void CursorLeft (bool ctrl)
|
|
|
{
|
|
@@ -894,7 +902,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Changes the <see cref="SelectedObject"/> to the first root object and resets
|
|
|
- /// the <see cref="ScrollOffsetVertical"/> to 0
|
|
|
+ /// the <see cref="ScrollOffsetVertical"/> to 0.
|
|
|
/// </summary>
|
|
|
public void GoToFirst ()
|
|
|
{
|
|
@@ -906,7 +914,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Changes the <see cref="SelectedObject"/> to the last object in the tree and scrolls so
|
|
|
- /// that it is visible
|
|
|
+ /// that it is visible.
|
|
|
/// </summary>
|
|
|
public void GoToEnd ()
|
|
|
{
|
|
@@ -919,8 +927,8 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Changes the <see cref="SelectedObject"/> to <paramref name="toSelect"/> and scrolls to ensure
|
|
|
- /// it is visible. Has no effect if <paramref name="toSelect"/> is not exposed in the tree (e.g.
|
|
|
- /// its parents are collapsed)
|
|
|
+ /// it is visible. Has no effect if <paramref name="toSelect"/> is not exposed in the tree (e.g.
|
|
|
+ /// its parents are collapsed).
|
|
|
/// </summary>
|
|
|
/// <param name="toSelect"></param>
|
|
|
public void GoTo (T toSelect)
|
|
@@ -935,14 +943,14 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// The number of screen lines to move the currently selected object by. Supports negative
|
|
|
- /// <paramref name="offset"/>. Each branch occupies 1 line on screen
|
|
|
+ /// The number of screen lines to move the currently selected object by. Supports negative values.
|
|
|
+ /// <paramref name="offset"/>. Each branch occupies 1 line on screen.
|
|
|
/// </summary>
|
|
|
/// <remarks>If nothing is currently selected or the selected object is no longer in the tree
|
|
|
- /// then the first object in the tree is selected instead</remarks>
|
|
|
+ /// then the first object in the tree is selected instead.</remarks>
|
|
|
/// <param name="offset">Positive to move the selection down the screen, negative to move it up</param>
|
|
|
/// <param name="expandSelection">True to expand the selection (assuming
|
|
|
- /// <see cref="MultiSelect"/> is enabled). False to replace</param>
|
|
|
+ /// <see cref="MultiSelect"/> is enabled). False to replace.</param>
|
|
|
public void AdjustSelection (int offset, bool expandSelection = false)
|
|
|
{
|
|
|
// if it is not a shift click or we don't allow multi select
|
|
@@ -958,7 +966,6 @@ namespace Terminal.Gui {
|
|
|
var idx = map.IndexOf (b => b.Model.Equals (SelectedObject));
|
|
|
|
|
|
if (idx == -1) {
|
|
|
-
|
|
|
// The current selection has disapeared!
|
|
|
SelectedObject = roots.Keys.FirstOrDefault ();
|
|
|
} else {
|
|
@@ -982,14 +989,12 @@ namespace Terminal.Gui {
|
|
|
|
|
|
EnsureVisible (SelectedObject);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
SetNeedsDisplay ();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Moves the selection to the first child in the currently selected level
|
|
|
+ /// Moves the selection to the first child in the currently selected level.
|
|
|
/// </summary>
|
|
|
public void AdjustSelectionToBranchStart ()
|
|
|
{
|
|
@@ -1029,7 +1034,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Moves the selection to the last child in the currently selected level
|
|
|
+ /// Moves the selection to the last child in the currently selected level.
|
|
|
/// </summary>
|
|
|
public void AdjustSelectionToBranchEnd ()
|
|
|
{
|
|
@@ -1063,13 +1068,12 @@ namespace Terminal.Gui {
|
|
|
currentBranch = next;
|
|
|
next = map.ElementAt (currentIdx);
|
|
|
}
|
|
|
-
|
|
|
GoToEnd ();
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Sets the selection to the next branch that matches the <paramref name="predicate"/>
|
|
|
+ /// 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)
|
|
@@ -1107,7 +1111,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Adjusts the <see cref="ScrollOffsetVertical"/> to ensure the given
|
|
|
- /// <paramref name="model"/> is visible. Has no effect if already visible
|
|
|
+ /// <paramref name="model"/> is visible. Has no effect if already visible.
|
|
|
/// </summary>
|
|
|
public void EnsureVisible (T model)
|
|
|
{
|
|
@@ -1134,7 +1138,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Expands the currently <see cref="SelectedObject"/>
|
|
|
+ /// Expands the currently <see cref="SelectedObject"/>.
|
|
|
/// </summary>
|
|
|
public void Expand ()
|
|
|
{
|
|
@@ -1143,9 +1147,9 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Expands the supplied object if it is contained in the tree (either as a root object or
|
|
|
- /// as an exposed branch object)
|
|
|
+ /// as an exposed branch object).
|
|
|
/// </summary>
|
|
|
- /// <param name="toExpand">The object to expand</param>
|
|
|
+ /// <param name="toExpand">The object to expand.</param>
|
|
|
public void Expand (T toExpand)
|
|
|
{
|
|
|
if (toExpand == null) {
|
|
@@ -1158,9 +1162,9 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Expands the supplied object and all child objects
|
|
|
+ /// Expands the supplied object and all child objects.
|
|
|
/// </summary>
|
|
|
- /// <param name="toExpand">The object to expand</param>
|
|
|
+ /// <param name="toExpand">The object to expand.</param>
|
|
|
public void ExpandAll (T toExpand)
|
|
|
{
|
|
|
if (toExpand == null) {
|
|
@@ -1173,7 +1177,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// Fully expands all nodes in the tree, if the tree is very big and built dynamically this
|
|
|
- /// may take a while (e.g. for file system)
|
|
|
+ /// may take a while (e.g. for file system).
|
|
|
/// </summary>
|
|
|
public void ExpandAll ()
|
|
|
{
|
|
@@ -1186,7 +1190,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// Returns true if the given object <paramref name="o"/> is exposed in the tree and can be
|
|
|
- /// expanded otherwise false
|
|
|
+ /// expanded otherwise false.
|
|
|
/// </summary>
|
|
|
/// <param name="o"></param>
|
|
|
/// <returns></returns>
|
|
@@ -1197,7 +1201,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns true if the given object <paramref name="o"/> is exposed in the tree and
|
|
|
- /// expanded otherwise false
|
|
|
+ /// expanded otherwise false.
|
|
|
/// </summary>
|
|
|
/// <param name="o"></param>
|
|
|
/// <returns></returns>
|
|
@@ -1215,26 +1219,26 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Collapses the supplied object if it is currently expanded
|
|
|
+ /// Collapses the supplied object if it is currently expanded .
|
|
|
/// </summary>
|
|
|
- /// <param name="toCollapse">The object to collapse</param>
|
|
|
+ /// <param name="toCollapse">The object to collapse.</param>
|
|
|
public void Collapse (T toCollapse)
|
|
|
{
|
|
|
CollapseImpl (toCollapse, false);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Collapses the supplied object if it is currently expanded. Also collapses all children
|
|
|
- /// branches (this will only become apparent when/if the user expands it again)
|
|
|
+ /// Collapses the supplied object if it is currently expanded. Also collapses all children
|
|
|
+ /// branches (this will only become apparent when/if the user expands it again).
|
|
|
/// </summary>
|
|
|
- /// <param name="toCollapse">The object to collapse</param>
|
|
|
+ /// <param name="toCollapse">The object to collapse.</param>
|
|
|
public void CollapseAll (T toCollapse)
|
|
|
{
|
|
|
CollapseImpl (toCollapse, true);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Collapses all root nodes in the tree
|
|
|
+ /// Collapses all root nodes in the tree.
|
|
|
/// </summary>
|
|
|
public void CollapseAll ()
|
|
|
{
|
|
@@ -1247,19 +1251,17 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Implementation of <see cref="Collapse(T)"/> and <see cref="CollapseAll(T)"/>. Performs
|
|
|
- /// operation and updates selection if disapeared
|
|
|
+ /// Implementation of <see cref="Collapse(T)"/> and <see cref="CollapseAll(T)"/>. Performs
|
|
|
+ /// operation and updates selection if disapeared.
|
|
|
/// </summary>
|
|
|
/// <param name="toCollapse"></param>
|
|
|
/// <param name="all"></param>
|
|
|
protected void CollapseImpl (T toCollapse, bool all)
|
|
|
{
|
|
|
-
|
|
|
if (toCollapse == null) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
var branch = ObjectToBranch (toCollapse);
|
|
|
|
|
|
// Nothing to collapse
|
|
@@ -1292,12 +1294,12 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns the corresponding <see cref="Branch{T}"/> in the tree for
|
|
|
- /// <paramref name="toFind"/>. This will not work for objects hidden
|
|
|
- /// by their parent being collapsed
|
|
|
+ /// <paramref name="toFind"/>. This will not work for objects hidden
|
|
|
+ /// by their parent being collapsed.
|
|
|
/// </summary>
|
|
|
/// <param name="toFind"></param>
|
|
|
/// <returns>The branch for <paramref name="toFind"/> or null if it is not currently
|
|
|
- /// exposed in the tree</returns>
|
|
|
+ /// exposed in the tree.</returns>
|
|
|
private Branch<T> ObjectToBranch (T toFind)
|
|
|
{
|
|
|
return BuildLineMap ().FirstOrDefault (o => o.Model.Equals (toFind));
|
|
@@ -1305,7 +1307,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns true if the <paramref name="model"/> is either the
|
|
|
- /// <see cref="SelectedObject"/> or part of a <see cref="MultiSelect"/>
|
|
|
+ /// <see cref="SelectedObject"/> or part of a <see cref="MultiSelect"/>.
|
|
|
/// </summary>
|
|
|
/// <param name="model"></param>
|
|
|
/// <returns></returns>
|
|
@@ -1340,7 +1342,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
/// <summary>
|
|
|
/// Selects all objects in the tree when <see cref="MultiSelect"/> is enabled otherwise
|
|
|
- /// does nothing
|
|
|
+ /// does nothing.
|
|
|
/// </summary>
|
|
|
public void SelectAll ()
|
|
|
{
|
|
@@ -1362,9 +1364,8 @@ namespace Terminal.Gui {
|
|
|
OnSelectionChanged (new SelectionChangedEventArgs<T> (this, SelectedObject, SelectedObject));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// Raises the SelectionChanged event
|
|
|
+ /// Raises the SelectionChanged event.
|
|
|
/// </summary>
|
|
|
/// <param name="e"></param>
|
|
|
protected virtual void OnSelectionChanged (SelectionChangedEventArgs<T> e)
|
|
@@ -1406,5 +1407,4 @@ namespace Terminal.Gui {
|
|
|
return included.Contains (model);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|