Fix tree rendering

Fixes some tree rendering problems where lines were not properly drawn
at some levels during some circumstances.

* Change the API back to only allow one root.
* Now uses a stack based approach to rendering instead of recursion.
* Removes the need for measuring the whole tree in advance.
  Leave this up to each child to render.
This commit is contained in:
Patrik Svensson
2021-01-09 18:34:07 +01:00
committed by Patrik Svensson
parent 0e0f4b4220
commit 8261b25e5c
34 changed files with 697 additions and 446 deletions

View File

@ -1,25 +0,0 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// An ASCII rendering of a tree.
/// </summary>
public sealed class AsciiTreeAppearance : TreeAppearance
{
/// <inheritdoc/>
public override int PartSize => 4;
/// <inheritdoc/>
public override string GetPart(TreePart part)
{
return part switch
{
TreePart.SiblingConnector => "│ ",
TreePart.ChildBranch => "├── ",
TreePart.BottomChildBranch => "└── ",
_ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."),
};
}
}
}

View File

@ -0,0 +1,23 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// An ASCII tree guide.
/// </summary>
public sealed class AsciiTreeGuide : TreeGuide
{
/// <inheritdoc/>
public override string GetPart(TreeGuidePart part)
{
return part switch
{
TreeGuidePart.Space => " ",
TreeGuidePart.Continue => "| ",
TreeGuidePart.Fork => "|-- ",
TreeGuidePart.End => "`-- ",
_ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."),
};
}
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// A tree guide made up of bold lines.
/// </summary>
public sealed class BoldLineTreeGuide : TreeGuide
{
/// <inheritdoc/>
public override TreeGuide? SafeTreeGuide => Ascii;
/// <inheritdoc/>
public override string GetPart(TreeGuidePart part)
{
return part switch
{
TreeGuidePart.Space => " ",
TreeGuidePart.Continue => "┃ ",
TreeGuidePart.Fork => "┣━━ ",
TreeGuidePart.End => "┗━━ ",
_ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."),
};
}
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// A tree guide made up of double lines.
/// </summary>
public sealed class DoubleLineTreeGuide : TreeGuide
{
/// <inheritdoc/>
public override TreeGuide? SafeTreeGuide => Ascii;
/// <inheritdoc/>
public override string GetPart(TreeGuidePart part)
{
return part switch
{
TreeGuidePart.Space => " ",
TreeGuidePart.Continue => "║ ",
TreeGuidePart.Fork => "╠══ ",
TreeGuidePart.End => "╚══ ",
_ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."),
};
}
}
}

View File

@ -0,0 +1,26 @@
using System;
namespace Spectre.Console.Rendering
{
/// <summary>
/// A tree guide made up of lines.
/// </summary>
public sealed class LineTreeGuide : TreeGuide
{
/// <inheritdoc/>
public override TreeGuide? SafeTreeGuide => Ascii;
/// <inheritdoc/>
public override string GetPart(TreeGuidePart part)
{
return part switch
{
TreeGuidePart.Space => " ",
TreeGuidePart.Continue => "│ ",
TreeGuidePart.Fork => "├── ",
TreeGuidePart.End => "└── ",
_ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."),
};
}
}
}

View File

@ -3,21 +3,26 @@ namespace Spectre.Console.Rendering
/// <summary>
/// Defines the different rendering parts of a <see cref="Tree"/>.
/// </summary>
public enum TreePart
public enum TreeGuidePart
{
/// <summary>
/// Represents a space.
/// </summary>
Space,
/// <summary>
/// Connection between siblings.
/// </summary>
SiblingConnector,
Continue,
/// <summary>
/// Branch from parent to child.
/// </summary>
ChildBranch,
Fork,
/// <summary>
/// Branch from parent to child for the last child in a set.
/// </summary>
BottomChildBranch,
End,
}
}