|
@@ -1,8 +1,10 @@
|
|
-namespace Terminal.Gui;
|
|
|
|
|
|
+#nullable enable
|
|
|
|
+
|
|
|
|
+namespace Terminal.Gui;
|
|
|
|
|
|
internal class Branch<T> where T : class
|
|
internal class Branch<T> where T : class
|
|
{
|
|
{
|
|
- private readonly TreeView<T> tree;
|
|
|
|
|
|
+ private readonly TreeView<T> _tree;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Declares a new branch of <paramref name="tree"/> in which the users object <paramref name="model"/> is
|
|
/// Declares a new branch of <paramref name="tree"/> in which the users object <paramref name="model"/> is
|
|
@@ -11,9 +13,9 @@ internal class Branch<T> where T : class
|
|
/// <param name="tree">The UI control in which the branch resides.</param>
|
|
/// <param name="tree">The UI control in which the branch resides.</param>
|
|
/// <param name="parentBranchIfAny">Pass null for root level branches, otherwise pass the parent.</param>
|
|
/// <param name="parentBranchIfAny">Pass null for root level branches, otherwise pass the parent.</param>
|
|
/// <param name="model">The user's object that should be displayed.</param>
|
|
/// <param name="model">The user's object that should be displayed.</param>
|
|
- public Branch (TreeView<T> tree, Branch<T> parentBranchIfAny, T model)
|
|
|
|
|
|
+ public Branch (TreeView<T> tree, Branch<T>? parentBranchIfAny, T model)
|
|
{
|
|
{
|
|
- this.tree = tree;
|
|
|
|
|
|
+ _tree = tree;
|
|
Model = model;
|
|
Model = model;
|
|
|
|
|
|
if (parentBranchIfAny is { })
|
|
if (parentBranchIfAny is { })
|
|
@@ -27,7 +29,7 @@ internal class Branch<T> where T : class
|
|
/// The children of the current branch. This is null until the first call to <see cref="FetchChildren"/> to avoid
|
|
/// The children of the current branch. This is null until the first call to <see cref="FetchChildren"/> to avoid
|
|
/// enumerating the entire underlying hierarchy.
|
|
/// enumerating the entire underlying hierarchy.
|
|
/// </summary>
|
|
/// </summary>
|
|
- public Dictionary<T, Branch<T>> ChildBranches { get; set; }
|
|
|
|
|
|
+ public List<Branch<T>>? ChildBranches { get; set; }
|
|
|
|
|
|
/// <summary>The depth of the current branch. Depth of 0 indicates root level branches.</summary>
|
|
/// <summary>The depth of the current branch. Depth of 0 indicates root level branches.</summary>
|
|
public int Depth { get; }
|
|
public int Depth { get; }
|
|
@@ -39,7 +41,7 @@ internal class Branch<T> where T : class
|
|
public T Model { get; private set; }
|
|
public T Model { get; private set; }
|
|
|
|
|
|
/// <summary>The parent <see cref="Branch{T}"/> or null if it is a root.</summary>
|
|
/// <summary>The parent <see cref="Branch{T}"/> or null if it is a root.</summary>
|
|
- public Branch<T> Parent { get; }
|
|
|
|
|
|
+ public Branch<T>? Parent { get; }
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Returns true if the current branch can be expanded according to the <see cref="TreeBuilder{T}"/> or cached
|
|
/// Returns true if the current branch can be expanded according to the <see cref="TreeBuilder{T}"/> or cached
|
|
@@ -52,13 +54,13 @@ internal class Branch<T> where T : class
|
|
if (ChildBranches is null)
|
|
if (ChildBranches is null)
|
|
{
|
|
{
|
|
//if there is a rapid method for determining whether there are children
|
|
//if there is a rapid method for determining whether there are children
|
|
- if (tree.TreeBuilder.SupportsCanExpand)
|
|
|
|
|
|
+ if (_tree.TreeBuilder.SupportsCanExpand)
|
|
{
|
|
{
|
|
- return tree.TreeBuilder.CanExpand (Model);
|
|
|
|
|
|
+ return _tree.TreeBuilder.CanExpand (Model);
|
|
}
|
|
}
|
|
|
|
|
|
//there is no way of knowing whether we can expand without fetching the children
|
|
//there is no way of knowing whether we can expand without fetching the children
|
|
- FetchChildren ();
|
|
|
|
|
|
+ ChildBranches = FetchChildren ();
|
|
}
|
|
}
|
|
|
|
|
|
//we fetched or already know the children, so return whether we have any
|
|
//we fetched or already know the children, so return whether we have any
|
|
@@ -69,32 +71,30 @@ internal class Branch<T> where T : class
|
|
public void Collapse () { IsExpanded = false; }
|
|
public void Collapse () { IsExpanded = false; }
|
|
|
|
|
|
/// <summary>Renders the current <see cref="Model"/> on the specified line <paramref name="y"/>.</summary>
|
|
/// <summary>Renders the current <see cref="Model"/> on the specified line <paramref name="y"/>.</summary>
|
|
- /// <param name="driver"></param>
|
|
|
|
- /// <param name="colorScheme"></param>
|
|
|
|
/// <param name="y"></param>
|
|
/// <param name="y"></param>
|
|
/// <param name="availableWidth"></param>
|
|
/// <param name="availableWidth"></param>
|
|
- public virtual void Draw (IConsoleDriver driver, ColorScheme colorScheme, int y, int availableWidth)
|
|
|
|
|
|
+ public virtual void Draw (int y, int availableWidth)
|
|
{
|
|
{
|
|
List<Cell> cells = new ();
|
|
List<Cell> cells = new ();
|
|
int? indexOfExpandCollapseSymbol = null;
|
|
int? indexOfExpandCollapseSymbol = null;
|
|
int indexOfModelText;
|
|
int indexOfModelText;
|
|
|
|
|
|
// true if the current line of the tree is the selected one and control has focus
|
|
// true if the current line of the tree is the selected one and control has focus
|
|
- bool isSelected = tree.IsSelected (Model);
|
|
|
|
|
|
+ bool isSelected = _tree.IsSelected (Model);
|
|
|
|
|
|
Attribute textColor =
|
|
Attribute textColor =
|
|
- isSelected ? tree.HasFocus ? colorScheme.Focus : colorScheme.HotNormal : colorScheme.Normal;
|
|
|
|
- Attribute symbolColor = tree.Style.HighlightModelTextOnly ? colorScheme.Normal : textColor;
|
|
|
|
|
|
+ isSelected ? _tree.HasFocus ? _tree.GetFocusColor () : _tree.GetHotNormalColor () : _tree.GetNormalColor ();
|
|
|
|
+ Attribute symbolColor = _tree.Style.HighlightModelTextOnly ? _tree.GetNormalColor () : textColor;
|
|
|
|
|
|
// Everything on line before the expansion run and branch text
|
|
// Everything on line before the expansion run and branch text
|
|
- Rune [] prefix = GetLinePrefix (driver).ToArray ();
|
|
|
|
- Rune expansion = GetExpandableSymbol (driver);
|
|
|
|
- string lineBody = tree.AspectGetter (Model) ?? "";
|
|
|
|
|
|
+ Rune [] prefix = GetLinePrefix ().ToArray ();
|
|
|
|
+ Rune expansion = GetExpandableSymbol ();
|
|
|
|
+ string lineBody = _tree.AspectGetter (Model) ?? "";
|
|
|
|
|
|
- tree.Move (0, y);
|
|
|
|
|
|
+ _tree.Move (0, y);
|
|
|
|
|
|
// if we have scrolled to the right then bits of the prefix will have disappeared off the screen
|
|
// if we have scrolled to the right then bits of the prefix will have disappeared off the screen
|
|
- int toSkip = tree.ScrollOffsetHorizontal;
|
|
|
|
|
|
+ int toSkip = _tree.ScrollOffsetHorizontal;
|
|
Attribute attr = symbolColor;
|
|
Attribute attr = symbolColor;
|
|
|
|
|
|
// Draw the line prefix (all parallel lanes or whitespace and an expand/collapse/leaf symbol)
|
|
// Draw the line prefix (all parallel lanes or whitespace and an expand/collapse/leaf symbol)
|
|
@@ -112,20 +112,20 @@ internal class Branch<T> where T : class
|
|
}
|
|
}
|
|
|
|
|
|
// pick color for expanded symbol
|
|
// pick color for expanded symbol
|
|
- if (tree.Style.ColorExpandSymbol || tree.Style.InvertExpandSymbolColors)
|
|
|
|
|
|
+ if (_tree.Style.ColorExpandSymbol || _tree.Style.InvertExpandSymbolColors)
|
|
{
|
|
{
|
|
- Attribute color = symbolColor;
|
|
|
|
|
|
+ Attribute color;
|
|
|
|
|
|
- if (tree.Style.ColorExpandSymbol)
|
|
|
|
|
|
+ if (_tree.Style.ColorExpandSymbol)
|
|
{
|
|
{
|
|
if (isSelected)
|
|
if (isSelected)
|
|
{
|
|
{
|
|
- color = tree.Style.HighlightModelTextOnly ? colorScheme.HotNormal :
|
|
|
|
- tree.HasFocus ? tree.ColorScheme.HotFocus : tree.ColorScheme.HotNormal;
|
|
|
|
|
|
+ color = _tree.Style.HighlightModelTextOnly ? _tree.GetHotNormalColor () :
|
|
|
|
+ _tree.HasFocus ? _tree.GetHotFocusColor () : _tree.GetHotNormalColor ();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- color = tree.ColorScheme.HotNormal;
|
|
|
|
|
|
+ color = _tree.GetHotNormalColor ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -133,9 +133,9 @@ internal class Branch<T> where T : class
|
|
color = symbolColor;
|
|
color = symbolColor;
|
|
}
|
|
}
|
|
|
|
|
|
- if (tree.Style.InvertExpandSymbolColors)
|
|
|
|
|
|
+ if (_tree.Style.InvertExpandSymbolColors)
|
|
{
|
|
{
|
|
- color = new Attribute (color.Background, color.Foreground);
|
|
|
|
|
|
+ color = new (color.Background, color.Foreground);
|
|
}
|
|
}
|
|
|
|
|
|
attr = color;
|
|
attr = color;
|
|
@@ -177,10 +177,10 @@ internal class Branch<T> where T : class
|
|
if (lineBody.EnumerateRunes ().Sum (l => l.GetColumns ()) > availableWidth)
|
|
if (lineBody.EnumerateRunes ().Sum (l => l.GetColumns ()) > availableWidth)
|
|
{
|
|
{
|
|
// remaining space is zero and truncate the line
|
|
// remaining space is zero and truncate the line
|
|
- lineBody = new string (
|
|
|
|
- lineBody.TakeWhile (c => (availableWidth -= ((Rune)c).GetColumns ()) >= 0)
|
|
|
|
- .ToArray ()
|
|
|
|
- );
|
|
|
|
|
|
+ lineBody = new (
|
|
|
|
+ lineBody.TakeWhile (c => (availableWidth -= ((Rune)c).GetColumns ()) >= 0)
|
|
|
|
+ .ToArray ()
|
|
|
|
+ );
|
|
availableWidth = 0;
|
|
availableWidth = 0;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -194,9 +194,9 @@ internal class Branch<T> where T : class
|
|
Attribute modelColor = textColor;
|
|
Attribute modelColor = textColor;
|
|
|
|
|
|
// if custom color delegate invoke it
|
|
// if custom color delegate invoke it
|
|
- if (tree.ColorGetter is { })
|
|
|
|
|
|
+ if (_tree.ColorGetter is { })
|
|
{
|
|
{
|
|
- ColorScheme modelScheme = tree.ColorGetter (Model);
|
|
|
|
|
|
+ ColorScheme modelScheme = _tree.ColorGetter (Model);
|
|
|
|
|
|
// if custom color scheme is defined for this Model
|
|
// if custom color scheme is defined for this Model
|
|
if (modelScheme is { })
|
|
if (modelScheme is { })
|
|
@@ -206,12 +206,12 @@ internal class Branch<T> where T : class
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- modelColor = new Attribute ();
|
|
|
|
|
|
+ modelColor = new ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
attr = modelColor;
|
|
attr = modelColor;
|
|
- cells.AddRange (lineBody.Select (r => NewCell (attr, new Rune (r))));
|
|
|
|
|
|
+ cells.AddRange (lineBody.Select (r => NewCell (attr, new (r))));
|
|
|
|
|
|
if (availableWidth > 0)
|
|
if (availableWidth > 0)
|
|
{
|
|
{
|
|
@@ -219,7 +219,7 @@ internal class Branch<T> where T : class
|
|
|
|
|
|
cells.AddRange (
|
|
cells.AddRange (
|
|
Enumerable.Repeat (
|
|
Enumerable.Repeat (
|
|
- NewCell (attr, new Rune (' ')),
|
|
|
|
|
|
+ NewCell (attr, new (' ')),
|
|
availableWidth
|
|
availableWidth
|
|
)
|
|
)
|
|
);
|
|
);
|
|
@@ -230,32 +230,29 @@ internal class Branch<T> where T : class
|
|
Model = Model,
|
|
Model = Model,
|
|
Y = y,
|
|
Y = y,
|
|
Cells = cells,
|
|
Cells = cells,
|
|
- Tree = tree,
|
|
|
|
|
|
+ Tree = _tree,
|
|
IndexOfExpandCollapseSymbol =
|
|
IndexOfExpandCollapseSymbol =
|
|
indexOfExpandCollapseSymbol,
|
|
indexOfExpandCollapseSymbol,
|
|
IndexOfModelText = indexOfModelText
|
|
IndexOfModelText = indexOfModelText
|
|
};
|
|
};
|
|
- tree.OnDrawLine (e);
|
|
|
|
|
|
+ _tree.OnDrawLine (e);
|
|
|
|
|
|
- if (!e.Handled && driver != null)
|
|
|
|
|
|
+ if (!e.Handled)
|
|
{
|
|
{
|
|
foreach (Cell cell in cells)
|
|
foreach (Cell cell in cells)
|
|
{
|
|
{
|
|
- driver.SetAttribute ((Attribute)cell.Attribute!);
|
|
|
|
- driver.AddRune (cell.Rune);
|
|
|
|
|
|
+ _tree.SetAttribute ((Attribute)cell.Attribute!);
|
|
|
|
+ _tree.AddRune (cell.Rune);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- driver?.SetAttribute (colorScheme.Normal);
|
|
|
|
|
|
+ _tree.SetAttribute (_tree.GetNormalColor());
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>Expands the current branch if possible.</summary>
|
|
/// <summary>Expands the current branch if possible.</summary>
|
|
public void Expand ()
|
|
public void Expand ()
|
|
{
|
|
{
|
|
- if (ChildBranches is null)
|
|
|
|
- {
|
|
|
|
- FetchChildren ();
|
|
|
|
- }
|
|
|
|
|
|
+ ChildBranches ??= FetchChildren ();
|
|
|
|
|
|
if (ChildBranches.Any ())
|
|
if (ChildBranches.Any ())
|
|
{
|
|
{
|
|
@@ -264,45 +261,44 @@ internal class Branch<T> where T : class
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>Fetch the children of this branch. This method populates <see cref="ChildBranches"/>.</summary>
|
|
/// <summary>Fetch the children of this branch. This method populates <see cref="ChildBranches"/>.</summary>
|
|
- public virtual void FetchChildren ()
|
|
|
|
|
|
+ private List<Branch<T>> FetchChildren ()
|
|
{
|
|
{
|
|
- if (tree.TreeBuilder is null)
|
|
|
|
|
|
+ if (_tree.TreeBuilder is null)
|
|
{
|
|
{
|
|
- return;
|
|
|
|
|
|
+ return [];
|
|
}
|
|
}
|
|
|
|
|
|
IEnumerable<T> children;
|
|
IEnumerable<T> children;
|
|
|
|
|
|
- if (Depth >= tree.MaxDepth)
|
|
|
|
|
|
+ if (Depth >= _tree.MaxDepth)
|
|
{
|
|
{
|
|
- children = Enumerable.Empty<T> ();
|
|
|
|
|
|
+ children = [];
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- children = tree.TreeBuilder.GetChildren (Model) ?? Enumerable.Empty<T> ();
|
|
|
|
|
|
+ children = _tree.TreeBuilder.GetChildren (Model) ?? [];
|
|
}
|
|
}
|
|
|
|
|
|
- ChildBranches = children.ToDictionary (k => k, val => new Branch<T> (tree, this, val));
|
|
|
|
|
|
+ return children.Select (o => new Branch<T> (_tree, this, o)).ToList ();
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Returns an appropriate symbol for displaying next to the string representation of the <see cref="Model"/>
|
|
/// Returns an appropriate symbol for displaying next to the string representation of the <see cref="Model"/>
|
|
/// object to indicate whether it <see cref="IsExpanded"/> or not (or it is a leaf).
|
|
/// object to indicate whether it <see cref="IsExpanded"/> or not (or it is a leaf).
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// <param name="driver"></param>
|
|
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public Rune GetExpandableSymbol (IConsoleDriver driver)
|
|
|
|
|
|
+ public Rune GetExpandableSymbol ()
|
|
{
|
|
{
|
|
- Rune leafSymbol = tree.Style.ShowBranchLines ? Glyphs.HLine : (Rune)' ';
|
|
|
|
|
|
+ Rune leafSymbol = _tree.Style.ShowBranchLines ? Glyphs.HLine : (Rune)' ';
|
|
|
|
|
|
if (IsExpanded)
|
|
if (IsExpanded)
|
|
{
|
|
{
|
|
- return tree.Style.CollapseableSymbol ?? leafSymbol;
|
|
|
|
|
|
+ return _tree.Style.CollapseableSymbol ?? leafSymbol;
|
|
}
|
|
}
|
|
|
|
|
|
if (CanExpand ())
|
|
if (CanExpand ())
|
|
{
|
|
{
|
|
- return tree.Style.ExpandableSymbol ?? leafSymbol;
|
|
|
|
|
|
+ return _tree.Style.ExpandableSymbol ?? leafSymbol;
|
|
}
|
|
}
|
|
|
|
|
|
return leafSymbol;
|
|
return leafSymbol;
|
|
@@ -313,10 +309,10 @@ internal class Branch<T> where T : class
|
|
/// line body).
|
|
/// line body).
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public virtual int GetWidth (IConsoleDriver driver)
|
|
|
|
|
|
+ public virtual int GetWidth ()
|
|
{
|
|
{
|
|
return
|
|
return
|
|
- GetLinePrefix (driver).Sum (r => r.GetColumns ()) + GetExpandableSymbol (driver).GetColumns () + (tree.AspectGetter (Model) ?? "").Length;
|
|
|
|
|
|
+ GetLinePrefix ().Sum (r => r.GetColumns ()) + GetExpandableSymbol ().GetColumns () + (_tree.AspectGetter (Model) ?? "").Length;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>Refreshes cached knowledge in this branch e.g. what children an object has.</summary>
|
|
/// <summary>Refreshes cached knowledge in this branch e.g. what children an object has.</summary>
|
|
@@ -333,41 +329,46 @@ internal class Branch<T> where T : class
|
|
//if we don't know about any children yet just use the normal method
|
|
//if we don't know about any children yet just use the normal method
|
|
if (ChildBranches is null)
|
|
if (ChildBranches is null)
|
|
{
|
|
{
|
|
- FetchChildren ();
|
|
|
|
|
|
+ ChildBranches = FetchChildren ();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
// we already knew about some children so preserve the state of the old children
|
|
// we already knew about some children so preserve the state of the old children
|
|
|
|
|
|
// first gather the new Children
|
|
// first gather the new Children
|
|
- IEnumerable<T> newChildren = tree.TreeBuilder?.GetChildren (Model) ?? Enumerable.Empty<T> ();
|
|
|
|
|
|
+ T [] newChildren = _tree.TreeBuilder?.GetChildren (Model).ToArray () ?? [];
|
|
|
|
|
|
// Children who no longer appear need to go
|
|
// Children who no longer appear need to go
|
|
- foreach (T toRemove in ChildBranches.Keys.Except (newChildren).ToArray ())
|
|
|
|
|
|
+ foreach (Branch<T> toRemove in ChildBranches.Where (b => !newChildren.Contains (b.Model)).ToArray ())
|
|
{
|
|
{
|
|
ChildBranches.Remove (toRemove);
|
|
ChildBranches.Remove (toRemove);
|
|
|
|
|
|
//also if the user has this node selected (its disappearing) so lets change selection to us (the parent object) to be helpful
|
|
//also if the user has this node selected (its disappearing) so lets change selection to us (the parent object) to be helpful
|
|
- if (Equals (tree.SelectedObject, toRemove))
|
|
|
|
|
|
+ if (Equals (_tree.SelectedObject, toRemove.Model))
|
|
{
|
|
{
|
|
- tree.SelectedObject = Model;
|
|
|
|
|
|
+ _tree.SelectedObject = Model;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// New children need to be added
|
|
// New children need to be added
|
|
foreach (T newChild in newChildren)
|
|
foreach (T newChild in newChildren)
|
|
{
|
|
{
|
|
|
|
+ Branch<T>? existingBranch = ChildBranches.FirstOrDefault (b => b.Model.Equals (newChild));
|
|
|
|
+
|
|
// If we don't know about the child, yet we need a new branch
|
|
// If we don't know about the child, yet we need a new branch
|
|
- if (!ChildBranches.ContainsKey (newChild))
|
|
|
|
|
|
+ if (existingBranch == null)
|
|
{
|
|
{
|
|
- ChildBranches.Add (newChild, new Branch<T> (tree, this, newChild));
|
|
|
|
|
|
+ ChildBranches.Add (new (_tree, this, newChild));
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
//we already have this object but update the reference anyway in case Equality match but the references are new
|
|
//we already have this object but update the reference anyway in case Equality match but the references are new
|
|
- ChildBranches [newChild].Model = newChild;
|
|
|
|
|
|
+ existingBranch.Model = newChild;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Order the list
|
|
|
|
+ ChildBranches = ChildBranches.OrderBy (b => newChildren.IndexOf (b.Model)).ToList ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -381,9 +382,9 @@ internal class Branch<T> where T : class
|
|
|
|
|
|
if (ChildBranches is { })
|
|
if (ChildBranches is { })
|
|
{
|
|
{
|
|
- foreach (KeyValuePair<T, Branch<T>> child in ChildBranches)
|
|
|
|
|
|
+ foreach (Branch<T> child in ChildBranches)
|
|
{
|
|
{
|
|
- child.Value.CollapseAll ();
|
|
|
|
|
|
+ child.CollapseAll ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -395,9 +396,9 @@ internal class Branch<T> where T : class
|
|
|
|
|
|
if (ChildBranches is { })
|
|
if (ChildBranches is { })
|
|
{
|
|
{
|
|
- foreach (KeyValuePair<T, Branch<T>> child in ChildBranches)
|
|
|
|
|
|
+ foreach (Branch<T> child in ChildBranches)
|
|
{
|
|
{
|
|
- child.Value.ExpandAll ();
|
|
|
|
|
|
+ child.ExpandAll ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -406,16 +407,15 @@ internal class Branch<T> where T : class
|
|
/// Gets all characters to render prior to the current branches line. This includes indentation whitespace and
|
|
/// Gets all characters to render prior to the current branches line. This includes indentation whitespace and
|
|
/// any tree branches (if enabled).
|
|
/// any tree branches (if enabled).
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// <param name="driver"></param>
|
|
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- internal IEnumerable<Rune> GetLinePrefix (IConsoleDriver driver)
|
|
|
|
|
|
+ internal IEnumerable<Rune> GetLinePrefix ()
|
|
{
|
|
{
|
|
// If not showing line branches or this is a root object.
|
|
// If not showing line branches or this is a root object.
|
|
- if (!tree.Style.ShowBranchLines)
|
|
|
|
|
|
+ if (!_tree.Style.ShowBranchLines)
|
|
{
|
|
{
|
|
for (var i = 0; i < Depth; i++)
|
|
for (var i = 0; i < Depth; i++)
|
|
{
|
|
{
|
|
- yield return new Rune (' ');
|
|
|
|
|
|
+ yield return new (' ');
|
|
}
|
|
}
|
|
|
|
|
|
yield break;
|
|
yield break;
|
|
@@ -426,14 +426,14 @@ internal class Branch<T> where T : class
|
|
{
|
|
{
|
|
if (cur.IsLast ())
|
|
if (cur.IsLast ())
|
|
{
|
|
{
|
|
- yield return new Rune (' ');
|
|
|
|
|
|
+ yield return new (' ');
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
yield return Glyphs.VLine;
|
|
yield return Glyphs.VLine;
|
|
}
|
|
}
|
|
|
|
|
|
- yield return new Rune (' ');
|
|
|
|
|
|
+ yield return new (' ');
|
|
}
|
|
}
|
|
|
|
|
|
if (IsLast ())
|
|
if (IsLast ())
|
|
@@ -462,15 +462,15 @@ internal class Branch<T> where T : class
|
|
}
|
|
}
|
|
|
|
|
|
// if we could theoretically expand
|
|
// if we could theoretically expand
|
|
- if (!IsExpanded && tree.Style.ExpandableSymbol != default (Rune?))
|
|
|
|
|
|
+ if (!IsExpanded && _tree.Style.ExpandableSymbol != default (Rune?))
|
|
{
|
|
{
|
|
- return x == GetLinePrefix (driver).Count ();
|
|
|
|
|
|
+ return x == GetLinePrefix ().Count ();
|
|
}
|
|
}
|
|
|
|
|
|
// if we could theoretically collapse
|
|
// if we could theoretically collapse
|
|
- if (IsExpanded && tree.Style.CollapseableSymbol != default (Rune?))
|
|
|
|
|
|
+ if (IsExpanded && _tree.Style.CollapseableSymbol != default (Rune?))
|
|
{
|
|
{
|
|
- return x == GetLinePrefix (driver).Count ();
|
|
|
|
|
|
+ return x == GetLinePrefix ().Count ();
|
|
}
|
|
}
|
|
|
|
|
|
return false;
|
|
return false;
|
|
@@ -487,9 +487,9 @@ internal class Branch<T> where T : class
|
|
if (IsExpanded)
|
|
if (IsExpanded)
|
|
{
|
|
{
|
|
// if we are expanded we need to update the visible children
|
|
// if we are expanded we need to update the visible children
|
|
- foreach (KeyValuePair<T, Branch<T>> child in ChildBranches)
|
|
|
|
|
|
+ foreach (Branch<T> child in ChildBranches)
|
|
{
|
|
{
|
|
- child.Value.Rebuild ();
|
|
|
|
|
|
+ child.Rebuild ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -504,7 +504,7 @@ internal class Branch<T> where T : class
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
private IEnumerable<Branch<T>> GetParentBranches ()
|
|
private IEnumerable<Branch<T>> GetParentBranches ()
|
|
{
|
|
{
|
|
- Branch<T> cur = Parent;
|
|
|
|
|
|
+ Branch<T>? cur = Parent;
|
|
|
|
|
|
while (cur is { })
|
|
while (cur is { })
|
|
{
|
|
{
|
|
@@ -523,11 +523,13 @@ internal class Branch<T> where T : class
|
|
{
|
|
{
|
|
if (Parent is null)
|
|
if (Parent is null)
|
|
{
|
|
{
|
|
- return this == tree.roots.Values.LastOrDefault ();
|
|
|
|
|
|
+ return this == _tree.roots.Values.LastOrDefault ();
|
|
}
|
|
}
|
|
|
|
|
|
- return Parent.ChildBranches.Values.LastOrDefault () == this;
|
|
|
|
|
|
+ Parent.ChildBranches ??= Parent.FetchChildren ();
|
|
|
|
+
|
|
|
|
+ return Parent.ChildBranches.LastOrDefault () == this;
|
|
}
|
|
}
|
|
|
|
|
|
- private static Cell NewCell (Attribute attr, Rune r) { return new Cell { Rune = r, Attribute = new (attr) }; }
|
|
|
|
|
|
+ private static Cell NewCell (Attribute attr, Rune r) { return new() { Rune = r, Attribute = new (attr) }; }
|
|
}
|
|
}
|