mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 00:42:51 +08:00

* Fixes a bug with `SelectionPrompt` and page size. * Allow `IAnsiConsoleInput` to return `null`.
82 lines
2.5 KiB
C#
82 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using Spectre.Console;
|
|
|
|
namespace Generator.Commands
|
|
{
|
|
public sealed class AsciiCastInput : IAnsiConsoleInput
|
|
{
|
|
private readonly Queue<(ConsoleKeyInfo?, int)> _input;
|
|
private readonly Random _random = new Random();
|
|
|
|
public AsciiCastInput()
|
|
{
|
|
_input = new Queue<(ConsoleKeyInfo?, int)>();
|
|
}
|
|
|
|
public void PushText(string input, int keypressDelayMs)
|
|
{
|
|
if (input is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(input));
|
|
}
|
|
|
|
foreach (var character in input)
|
|
{
|
|
PushCharacter(character, keypressDelayMs);
|
|
}
|
|
}
|
|
|
|
public void PushTextWithEnter(string input, int keypressDelayMs)
|
|
{
|
|
PushText(input, keypressDelayMs);
|
|
PushKey(ConsoleKey.Enter, keypressDelayMs);
|
|
}
|
|
|
|
public void PushCharacter(char input, int keypressDelayMs)
|
|
{
|
|
var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2));
|
|
|
|
switch (input)
|
|
{
|
|
case '↑':
|
|
PushKey(ConsoleKey.UpArrow, keypressDelayMs);
|
|
break;
|
|
case '↓':
|
|
PushKey(ConsoleKey.DownArrow, keypressDelayMs);
|
|
break;
|
|
case '↲':
|
|
PushKey(ConsoleKey.Enter, keypressDelayMs);
|
|
break;
|
|
case '¦':
|
|
_input.Enqueue((null, delay));
|
|
break;
|
|
default:
|
|
var control = char.IsUpper(input);
|
|
_input.Enqueue((new ConsoleKeyInfo(input, (ConsoleKey)input, false, false, control), delay));
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void PushKey(ConsoleKey input, int keypressDelayMs)
|
|
{
|
|
var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2));
|
|
_input.Enqueue((new ConsoleKeyInfo((char)input, input, false, false, false), delay));
|
|
}
|
|
|
|
public ConsoleKeyInfo? ReadKey(bool intercept)
|
|
{
|
|
if (_input.Count == 0)
|
|
{
|
|
throw new InvalidOperationException("No input available.");
|
|
}
|
|
|
|
var result = _input.Dequeue();
|
|
|
|
Thread.Sleep(result.Item2);
|
|
return result.Item1;
|
|
}
|
|
}
|
|
}
|