Add support for hierarchical list prompts

Closes #412
This commit is contained in:
Patrik Svensson
2021-05-16 22:45:58 +02:00
committed by Phil Scott
parent c147929f16
commit 315a52f3e9
32 changed files with 946 additions and 541 deletions

View File

@ -0,0 +1,80 @@
using System.Collections.Generic;
namespace Spectre.Console
{
internal sealed class ListPromptItem<T> : IMultiSelectionItem<T>
where T : notnull
{
public T Data { get; }
public ListPromptItem<T>? Parent { get; }
public List<ListPromptItem<T>> Children { get; }
public int Depth { get; }
public bool Selected { get; set; }
public bool IsGroup => Children.Count > 0;
public ListPromptItem(T data, ListPromptItem<T>? parent = null)
{
Data = data;
Parent = parent;
Children = new List<ListPromptItem<T>>();
Depth = CalculateDepth(parent);
}
public IMultiSelectionItem<T> Select()
{
Selected = true;
return this;
}
public ISelectionItem<T> AddChild(T item)
{
var node = new ListPromptItem<T>(item, this);
Children.Add(node);
return node;
}
public IEnumerable<ListPromptItem<T>> Traverse(bool includeSelf)
{
var stack = new Stack<ListPromptItem<T>>();
if (includeSelf)
{
stack.Push(this);
}
else
{
foreach (var child in Children)
{
stack.Push(child);
}
}
while (stack.Count > 0)
{
var current = stack.Pop();
yield return current;
if (current.Children.Count > 0)
{
foreach (var child in current.Children.ReverseEnumerable())
{
stack.Push(child);
}
}
}
}
private static int CalculateDepth(ListPromptItem<T>? parent)
{
var level = 0;
while (parent != null)
{
level++;
parent = parent.Parent;
}
return level;
}
}
}