mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 00:42:51 +08:00
Add support for different spinners
This commit is contained in:
parent
3c504155bc
commit
cbed41e637
@ -1,39 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace ColumnsExample
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static async Task Main()
|
||||
public static void Main()
|
||||
{
|
||||
// Download some random users
|
||||
using var client = new HttpClient();
|
||||
dynamic users = JObject.Parse(
|
||||
await client.GetStringAsync("https://randomuser.me/api/?results=15"));
|
||||
|
||||
// Create a card for each user
|
||||
var cards = new List<Panel>();
|
||||
foreach(var user in users.results)
|
||||
foreach(var user in User.LoadUsers())
|
||||
{
|
||||
cards.Add(new Panel(GetCardContent(user))
|
||||
.Header($"{user.location.country}")
|
||||
.RoundedBorder().Expand());
|
||||
cards.Add(
|
||||
new Panel(GetCardContent(user))
|
||||
.Header($"{user.Country}")
|
||||
.RoundedBorder().Expand());
|
||||
}
|
||||
|
||||
// Render all cards in columns
|
||||
AnsiConsole.Render(new Columns(cards));
|
||||
}
|
||||
|
||||
private static string GetCardContent(dynamic user)
|
||||
private static string GetCardContent(User user)
|
||||
{
|
||||
var name = $"{user.name.first} {user.name.last}";
|
||||
var country = $"{user.location.city}";
|
||||
var name = $"{user.FirstName} {user.LastName}";
|
||||
var city = $"{user.City}";
|
||||
|
||||
return $"[b]{name}[/]\n[yellow]{country}[/]";
|
||||
return $"[b]{name}[/]\n[yellow]{city}[/]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
89
examples/Columns/User.cs
Normal file
89
examples/Columns/User.cs
Normal file
@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColumnsExample
|
||||
{
|
||||
public sealed class User
|
||||
{
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string City { get; set; }
|
||||
public string Country { get; set; }
|
||||
|
||||
public static List<User> LoadUsers()
|
||||
{
|
||||
return new List<User>
|
||||
{
|
||||
new User
|
||||
{
|
||||
FirstName = "Andrea",
|
||||
LastName = "Johansen",
|
||||
City = "Hornbæk",
|
||||
Country = "Denmark",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Brandon",
|
||||
LastName = "Cole",
|
||||
City = "Washington",
|
||||
Country = "United States",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Patrik",
|
||||
LastName = "Svensson",
|
||||
City = "Stockholm",
|
||||
Country = "Sweden",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Freya",
|
||||
LastName = "Thompson",
|
||||
City = "Rotorua",
|
||||
Country = "New Zealand",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "طاها",
|
||||
LastName = "رضایی",
|
||||
City = "اهواز",
|
||||
Country = "Iran",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Yara",
|
||||
LastName = "Simon",
|
||||
City = "Develier",
|
||||
Country = "Switzerland",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Giray",
|
||||
LastName = "Erbay",
|
||||
City = "Karabük",
|
||||
Country = "Turkey",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Miodrag",
|
||||
LastName = "Schaffer",
|
||||
City = "Möckern",
|
||||
Country = "Germany",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Carmela",
|
||||
LastName = "Lo Castro",
|
||||
City = "Firenze",
|
||||
Country = "Italy",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Roberto",
|
||||
LastName = "Sims",
|
||||
City = "Mallow",
|
||||
Country = "Ireland",
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
22
resources/scripts/Generate-Spinners.ps1
Normal file
22
resources/scripts/Generate-Spinners.ps1
Normal file
@ -0,0 +1,22 @@
|
||||
##########################################################
|
||||
# Script that generates progress spinners.
|
||||
##########################################################
|
||||
|
||||
$Output = Join-Path $PSScriptRoot "Temp"
|
||||
$Source = Join-Path $PSScriptRoot "/../../src/Spectre.Console"
|
||||
|
||||
if(!(Test-Path $Output -PathType Container)) {
|
||||
New-Item -ItemType Directory -Path $Output | Out-Null
|
||||
}
|
||||
|
||||
# Generate the files
|
||||
Push-Location Generator
|
||||
&dotnet run -- spinners "$Output" --input $Output
|
||||
if(!$?) {
|
||||
Pop-Location
|
||||
Throw "An error occured when generating code."
|
||||
}
|
||||
Pop-Location
|
||||
|
||||
# Copy the files to the correct location
|
||||
Copy-Item (Join-Path "$Output" "ProgressSpinner.Generated.cs") -Destination "$Source/Progress/ProgressSpinner.Generated.cs"
|
@ -7,7 +7,7 @@ using Spectre.IO;
|
||||
|
||||
namespace Generator.Commands
|
||||
{
|
||||
public sealed class ColorGeneratorCommand : Command<GeneratorCommandSettings>
|
||||
public sealed class ColorGeneratorCommand : Command<ColorGeneratorCommand.Settings>
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
@ -16,7 +16,13 @@ namespace Generator.Commands
|
||||
_fileSystem = new FileSystem();
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, GeneratorCommandSettings settings)
|
||||
public sealed class Settings : GeneratorSettings
|
||||
{
|
||||
[CommandOption("-i|--input <PATH>")]
|
||||
public string Input { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
var templates = new FilePath[]
|
||||
{
|
||||
@ -50,13 +56,4 @@ namespace Generator.Commands
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class GeneratorCommandSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<OUTPUT>")]
|
||||
public string Output { get; set; }
|
||||
|
||||
[CommandOption("-i|--input <PATH>")]
|
||||
public string Input { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ using SpectreEnvironment = Spectre.IO.Environment;
|
||||
|
||||
namespace Generator.Commands
|
||||
{
|
||||
public sealed class EmojiGeneratorCommand : AsyncCommand<GeneratorCommandSettings>
|
||||
public sealed class EmojiGeneratorCommand : AsyncCommand<EmojiGeneratorCommand.Settings>
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IEnvironment _environment;
|
||||
@ -24,9 +24,15 @@ namespace Generator.Commands
|
||||
private readonly Dictionary<string, string> _templates = new Dictionary<string, string>
|
||||
{
|
||||
{ "Templates/Emoji.Generated.template", "Emoji.Generated.cs" },
|
||||
{ "Templates/Emoji.Json.template", "emojis.json" },
|
||||
{ "Templates/Emoji.Json.template", "emojis.json" }, // For documentation
|
||||
};
|
||||
|
||||
public sealed class Settings : GeneratorSettings
|
||||
{
|
||||
[CommandOption("-i|--input <PATH>")]
|
||||
public string Input { get; set; }
|
||||
}
|
||||
|
||||
public EmojiGeneratorCommand()
|
||||
{
|
||||
_fileSystem = new FileSystem();
|
||||
@ -34,7 +40,7 @@ namespace Generator.Commands
|
||||
_parser = new HtmlParser();
|
||||
}
|
||||
|
||||
public override async Task<int> ExecuteAsync(CommandContext context, GeneratorCommandSettings settings)
|
||||
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
||||
{
|
||||
var output = new DirectoryPath(settings.Output);
|
||||
if (!_fileSystem.Directory.Exists(settings.Output))
|
||||
@ -60,7 +66,7 @@ namespace Generator.Commands
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async Task<Stream> FetchEmojis(GeneratorCommandSettings settings)
|
||||
private async Task<Stream> FetchEmojis(Settings settings)
|
||||
{
|
||||
var input = string.IsNullOrEmpty(settings.Input)
|
||||
? _environment.WorkingDirectory
|
||||
|
10
resources/scripts/Generator/Commands/GeneratorSettings.cs
Normal file
10
resources/scripts/Generator/Commands/GeneratorSettings.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using Spectre.Cli;
|
||||
|
||||
namespace Generator.Commands
|
||||
{
|
||||
public class GeneratorSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<OUTPUT>")]
|
||||
public string Output { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Generator.Models;
|
||||
using Scriban;
|
||||
using Spectre.Cli;
|
||||
using Spectre.IO;
|
||||
|
||||
namespace Generator.Commands
|
||||
{
|
||||
public sealed class SpinnerGeneratorCommand : Command<GeneratorSettings>
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public SpinnerGeneratorCommand()
|
||||
{
|
||||
_fileSystem = new FileSystem();
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, GeneratorSettings settings)
|
||||
{
|
||||
// Read the spinner model.
|
||||
var spinners = new List<Spinner>();
|
||||
spinners.AddRange(Spinner.Parse(File.ReadAllText("Data/spinners.json")));
|
||||
spinners.AddRange(Spinner.Parse(File.ReadAllText("Data/spinners_default.json")));
|
||||
|
||||
var output = new DirectoryPath(settings.Output);
|
||||
if (!_fileSystem.Directory.Exists(settings.Output))
|
||||
{
|
||||
_fileSystem.Directory.Create(settings.Output);
|
||||
}
|
||||
|
||||
// Parse the Scriban template.
|
||||
var templatePath = new FilePath("Templates/ProgressSpinner.Generated.template");
|
||||
var template = Template.Parse(File.ReadAllText(templatePath.FullPath));
|
||||
|
||||
// Render the template with the model.
|
||||
var result = template.Render(new { Spinners = spinners });
|
||||
|
||||
// Write output to file
|
||||
var file = output.CombineWithFilePath(templatePath.GetFilename().ChangeExtension(".cs"));
|
||||
File.WriteAllText(file.FullPath, result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
1368
resources/scripts/Generator/Data/spinners.json
Normal file
1368
resources/scripts/Generator/Data/spinners.json
Normal file
File diff suppressed because it is too large
Load Diff
30
resources/scripts/Generator/Data/spinners_default.json
Normal file
30
resources/scripts/Generator/Data/spinners_default.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"Default": {
|
||||
"interval": 100,
|
||||
"unicode": true,
|
||||
"frames": [
|
||||
"⣷",
|
||||
"⣯",
|
||||
"⣟",
|
||||
"⡿",
|
||||
"⢿",
|
||||
"⣻",
|
||||
"⣽",
|
||||
"⣾"
|
||||
]
|
||||
},
|
||||
"Ascii": {
|
||||
"interval": 100,
|
||||
"unicode": true,
|
||||
"frames": [
|
||||
"-",
|
||||
"\\",
|
||||
"|",
|
||||
"/",
|
||||
"-",
|
||||
"\\",
|
||||
"|",
|
||||
"/"
|
||||
]
|
||||
}
|
||||
}
|
@ -15,6 +15,9 @@
|
||||
<None Update="Data\colors.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\spinners.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\ColorTable.Generated.template">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
@ -24,6 +27,9 @@
|
||||
<None Update="Templates\ColorPalette.Generated.template">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\ProgressSpinner.Generated.template">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\Emoji.Json.template">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
31
resources/scripts/Generator/Models/Spinner.cs
Normal file
31
resources/scripts/Generator/Models/Spinner.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Humanizer;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Generator.Models
|
||||
{
|
||||
public sealed class Spinner
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string NormalizedName { get; set; }
|
||||
public int Interval { get; set; }
|
||||
public bool Unicode { get; set; }
|
||||
public List<string> Frames { get; set; }
|
||||
|
||||
public static IEnumerable<Spinner> Parse(string json)
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<Dictionary<string, Spinner>>(json);
|
||||
foreach (var item in data)
|
||||
{
|
||||
item.Value.Name = item.Key;
|
||||
item.Value.NormalizedName = item.Value.Name.Pascalize();
|
||||
|
||||
var frames = item.Value.Frames;
|
||||
item.Value.Frames = frames.Select(f => f.Replace("\\", "\\\\")).ToList();
|
||||
}
|
||||
|
||||
return data.Values;
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ namespace Generator
|
||||
{
|
||||
config.AddCommand<ColorGeneratorCommand>("colors");
|
||||
config.AddCommand<EmojiGeneratorCommand>("emoji");
|
||||
config.AddCommand<SpinnerGeneratorCommand>("spinners");
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
|
@ -2,6 +2,7 @@
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
// Generated from https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
|
@ -0,0 +1,45 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
public abstract partial class ProgressSpinner
|
||||
{
|
||||
{{~ for spinner in spinners ~}}
|
||||
private sealed class {{ spinner.normalized_name }}Spinner : ProgressSpinner
|
||||
{
|
||||
public override TimeSpan Interval => TimeSpan.FromMilliseconds({{ spinner.interval }});
|
||||
public override bool IsUnicode => {{ spinner.unicode }};
|
||||
public override IReadOnlyList<string> Frames => new List<string>
|
||||
{
|
||||
{{~ for frame in spinner.frames ~}}
|
||||
"{{ frame }}",
|
||||
{{~ end ~}}
|
||||
};
|
||||
}
|
||||
{{~ end ~}}
|
||||
|
||||
/// <summary>
|
||||
/// Contains all predefined spinners.
|
||||
/// </summary>
|
||||
public static class Known
|
||||
{
|
||||
{{~ for spinner in spinners ~}}
|
||||
/// <summary>
|
||||
/// Gets the "{{ spinner.name }}" spinner.
|
||||
/// </summary>
|
||||
public static ProgressSpinner {{ spinner.normalized_name }} { get; } = new {{ spinner.normalized_name }}Spinner();
|
||||
{{~ end ~}}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user