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

committed by
Patrik Svensson

parent
3c504155bc
commit
cbed41e637
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
@ -11,8 +13,8 @@ namespace Spectre.Console
|
||||
private const string ACCUMULATED = "SPINNER_ACCUMULATED";
|
||||
private const string INDEX = "SPINNER_INDEX";
|
||||
|
||||
private readonly string _ansiSequence = "⣷⣯⣟⡿⢿⣻⣽⣾";
|
||||
private readonly string _asciiSequence = "-\\|/-\\|/";
|
||||
private readonly ProgressSpinner _spinner;
|
||||
private int? _maxLength;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected internal override int? ColumnWidth => 1;
|
||||
@ -25,26 +27,48 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public Style Style { get; set; } = new Style(foreground: Color.Yellow);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SpinnerColumn"/> class.
|
||||
/// </summary>
|
||||
public SpinnerColumn()
|
||||
: this(ProgressSpinner.Known.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SpinnerColumn"/> class.
|
||||
/// </summary>
|
||||
/// <param name="spinner">The spinner to use.</param>
|
||||
public SpinnerColumn(ProgressSpinner spinner)
|
||||
{
|
||||
_spinner = spinner ?? throw new ArgumentNullException(nameof(spinner));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IRenderable Render(RenderContext context, ProgressTask task, TimeSpan deltaTime)
|
||||
{
|
||||
var useAscii = (context.LegacyConsole || !context.Unicode) && _spinner.IsUnicode;
|
||||
var spinner = useAscii ? ProgressSpinner.Known.Ascii : _spinner;
|
||||
|
||||
if (!task.IsStarted || task.IsFinished)
|
||||
{
|
||||
return new Markup(" ");
|
||||
if (_maxLength == null)
|
||||
{
|
||||
_maxLength = _spinner.Frames.Max(frame => Cell.GetCellLength(context, frame));
|
||||
}
|
||||
|
||||
return new Markup(new string(' ', _maxLength.Value));
|
||||
}
|
||||
|
||||
var accumulated = task.State.Update<double>(ACCUMULATED, acc => acc + deltaTime.TotalMilliseconds);
|
||||
if (accumulated >= 100)
|
||||
if (accumulated >= _spinner.Interval.TotalMilliseconds)
|
||||
{
|
||||
task.State.Update<double>(ACCUMULATED, _ => 0);
|
||||
task.State.Update<int>(INDEX, index => index + 1);
|
||||
}
|
||||
|
||||
var useAscii = context.LegacyConsole || !context.Unicode;
|
||||
var sequence = useAscii ? _asciiSequence : _ansiSequence;
|
||||
|
||||
var index = task.State.Get<int>(INDEX);
|
||||
return new Markup(sequence[index % sequence.Length].ToString(), Style ?? Style.Plain);
|
||||
return new Markup(spinner.Frames[index % spinner.Frames.Count], Style ?? Style.Plain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public bool AutoClear { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the refresh rate if <c>AutoRefresh</c> is enabled.
|
||||
/// Defaults to 10 times/second.
|
||||
/// </summary>
|
||||
public TimeSpan RefreshRate { get; set; } = TimeSpan.FromMilliseconds(100);
|
||||
|
||||
internal List<ProgressColumn> Columns { get; }
|
||||
|
||||
/// <summary>
|
||||
@ -110,7 +116,7 @@ namespace Spectre.Console
|
||||
if (interactive)
|
||||
{
|
||||
var columns = new List<ProgressColumn>(Columns);
|
||||
return new InteractiveProgressRenderer(_console, columns);
|
||||
return new InteractiveProgressRenderer(_console, columns, RefreshRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
1870
src/Spectre.Console/Progress/ProgressSpinner.Generated.cs
Normal file
1870
src/Spectre.Console/Progress/ProgressSpinner.Generated.cs
Normal file
File diff suppressed because it is too large
Load Diff
27
src/Spectre.Console/Progress/ProgressSpinner.cs
Normal file
27
src/Spectre.Console/Progress/ProgressSpinner.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a spinner used in a <see cref="SpinnerColumn"/>.
|
||||
/// </summary>
|
||||
public abstract partial class ProgressSpinner
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the update interval for the spinner.
|
||||
/// </summary>
|
||||
public abstract TimeSpan Interval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the spinner
|
||||
/// uses Unicode characters.
|
||||
/// </summary>
|
||||
public abstract bool IsUnicode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the spinner frames.
|
||||
/// </summary>
|
||||
public abstract IReadOnlyList<string> Frames { get; }
|
||||
}
|
||||
}
|
@ -15,9 +15,9 @@ namespace Spectre.Console.Internal
|
||||
private readonly Stopwatch _stopwatch;
|
||||
private TimeSpan _lastUpdate;
|
||||
|
||||
public override TimeSpan RefreshRate => TimeSpan.FromMilliseconds(100);
|
||||
public override TimeSpan RefreshRate { get; }
|
||||
|
||||
public InteractiveProgressRenderer(IAnsiConsole console, List<ProgressColumn> columns)
|
||||
public InteractiveProgressRenderer(IAnsiConsole console, List<ProgressColumn> columns, TimeSpan refreshRate)
|
||||
{
|
||||
_console = console ?? throw new ArgumentNullException(nameof(console));
|
||||
_columns = columns ?? throw new ArgumentNullException(nameof(columns));
|
||||
@ -25,6 +25,8 @@ namespace Spectre.Console.Internal
|
||||
_lock = new object();
|
||||
_stopwatch = new Stopwatch();
|
||||
_lastUpdate = TimeSpan.Zero;
|
||||
|
||||
RefreshRate = refreshRate;
|
||||
}
|
||||
|
||||
public override void Started()
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
|
Reference in New Issue
Block a user