mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-19 02:12:49 +08:00

This makes it possible for encoders to output better representation of the actual objects instead of working with chopped up segments. * IAnsiConsole.Write now takes an IRenderable instead of segments * Calculating cell width does no longer require a render context * Removed RenderContext.LegacyConsole * Removed RenderContext.Encoding * Added Capabilities.Unicode
81 lines
2.2 KiB
C#
81 lines
2.2 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace Spectre.Console.Rendering
|
|
{
|
|
internal sealed class LiveRenderable : Renderable
|
|
{
|
|
private readonly object _lock = new object();
|
|
private IRenderable? _renderable;
|
|
private SegmentShape? _shape;
|
|
|
|
public bool HasRenderable => _renderable != null;
|
|
|
|
public void SetRenderable(IRenderable renderable)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_renderable = renderable;
|
|
}
|
|
}
|
|
|
|
public IRenderable PositionCursor()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_shape == null)
|
|
{
|
|
return new ControlSequence(string.Empty);
|
|
}
|
|
|
|
return new ControlSequence("\r" + "\u001b[1A".Repeat(_shape.Value.Height - 1));
|
|
}
|
|
}
|
|
|
|
public IRenderable RestoreCursor()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_shape == null)
|
|
{
|
|
return new ControlSequence(string.Empty);
|
|
}
|
|
|
|
return new ControlSequence("\r\u001b[2K" + "\u001b[1A\u001b[2K".Repeat(_shape.Value.Height - 1));
|
|
}
|
|
}
|
|
|
|
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_renderable != null)
|
|
{
|
|
var segments = _renderable.Render(context, maxWidth);
|
|
var lines = Segment.SplitLines(segments);
|
|
|
|
var shape = SegmentShape.Calculate(context, lines);
|
|
_shape = _shape == null ? shape : _shape.Value.Inflate(shape);
|
|
_shape.Value.Apply(context, ref lines);
|
|
|
|
foreach (var (_, _, last, line) in lines.Enumerate())
|
|
{
|
|
foreach (var item in line)
|
|
{
|
|
yield return item;
|
|
}
|
|
|
|
if (!last)
|
|
{
|
|
yield return Segment.LineBreak;
|
|
}
|
|
}
|
|
|
|
yield break;
|
|
}
|
|
|
|
_shape = null;
|
|
}
|
|
}
|
|
}
|
|
}
|