mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 21:38:16 +08:00
Add Layout widget (#1041)
* Add width to panels * Add height to panels * Replace RenderContext with RenderOptions * Remove exclusivity from alternative buffer * Add Layout widget * Add Align widget
This commit is contained in:
@ -41,7 +41,7 @@ internal sealed class LiveDisplayRenderer : IRenderHook
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Process(RenderContext context, IEnumerable<IRenderable> renderables)
|
||||
public IEnumerable<IRenderable> Process(RenderOptions options, IEnumerable<IRenderable> renderables)
|
||||
{
|
||||
lock (_context.Lock)
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ internal sealed class LiveRenderable : Renderable
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
protected override IEnumerable<Segment> Render(RenderOptions options, int maxWidth)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
@ -75,10 +75,10 @@ internal sealed class LiveRenderable : Renderable
|
||||
|
||||
if (_renderable != null)
|
||||
{
|
||||
var segments = _renderable.Render(context, maxWidth);
|
||||
var segments = _renderable.Render(options, maxWidth);
|
||||
var lines = Segment.SplitLines(segments);
|
||||
|
||||
var shape = SegmentShape.Calculate(context, lines);
|
||||
var shape = SegmentShape.Calculate(options, lines);
|
||||
if (shape.Height > _console.Profile.Height)
|
||||
{
|
||||
if (Overflow == VerticalOverflow.Crop)
|
||||
@ -97,12 +97,12 @@ internal sealed class LiveRenderable : Renderable
|
||||
lines.RemoveRange(0, start);
|
||||
}
|
||||
|
||||
shape = SegmentShape.Calculate(context, lines);
|
||||
shape = SegmentShape.Calculate(options, lines);
|
||||
}
|
||||
else if (Overflow == VerticalOverflow.Ellipsis)
|
||||
{
|
||||
var ellipsisText = _console.Profile.Capabilities.Unicode ? "…" : "...";
|
||||
var ellipsis = new SegmentLine(((IRenderable)new Markup($"[yellow]{ellipsisText}[/]")).Render(context, maxWidth));
|
||||
var ellipsis = new SegmentLine(((IRenderable)new Markup($"[yellow]{ellipsisText}[/]")).Render(options, maxWidth));
|
||||
|
||||
if (OverflowCropping == VerticalOverflowCropping.Bottom)
|
||||
{
|
||||
@ -120,14 +120,14 @@ internal sealed class LiveRenderable : Renderable
|
||||
lines.Insert(0, ellipsis);
|
||||
}
|
||||
|
||||
shape = SegmentShape.Calculate(context, lines);
|
||||
shape = SegmentShape.Calculate(options, lines);
|
||||
}
|
||||
|
||||
DidOverflow = true;
|
||||
}
|
||||
|
||||
_shape = _shape == null ? shape : _shape.Value.Inflate(shape);
|
||||
_shape.Value.Apply(context, ref lines);
|
||||
_shape.Value.Apply(options, ref lines);
|
||||
|
||||
foreach (var (_, _, last, line) in lines.Enumerate())
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ public sealed class DownloadedColumn : ProgressColumn
|
||||
public CultureInfo? Culture { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var total = new FileSize(task.MaxValue);
|
||||
|
||||
|
@ -14,7 +14,7 @@ public sealed class ElapsedTimeColumn : ProgressColumn
|
||||
public Style Style { get; set; } = new Style(foreground: Color.Blue);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var elapsed = task.ElapsedTime;
|
||||
if (elapsed == null)
|
||||
@ -31,7 +31,7 @@ public sealed class ElapsedTimeColumn : ProgressColumn
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int? GetColumnWidth(RenderContext context)
|
||||
public override int? GetColumnWidth(RenderOptions options)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
@ -16,15 +16,15 @@ public sealed class PercentageColumn : ProgressColumn
|
||||
public Style CompletedStyle { get; set; } = new Style(foreground: Color.Green);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var percentage = (int)task.Percentage;
|
||||
var style = percentage == 100 ? CompletedStyle : Style ?? Style.Plain;
|
||||
return new Text($"{percentage}%", style).RightAligned();
|
||||
return new Text($"{percentage}%", style).RightJustified();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int? GetColumnWidth(RenderContext context)
|
||||
public override int? GetColumnWidth(RenderOptions options)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public sealed class ProgressBarColumn : ProgressColumn
|
||||
public Style IndeterminateStyle { get; set; } = ProgressBar.DefaultPulseStyle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
return new ProgressBar
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ public sealed class RemainingTimeColumn : ProgressColumn
|
||||
public Style Style { get; set; } = new Style(foreground: Color.Blue);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var remaining = task.RemainingTime;
|
||||
if (remaining == null)
|
||||
@ -31,7 +31,7 @@ public sealed class RemainingTimeColumn : ProgressColumn
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int? GetColumnWidth(RenderContext context)
|
||||
public override int? GetColumnWidth(RenderOptions options)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
@ -95,9 +95,9 @@ public sealed class SpinnerColumn : ProgressColumn
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var useAscii = !context.Unicode && _spinner.IsUnicode;
|
||||
var useAscii = !options.Unicode && _spinner.IsUnicode;
|
||||
var spinner = useAscii ? Spinner.Known.Ascii : _spinner ?? Spinner.Known.Default;
|
||||
|
||||
if (!task.IsStarted)
|
||||
@ -123,24 +123,24 @@ public sealed class SpinnerColumn : ProgressColumn
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int? GetColumnWidth(RenderContext context)
|
||||
public override int? GetColumnWidth(RenderOptions options)
|
||||
{
|
||||
return GetMaxWidth(context);
|
||||
return GetMaxWidth(options);
|
||||
}
|
||||
|
||||
private int GetMaxWidth(RenderContext context)
|
||||
private int GetMaxWidth(RenderOptions options)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_maxWidth == null)
|
||||
{
|
||||
var useAscii = !context.Unicode && _spinner.IsUnicode;
|
||||
var useAscii = !options.Unicode && _spinner.IsUnicode;
|
||||
var spinner = useAscii ? Spinner.Known.Ascii : _spinner ?? Spinner.Known.Default;
|
||||
|
||||
_maxWidth = Math.Max(
|
||||
Math.Max(
|
||||
((IRenderable)new Markup(PendingText ?? " ")).Measure(context, int.MaxValue).Max,
|
||||
((IRenderable)new Markup(CompletedText ?? " ")).Measure(context, int.MaxValue).Max),
|
||||
((IRenderable)new Markup(PendingText ?? " ")).Measure(options, int.MaxValue).Max,
|
||||
((IRenderable)new Markup(CompletedText ?? " ")).Measure(options, int.MaxValue).Max),
|
||||
spinner.Frames.Max(frame => Cell.GetCellLength(frame)));
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,9 @@ public sealed class TaskDescriptionColumn : ProgressColumn
|
||||
public Justify Alignment { get; set; } = Justify.Right;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var text = task.Description?.RemoveNewLines()?.Trim();
|
||||
return new Markup(text ?? string.Empty).Overflow(Overflow.Ellipsis).Alignment(Alignment);
|
||||
return new Markup(text ?? string.Empty).Overflow(Overflow.Ellipsis).Justify(Alignment);
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ public sealed class TransferSpeedColumn : ProgressColumn
|
||||
public CultureInfo? Culture { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
public override IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
if (task.Speed == null)
|
||||
{
|
||||
|
@ -13,18 +13,18 @@ public abstract class ProgressColumn
|
||||
/// <summary>
|
||||
/// Gets a renderable representing the column.
|
||||
/// </summary>
|
||||
/// <param name="context">The render context.</param>
|
||||
/// <param name="options">The render options.</param>
|
||||
/// <param name="task">The task.</param>
|
||||
/// <param name="deltaTime">The elapsed time since last call.</param>
|
||||
/// <returns>A renderable representing the column.</returns>
|
||||
public abstract IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime);
|
||||
public abstract IRenderable Render(RenderOptions options, ProgressTask task, TimeSpan deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of the column.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="options">The render options.</param>
|
||||
/// <returns>The width of the column, or <c>null</c> to calculate.</returns>
|
||||
public virtual int? GetColumnWidth(RenderContext context)
|
||||
public virtual int? GetColumnWidth(RenderOptions options)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -13,5 +13,5 @@ internal abstract class ProgressRenderer : IRenderHook
|
||||
}
|
||||
|
||||
public abstract void Update(ProgressContext context);
|
||||
public abstract IEnumerable<IRenderable> Process(RenderContext context, IEnumerable<IRenderable> renderables);
|
||||
public abstract IEnumerable<IRenderable> Process(RenderOptions options, IEnumerable<IRenderable> renderables);
|
||||
}
|
@ -64,7 +64,7 @@ internal sealed class DefaultProgressRenderer : ProgressRenderer
|
||||
_stopwatch.Start();
|
||||
}
|
||||
|
||||
var renderContext = new RenderContext(_console.Profile.Capabilities);
|
||||
var renderContext = RenderOptions.Create(_console, _console.Profile.Capabilities);
|
||||
|
||||
var delta = _stopwatch.Elapsed - _lastUpdate;
|
||||
_lastUpdate = _stopwatch.Elapsed;
|
||||
@ -105,7 +105,7 @@ internal sealed class DefaultProgressRenderer : ProgressRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<IRenderable> Process(RenderContext context, IEnumerable<IRenderable> renderables)
|
||||
public override IEnumerable<IRenderable> Process(RenderOptions options, IEnumerable<IRenderable> renderables)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ internal sealed class FallbackProgressRenderer : ProgressRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<IRenderable> Process(RenderContext context, IEnumerable<IRenderable> renderables)
|
||||
public override IEnumerable<IRenderable> Process(RenderOptions options, IEnumerable<IRenderable> renderables)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ internal sealed class FallbackStatusRenderer : ProgressRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<IRenderable> Process(RenderContext context, IEnumerable<IRenderable> renderables)
|
||||
public override IEnumerable<IRenderable> Process(RenderOptions options, IEnumerable<IRenderable> renderables)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
Reference in New Issue
Block a user