mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Add status support
This commit is contained in:

committed by
Patrik Svensson

parent
cbed41e637
commit
501db5d287
@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
@ -8,7 +7,7 @@ namespace Spectre.Console.Rendering
|
||||
{
|
||||
private readonly object _lock = new object();
|
||||
private IRenderable? _renderable;
|
||||
private int? _height;
|
||||
private SegmentShape? _shape;
|
||||
|
||||
public void SetRenderable(IRenderable renderable)
|
||||
{
|
||||
@ -22,12 +21,12 @@ namespace Spectre.Console.Rendering
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_height == null)
|
||||
if (_shape == null)
|
||||
{
|
||||
return new ControlSequence(string.Empty);
|
||||
}
|
||||
|
||||
return new ControlSequence("\r" + "\u001b[1A".Repeat(_height.Value - 1));
|
||||
return new ControlSequence("\r" + "\u001b[1A".Repeat(_shape.Value.Height - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,12 +34,12 @@ namespace Spectre.Console.Rendering
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_height == null)
|
||||
if (_shape == null)
|
||||
{
|
||||
return new ControlSequence(string.Empty);
|
||||
}
|
||||
|
||||
return new ControlSequence("\r\u001b[2K" + "\u001b[1A\u001b[2K".Repeat(_height.Value - 1));
|
||||
return new ControlSequence("\r\u001b[2K" + "\u001b[1A\u001b[2K".Repeat(_shape.Value.Height - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,27 +52,27 @@ namespace Spectre.Console.Rendering
|
||||
var segments = _renderable.Render(context, maxWidth);
|
||||
var lines = Segment.SplitLines(context, segments);
|
||||
|
||||
_height = lines.Count;
|
||||
var shape = SegmentShape.Calculate(context, lines);
|
||||
_shape = _shape == null ? shape : _shape.Value.Inflate(shape);
|
||||
_shape.Value.SetShape(context, lines);
|
||||
|
||||
var result = new List<Segment>();
|
||||
foreach (var (_, _, last, line) in lines.Enumerate())
|
||||
{
|
||||
foreach (var item in line)
|
||||
{
|
||||
result.Add(item);
|
||||
yield return item;
|
||||
}
|
||||
|
||||
if (!last)
|
||||
{
|
||||
result.Add(Segment.LineBreak);
|
||||
yield return Segment.LineBreak;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
yield break;
|
||||
}
|
||||
|
||||
_height = 0;
|
||||
return Enumerable.Empty<Segment>();
|
||||
_shape = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -599,6 +599,7 @@ namespace Spectre.Console.Rendering
|
||||
return stack.ToList();
|
||||
}
|
||||
|
||||
// TODO: Move this to Table
|
||||
internal static List<List<SegmentLine>> MakeSameHeight(int cellHeight, List<List<SegmentLine>> cells)
|
||||
{
|
||||
if (cells is null)
|
||||
@ -619,5 +620,49 @@ namespace Spectre.Console.Rendering
|
||||
|
||||
return cells;
|
||||
}
|
||||
|
||||
internal static (int Width, int Height) GetShape(RenderContext context, List<SegmentLine> lines)
|
||||
{
|
||||
if (context is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (lines is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(lines));
|
||||
}
|
||||
|
||||
var height = lines.Count;
|
||||
var width = lines.Max(l => CellCount(context, l));
|
||||
|
||||
return (width, height);
|
||||
}
|
||||
|
||||
internal static List<SegmentLine> SetShape(RenderContext context, List<SegmentLine> lines, (int Width, int Height) shape)
|
||||
{
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var length = CellCount(context, line);
|
||||
var missing = shape.Width - length;
|
||||
if (missing > 0)
|
||||
{
|
||||
line.Add(new Segment(new string(' ', missing)));
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.Count < shape.Height)
|
||||
{
|
||||
var missing = shape.Height - lines.Count;
|
||||
for (int i = 0; i < missing; i++)
|
||||
{
|
||||
var line = new SegmentLine();
|
||||
line.Add(new Segment(new string(' ', shape.Width)));
|
||||
lines.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
67
src/Spectre.Console/Rendering/SegmentShape.cs
Normal file
67
src/Spectre.Console/Rendering/SegmentShape.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
internal readonly struct SegmentShape
|
||||
{
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
|
||||
public SegmentShape(int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public static SegmentShape Calculate(RenderContext context, List<SegmentLine> lines)
|
||||
{
|
||||
if (context is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (lines is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(lines));
|
||||
}
|
||||
|
||||
var height = lines.Count;
|
||||
var width = lines.Max(l => Segment.CellCount(context, l));
|
||||
|
||||
return new SegmentShape(width, height);
|
||||
}
|
||||
|
||||
public SegmentShape Inflate(SegmentShape other)
|
||||
{
|
||||
return new SegmentShape(
|
||||
Math.Max(Width, other.Width),
|
||||
Math.Max(Height, other.Height));
|
||||
}
|
||||
|
||||
public void SetShape(RenderContext context, List<SegmentLine> lines)
|
||||
{
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var length = Segment.CellCount(context, line);
|
||||
var missing = Width - length;
|
||||
if (missing > 0)
|
||||
{
|
||||
line.Add(new Segment(new string(' ', missing)));
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.Count < Height)
|
||||
{
|
||||
var missing = Height - lines.Count;
|
||||
for (var i = 0; i < missing; i++)
|
||||
{
|
||||
var line = new SegmentLine();
|
||||
line.Add(new Segment(new string(' ', Width)));
|
||||
lines.Add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user