using System; using System.Collections.Generic; using System.Threading.Tasks; using Spectre.Console.Internal; using Spectre.Console.Rendering; namespace Spectre.Console { /// /// Represents a task list. /// public sealed class Progress { private readonly IAnsiConsole _console; /// /// Gets or sets a value indicating whether or not task list should auto refresh. /// Defaults to true. /// public bool AutoRefresh { get; set; } = true; /// /// Gets or sets a value indicating whether or not the task list should /// be cleared once it completes. /// Defaults to false. /// public bool AutoClear { get; set; } internal List Columns { get; } /// /// Initializes a new instance of the class. /// /// The console to render to. public Progress(IAnsiConsole console) { _console = console ?? throw new ArgumentNullException(nameof(console)); // Initialize with default columns Columns = new List { new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn(), }; } /// /// Starts the progress task list. /// /// The action to execute. public void Start(Action action) { var task = StartAsync(ctx => { action(ctx); return Task.CompletedTask; }); task.GetAwaiter().GetResult(); } /// /// Starts the progress task list. /// /// The action to execute. /// A representing the asynchronous operation. public async Task StartAsync(Func action) { if (action is null) { throw new ArgumentNullException(nameof(action)); } var renderer = CreateRenderer(); renderer.Started(); try { using (new RenderHookScope(_console, renderer)) { var context = new ProgressContext(_console, renderer); if (AutoRefresh) { using (var thread = new ProgressRefreshThread(context, renderer.RefreshRate)) { await action(context).ConfigureAwait(false); } } else { await action(context).ConfigureAwait(false); } context.Refresh(); } } finally { renderer.Completed(AutoClear); } } private ProgressRenderer CreateRenderer() { var caps = _console.Capabilities; var interactive = caps.SupportsInteraction && caps.SupportsAnsi; if (interactive) { var columns = new List(Columns); return new InteractiveProgressRenderer(_console, columns); } else { return new NonInteractiveProgressRenderer(); } } } }