209 lines
6.7 KiB
C#
209 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Unosquare.Swan {
|
|
/// <summary>
|
|
/// A console terminal helper to create nicer output and receive input from the user
|
|
/// This class is thread-safe :).
|
|
/// </summary>
|
|
public static partial class Terminal {
|
|
#region ReadKey
|
|
|
|
/// <summary>
|
|
/// Reads a key from the Terminal. This is the closest equivalent to Console.ReadKey.
|
|
/// </summary>
|
|
/// <param name="intercept">if set to <c>true</c> the pressed key will not be rendered to the output.</param>
|
|
/// <param name="disableLocking">if set to <c>true</c> the output will continue to be shown.
|
|
/// This is useful for services and daemons that are running as console applications and wait for a key to exit the program.</param>
|
|
/// <returns>The console key information.</returns>
|
|
public static ConsoleKeyInfo ReadKey(Boolean intercept, Boolean disableLocking = false) {
|
|
if(IsConsolePresent == false) {
|
|
return default;
|
|
}
|
|
|
|
if(disableLocking) {
|
|
return Console.ReadKey(intercept);
|
|
}
|
|
|
|
lock(SyncLock) {
|
|
Flush();
|
|
InputDone.Reset();
|
|
try {
|
|
Console.CursorVisible = true;
|
|
return Console.ReadKey(intercept);
|
|
} finally {
|
|
Console.CursorVisible = false;
|
|
InputDone.Set();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads a key from the Terminal.
|
|
/// </summary>
|
|
/// <param name="prompt">The prompt.</param>
|
|
/// <param name="preventEcho">if set to <c>true</c> [prevent echo].</param>
|
|
/// <returns>The console key information.</returns>
|
|
public static ConsoleKeyInfo ReadKey(this String prompt, Boolean preventEcho) {
|
|
if(IsConsolePresent == false) {
|
|
return default;
|
|
}
|
|
|
|
lock(SyncLock) {
|
|
if(prompt != null) {
|
|
($" {(String.IsNullOrWhiteSpace(Settings.LoggingTimeFormat) ? String.Empty : DateTime.Now.ToString(Settings.LoggingTimeFormat) + " ")}" +
|
|
$"{Settings.UserInputPrefix} << {prompt} ").Write(ConsoleColor.White);
|
|
}
|
|
|
|
ConsoleKeyInfo input = ReadKey(true);
|
|
String echo = preventEcho ? String.Empty : input.Key.ToString();
|
|
echo.WriteLine();
|
|
return input;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads a key from the terminal preventing the key from being echoed.
|
|
/// </summary>
|
|
/// <param name="prompt">The prompt.</param>
|
|
/// <returns>A value that identifies the console key.</returns>
|
|
public static ConsoleKeyInfo ReadKey(this String prompt) => prompt.ReadKey(true);
|
|
|
|
#endregion
|
|
|
|
#region Other Terminal Read Methods
|
|
|
|
/// <summary>
|
|
/// Reads a line of text from the console.
|
|
/// </summary>
|
|
/// <returns>The read line.</returns>
|
|
public static String ReadLine() {
|
|
if(IsConsolePresent == false) {
|
|
return default;
|
|
}
|
|
|
|
lock(SyncLock) {
|
|
Flush();
|
|
InputDone.Reset();
|
|
|
|
try {
|
|
Console.CursorVisible = true;
|
|
return Console.ReadLine();
|
|
} finally {
|
|
Console.CursorVisible = false;
|
|
InputDone.Set();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads a number from the input. If unable to parse, it returns the default number.
|
|
/// </summary>
|
|
/// <param name="prompt">The prompt.</param>
|
|
/// <param name="defaultNumber">The default number.</param>
|
|
/// <returns>
|
|
/// Conversions of string representation of a number to its 32-bit signed integer equivalent.
|
|
/// </returns>
|
|
public static Int32 ReadNumber(this String prompt, Int32 defaultNumber) {
|
|
if(IsConsolePresent == false) {
|
|
return defaultNumber;
|
|
}
|
|
|
|
lock(SyncLock) {
|
|
$" {DateTime.Now:HH:mm:ss} USR << {prompt} (default is {defaultNumber}): ".Write(ConsoleColor.White);
|
|
|
|
String input = ReadLine();
|
|
return Int32.TryParse(input, out Int32 parsedInt) ? parsedInt : defaultNumber;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a table prompt where the user can enter an option based on the options dictionary provided.
|
|
/// </summary>
|
|
/// <param name="title">The title.</param>
|
|
/// <param name="options">The options.</param>
|
|
/// <param name="anyKeyOption">Any key option.</param>
|
|
/// <returns>A value that identifies the console key that was pressed.</returns>
|
|
public static ConsoleKeyInfo ReadPrompt(this String title, Dictionary<ConsoleKey, String> options, String anyKeyOption) {
|
|
if(IsConsolePresent == false) {
|
|
return default;
|
|
}
|
|
|
|
const ConsoleColor textColor = ConsoleColor.White;
|
|
Int32 lineLength = Console.BufferWidth;
|
|
Int32 lineAlign = -(lineLength - 2);
|
|
String textFormat = "{0," + lineAlign + "}";
|
|
|
|
// lock the output as an atomic operation
|
|
lock(SyncLock) {
|
|
{ // Top border
|
|
Table.TopLeft();
|
|
Table.Horizontal(-lineAlign);
|
|
Table.TopRight();
|
|
}
|
|
|
|
{ // Title
|
|
Table.Vertical();
|
|
String titleText = String.Format(
|
|
textFormat,
|
|
String.IsNullOrWhiteSpace(title) ? " Select an option from the list below." : $" {title}");
|
|
titleText.Write(textColor);
|
|
Table.Vertical();
|
|
}
|
|
|
|
{ // Title Bottom
|
|
Table.LeftTee();
|
|
Table.Horizontal(lineLength - 2);
|
|
Table.RightTee();
|
|
}
|
|
|
|
// Options
|
|
foreach(KeyValuePair<ConsoleKey, String> kvp in options) {
|
|
Table.Vertical();
|
|
String.Format(textFormat,
|
|
$" {"[ " + kvp.Key + " ]",-10} {kvp.Value}").Write(textColor);
|
|
Table.Vertical();
|
|
}
|
|
|
|
// Any Key Options
|
|
if(String.IsNullOrWhiteSpace(anyKeyOption) == false) {
|
|
Table.Vertical();
|
|
String.Format(textFormat, " ").Write(ConsoleColor.Gray);
|
|
Table.Vertical();
|
|
|
|
Table.Vertical();
|
|
String.Format(textFormat,
|
|
$" {" ",-10} {anyKeyOption}").Write(ConsoleColor.Gray);
|
|
Table.Vertical();
|
|
}
|
|
|
|
{ // Input section
|
|
Table.LeftTee();
|
|
Table.Horizontal(lineLength - 2);
|
|
Table.RightTee();
|
|
|
|
Table.Vertical();
|
|
String.Format(textFormat,
|
|
Settings.UserOptionText).Write(ConsoleColor.Green);
|
|
Table.Vertical();
|
|
|
|
Table.BottomLeft();
|
|
Table.Horizontal(lineLength - 2);
|
|
Table.BottomRight();
|
|
}
|
|
}
|
|
|
|
Int32 inputLeft = Settings.UserOptionText.Length + 3;
|
|
|
|
SetCursorPosition(inputLeft, CursorTop - 2);
|
|
ConsoleKeyInfo userInput = ReadKey(true);
|
|
userInput.Key.ToString().Write(ConsoleColor.Gray);
|
|
|
|
SetCursorPosition(0, CursorTop + 2);
|
|
return userInput;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|