mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 18:40:50 +08:00 
			
		
		
		
	Progress bar header and footer (#1262)
This commit is contained in:
		@@ -34,6 +34,19 @@ public static class ProgressExtensions
 | 
			
		||||
        return progress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Sets an optional hook to intercept rendering.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="progress">The <see cref="Progress"/> instance.</param>
 | 
			
		||||
    /// <param name="renderHook">The custom render function.</param>
 | 
			
		||||
    /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
    public static Progress UseRenderHook(this Progress progress, Func<IRenderable, IReadOnlyList<ProgressTask>, IRenderable> renderHook)
 | 
			
		||||
    {
 | 
			
		||||
        progress.RenderHook = renderHook;
 | 
			
		||||
 | 
			
		||||
        return progress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Sets whether or not auto refresh is enabled.
 | 
			
		||||
    /// If disabled, you will manually have to refresh the progress.
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,11 @@ public sealed class Progress
 | 
			
		||||
{
 | 
			
		||||
    private readonly IAnsiConsole _console;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Gets or sets a optional custom render function.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public Func<IRenderable, IReadOnlyList<ProgressTask>, IRenderable> RenderHook { get; set; } = (renderable, _) => renderable;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Gets or sets a value indicating whether or not task list should auto refresh.
 | 
			
		||||
    /// Defaults to <c>true</c>.
 | 
			
		||||
@@ -158,7 +163,7 @@ public sealed class Progress
 | 
			
		||||
        if (interactive)
 | 
			
		||||
        {
 | 
			
		||||
            var columns = new List<ProgressColumn>(Columns);
 | 
			
		||||
            return new DefaultProgressRenderer(_console, columns, RefreshRate, HideCompleted);
 | 
			
		||||
            return new DefaultProgressRenderer(_console, columns, RefreshRate, HideCompleted, RenderHook);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,12 @@ internal sealed class DefaultProgressRenderer : ProgressRenderer
 | 
			
		||||
    private readonly object _lock;
 | 
			
		||||
    private readonly Stopwatch _stopwatch;
 | 
			
		||||
    private readonly bool _hideCompleted;
 | 
			
		||||
    private readonly Func<IRenderable, IReadOnlyList<ProgressTask>, IRenderable> _renderHook;
 | 
			
		||||
    private TimeSpan _lastUpdate;
 | 
			
		||||
 | 
			
		||||
    public override TimeSpan RefreshRate { get; }
 | 
			
		||||
 | 
			
		||||
    public DefaultProgressRenderer(IAnsiConsole console, List<ProgressColumn> columns, TimeSpan refreshRate, bool hideCompleted)
 | 
			
		||||
    public DefaultProgressRenderer(IAnsiConsole console, List<ProgressColumn> columns, TimeSpan refreshRate, bool hideCompleted, Func<IRenderable, IReadOnlyList<ProgressTask>, IRenderable> renderHook)
 | 
			
		||||
    {
 | 
			
		||||
        _console = console ?? throw new ArgumentNullException(nameof(console));
 | 
			
		||||
        _columns = columns ?? throw new ArgumentNullException(nameof(columns));
 | 
			
		||||
@@ -21,6 +22,7 @@ internal sealed class DefaultProgressRenderer : ProgressRenderer
 | 
			
		||||
        _stopwatch = new Stopwatch();
 | 
			
		||||
        _lastUpdate = TimeSpan.Zero;
 | 
			
		||||
        _hideCompleted = hideCompleted;
 | 
			
		||||
        _renderHook = renderHook;
 | 
			
		||||
 | 
			
		||||
        RefreshRate = refreshRate;
 | 
			
		||||
    }
 | 
			
		||||
@@ -95,13 +97,20 @@ internal sealed class DefaultProgressRenderer : ProgressRenderer
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Add rows
 | 
			
		||||
            foreach (var task in context.GetTasks().Where(tsk => !(_hideCompleted && tsk.IsFinished)))
 | 
			
		||||
            var tasks = context.GetTasks();
 | 
			
		||||
 | 
			
		||||
            var layout = new Grid();
 | 
			
		||||
            layout.AddColumn();
 | 
			
		||||
 | 
			
		||||
            foreach (var task in tasks.Where(tsk => !(_hideCompleted && tsk.IsFinished)))
 | 
			
		||||
            {
 | 
			
		||||
                var columns = _columns.Select(column => column.Render(renderContext, task, delta));
 | 
			
		||||
                grid.AddRow(columns.ToArray());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _live.SetRenderable(new Padder(grid, new Padding(0, 1)));
 | 
			
		||||
            layout.AddRow(grid);
 | 
			
		||||
 | 
			
		||||
            _live.SetRenderable(new Padder(_renderHook(layout, tasks), new Padding(0, 1)));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,28 @@
 | 
			
		||||
namespace Spectre.Console;
 | 
			
		||||
 | 
			
		||||
internal sealed class ControlCode : Renderable
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// A control code.
 | 
			
		||||
/// </summary>
 | 
			
		||||
public sealed class ControlCode : Renderable
 | 
			
		||||
{
 | 
			
		||||
    private readonly Segment _segment;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Initializes a new instance of the <see cref="ControlCode"/> class.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="control">The control code.</param>
 | 
			
		||||
    public ControlCode(string control)
 | 
			
		||||
    {
 | 
			
		||||
        _segment = Segment.Control(control);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    protected override Measurement Measure(RenderOptions options, int maxWidth)
 | 
			
		||||
    {
 | 
			
		||||
        return new Measurement(0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    protected override IEnumerable<Segment> Render(RenderOptions options, int maxWidth)
 | 
			
		||||
    {
 | 
			
		||||
        if (options.Ansi)
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ public sealed class Rows : Renderable, IExpandable
 | 
			
		||||
 | 
			
		||||
                if (last)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!segment.IsLineBreak)
 | 
			
		||||
                    if (!segment.IsLineBreak && child is not ControlCode)
 | 
			
		||||
                    {
 | 
			
		||||
                        result.Add(Segment.LineBreak);
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user