using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spectre.Console.Composition;
namespace Spectre.Console
{
///
/// Represents a panel which contains another renderable item.
///
public sealed class Panel : IRenderable
{
private readonly IRenderable _child;
private readonly bool _fit;
///
/// Initializes a new instance of the class.
///
/// The child.
/// Whether or not to fit the panel to it's parent.
public Panel(IRenderable child, bool fit = false)
{
_child = child;
_fit = fit;
}
///
public int Measure(Encoding encoding, int maxWidth)
{
var childWidth = _child.Measure(encoding, maxWidth);
return childWidth + 4;
}
///
public IEnumerable Render(Encoding encoding, int width)
{
var childWidth = width - 4;
if (!_fit)
{
childWidth = _child.Measure(encoding, width - 2);
}
var result = new List();
var panelWidth = childWidth + 2;
result.Add(new Segment("┌"));
result.Add(new Segment(new string('─', panelWidth)));
result.Add(new Segment("┐"));
result.Add(new Segment("\n"));
var childSegments = _child.Render(encoding, childWidth);
foreach (var line in Segment.Split(childSegments))
{
result.Add(new Segment("│ "));
foreach (var segment in line)
{
result.Add(segment.StripLineEndings());
}
var length = line.Sum(segment => segment.CellLength(encoding));
if (length < childWidth)
{
var diff = childWidth - length;
result.Add(new Segment(new string(' ', diff)));
}
result.Add(new Segment(" │"));
result.Add(new Segment("\n"));
}
result.Add(new Segment("└"));
result.Add(new Segment(new string('─', panelWidth)));
result.Add(new Segment("┘"));
result.Add(new Segment("\n"));
return result;
}
}
}