diff --git a/Sharprompt/ConfirmOptions.cs b/Sharprompt/ConfirmOptions.cs index f084e8d..da32230 100644 --- a/Sharprompt/ConfirmOptions.cs +++ b/Sharprompt/ConfirmOptions.cs @@ -1,15 +1,6 @@ -using System; +namespace Sharprompt; -namespace Sharprompt; - -public class ConfirmOptions +public class ConfirmOptions : PromptOptions { - public string Message { get; set; } = null!; - public bool? DefaultValue { get; set; } - - internal void EnsureOptions() - { - ArgumentNullException.ThrowIfNull(Message); - } } diff --git a/Sharprompt/Forms/ConfirmForm.cs b/Sharprompt/Forms/ConfirmForm.cs index 499fe7e..8b25173 100644 --- a/Sharprompt/Forms/ConfirmForm.cs +++ b/Sharprompt/Forms/ConfirmForm.cs @@ -7,7 +7,7 @@ namespace Sharprompt.Forms; internal class ConfirmForm : TextFormBase { - public ConfirmForm(ConfirmOptions options) + public ConfirmForm(ConfirmOptions options, PromptConfiguration configuration) : base(configuration) { options.EnsureOptions(); diff --git a/Sharprompt/Forms/FormBase.cs b/Sharprompt/Forms/FormBase.cs index b47f263..98f242b 100644 --- a/Sharprompt/Forms/FormBase.cs +++ b/Sharprompt/Forms/FormBase.cs @@ -11,17 +11,21 @@ namespace Sharprompt.Forms; internal abstract class FormBase : IDisposable { - protected FormBase() + protected FormBase(PromptConfiguration configuration) { - _consoleDriver = Prompt.ConsoleDriverFactory() ?? throw new InvalidOperationException("ConsoleDriverFactory must return a non-null IConsoleDriver instance."); + _configuration = configuration; + _consoleDriver = configuration.ConsoleDriverFactory() ?? throw new InvalidOperationException("ConsoleDriverFactory must return a non-null IConsoleDriver instance."); _consoleDriver.CancellationCallback = CancellationHandler; - _formRenderer = new FormRenderer(_consoleDriver); + _formRenderer = new FormRenderer(_consoleDriver, configuration); } private readonly IConsoleDriver _consoleDriver; private readonly FormRenderer _formRenderer; + private readonly PromptConfiguration _configuration; + + protected PromptConfiguration Configuration => _configuration; protected TextInputBuffer InputBuffer { get; } = new(); @@ -31,7 +35,7 @@ protected FormBase() protected int Height => _consoleDriver.WindowHeight; - public void Dispose() => _formRenderer.Dispose(); + public void Dispose() => _consoleDriver.Dispose(); public T Start() { @@ -124,7 +128,7 @@ private void CancellationHandler() { _formRenderer.Cancel(); - if (Prompt.ThrowExceptionOnCancel) + if (_configuration.ThrowExceptionOnCancel) { throw new PromptCanceledException(Resource.Message_PromptCanceled, GetType().Name); } diff --git a/Sharprompt/Forms/FormRenderer.cs b/Sharprompt/Forms/FormRenderer.cs index afe2d8e..ed19175 100644 --- a/Sharprompt/Forms/FormRenderer.cs +++ b/Sharprompt/Forms/FormRenderer.cs @@ -5,14 +5,12 @@ namespace Sharprompt.Forms; -internal class FormRenderer(IConsoleDriver consoleDriver) : IDisposable +internal class FormRenderer(IConsoleDriver consoleDriver, PromptConfiguration configuration) { - private readonly OffscreenBuffer _offscreenBuffer = new(consoleDriver); + private readonly OffscreenBuffer _offscreenBuffer = new(consoleDriver, configuration); public string? ErrorMessage { get; set; } - public void Dispose() => _offscreenBuffer.Dispose(); - public void Cancel() => _offscreenBuffer.Cancel(); public void Render(Action template) diff --git a/Sharprompt/Forms/InputForm.cs b/Sharprompt/Forms/InputForm.cs index 7798362..3b68395 100644 --- a/Sharprompt/Forms/InputForm.cs +++ b/Sharprompt/Forms/InputForm.cs @@ -8,7 +8,7 @@ namespace Sharprompt.Forms; internal class InputForm : TextFormBase { - public InputForm(InputOptions options) + public InputForm(InputOptions options, PromptConfiguration configuration) : base(configuration) { options.EnsureOptions(); diff --git a/Sharprompt/Forms/ListForm.cs b/Sharprompt/Forms/ListForm.cs index aa0b507..167518b 100644 --- a/Sharprompt/Forms/ListForm.cs +++ b/Sharprompt/Forms/ListForm.cs @@ -9,7 +9,7 @@ namespace Sharprompt.Forms; internal class ListForm : TextFormBase> where T : notnull { - public ListForm(ListOptions options) + public ListForm(ListOptions options, PromptConfiguration configuration) : base(configuration) { options.EnsureOptions(); diff --git a/Sharprompt/Forms/MultiSelectForm.cs b/Sharprompt/Forms/MultiSelectForm.cs index 39bfa4a..0e6d9f8 100644 --- a/Sharprompt/Forms/MultiSelectForm.cs +++ b/Sharprompt/Forms/MultiSelectForm.cs @@ -8,59 +8,48 @@ namespace Sharprompt.Forms; -internal class MultiSelectForm : FormBase> where T : notnull +internal class MultiSelectForm : SelectFormBase> where T : notnull { - public MultiSelectForm(MultiSelectOptions options) + public MultiSelectForm(MultiSelectOptions options, PromptConfiguration configuration) : base(configuration) { options.EnsureOptions(); _options = options; - _paginator = new Paginator(options.Items, Math.Min(options.PageSize, Height - 2), Optional.Empty, options.TextSelector) - { - LoopingSelection = options.LoopingSelection - }; + + InitializePaginator(options.Items, options.PageSize, Optional.Empty, options.TextSelector, options.LoopingSelection); foreach (var defaultValue in options.DefaultValues) { _selectedItems.Add(defaultValue); } - KeyHandlerMaps = new() - { - [ConsoleKey.Spacebar] = HandleSpacebar, - [ConsoleKey.UpArrow] = HandleUpArrow, - [ConsoleKey.DownArrow] = HandleDownArrow, - [ConsoleKey.LeftArrow] = HandleLeftArrow, - [ConsoleKey.RightArrow] = HandleRightArrow, - [ConsoleKey.Backspace] = HandleBackspace, - [ConsoleKey.A] = HandleAWithControl, - [ConsoleKey.I] = HandleIWithControl, - }; + KeyHandlerMaps[ConsoleKey.Spacebar] = HandleSpacebar; + KeyHandlerMaps[ConsoleKey.A] = HandleAWithControl; + KeyHandlerMaps[ConsoleKey.I] = HandleIWithControl; } private readonly MultiSelectOptions _options; - private readonly Paginator _paginator; private readonly HashSet _selectedItems = []; protected override void InputTemplate(OffscreenBuffer offscreenBuffer) { - _paginator.UpdatePageSize(Math.Min(_options.PageSize, Height - 2)); + Paginator.UpdatePageSize(Math.Min(_options.PageSize, Height - 2)); offscreenBuffer.WritePrompt(_options.Message); - offscreenBuffer.Write(_paginator.FilterKeyword); + offscreenBuffer.Write(Paginator.FilterKeyword); offscreenBuffer.PushCursor(); - if (string.IsNullOrEmpty(_paginator.FilterKeyword)) + if (string.IsNullOrEmpty(Paginator.FilterKeyword)) { offscreenBuffer.WriteHint(Resource.MultiSelectForm_Message_Hint); } - var hasSelected = _paginator.TryGetSelectedItem(out var selectedItem); + var hasSelected = Paginator.TryGetSelectedItem(out var selectedItem); var comparer = EqualityComparer.Default; - foreach (var item in _paginator.CurrentItems) + foreach (var item in Paginator.CurrentItems) { var value = _options.TextSelector(item); var isChecked = _selectedItems.Contains(item); @@ -69,26 +58,22 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer) if (hasSelected && comparer.Equals(item, selectedItem)) { - offscreenBuffer.WriteSelect($"{Prompt.Symbols.Selector} {(isChecked ? Prompt.Symbols.Selected : Prompt.Symbols.NotSelect)} {value}"); + offscreenBuffer.WriteSelect($"{Configuration.Symbols.Selector} {(isChecked ? Configuration.Symbols.Selected : Configuration.Symbols.NotSelect)} {value}"); } else { if (isChecked) { - offscreenBuffer.WriteSelect($" {Prompt.Symbols.Selected} {value}"); + offscreenBuffer.WriteSelect($" {Configuration.Symbols.Selected} {value}"); } else { - offscreenBuffer.Write($" {Prompt.Symbols.NotSelect} {value}"); + offscreenBuffer.Write($" {Configuration.Symbols.NotSelect} {value}"); } } } - if (_paginator.PageCount > 1) - { - offscreenBuffer.WriteLine(); - offscreenBuffer.WriteHint(_options.Pagination(_paginator.TotalCount, _paginator.CurrentPage + 1, _paginator.PageCount)); - } + RenderPagination(offscreenBuffer, _options.Pagination); } protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, IEnumerable result) @@ -115,18 +100,9 @@ protected override bool HandleEnter([NotNullWhen(true)] out IEnumerable? resu return false; } - protected override bool HandleTextInput(ConsoleKeyInfo keyInfo) - { - base.HandleTextInput(keyInfo); - - _paginator.UpdateFilter(InputBuffer.ToString()); - - return true; - } - private bool HandleSpacebar(ConsoleKeyInfo keyInfo) { - if (!_paginator.TryGetSelectedItem(out var currentItem)) + if (!Paginator.TryGetSelectedItem(out var currentItem)) { return false; } @@ -146,47 +122,6 @@ private bool HandleSpacebar(ConsoleKeyInfo keyInfo) return true; } - private bool HandleUpArrow(ConsoleKeyInfo keyInfo) - { - _paginator.PreviousItem(); - - return true; - } - - private bool HandleDownArrow(ConsoleKeyInfo keyInfo) - { - _paginator.NextItem(); - - return true; - } - - private bool HandleLeftArrow(ConsoleKeyInfo keyInfo) - { - _paginator.PreviousPage(); - - return true; - } - - private bool HandleRightArrow(ConsoleKeyInfo keyInfo) - { - _paginator.NextPage(); - - return true; - } - - private bool HandleBackspace(ConsoleKeyInfo keyInfo) - { - if (InputBuffer.IsStart) - { - return false; - } - - InputBuffer.Backspace(); - _paginator.UpdateFilter(InputBuffer.ToString()); - - return true; - } - private bool HandleAWithControl(ConsoleKeyInfo keyInfo) { if (keyInfo.Modifiers != ConsoleModifiers.Control) @@ -194,13 +129,13 @@ private bool HandleAWithControl(ConsoleKeyInfo keyInfo) return false; } - if (_selectedItems.Count == _paginator.TotalCount) + if (_selectedItems.Count == Paginator.TotalCount) { _selectedItems.Clear(); } else { - foreach (var item in _paginator) + foreach (var item in Paginator) { _selectedItems.Add(item); } @@ -216,7 +151,7 @@ private bool HandleIWithControl(ConsoleKeyInfo keyInfo) return false; } - var invertedItems = _paginator.Except(_selectedItems).ToArray(); + var invertedItems = Paginator.Except(_selectedItems).ToArray(); _selectedItems.Clear(); diff --git a/Sharprompt/Forms/PasswordForm.cs b/Sharprompt/Forms/PasswordForm.cs index d063d48..eaaea86 100644 --- a/Sharprompt/Forms/PasswordForm.cs +++ b/Sharprompt/Forms/PasswordForm.cs @@ -8,7 +8,7 @@ namespace Sharprompt.Forms; internal class PasswordForm : FormBase { - public PasswordForm(PasswordOptions options) + public PasswordForm(PasswordOptions options, PromptConfiguration configuration) : base(configuration) { options.EnsureOptions(); diff --git a/Sharprompt/Forms/SelectForm.cs b/Sharprompt/Forms/SelectForm.cs index 78e2bd9..0b862b7 100644 --- a/Sharprompt/Forms/SelectForm.cs +++ b/Sharprompt/Forms/SelectForm.cs @@ -7,44 +7,32 @@ namespace Sharprompt.Forms; -internal class SelectForm : FormBase where T : notnull +internal class SelectForm : SelectFormBase where T : notnull { - public SelectForm(SelectOptions options) + public SelectForm(SelectOptions options, PromptConfiguration configuration) : base(configuration) { options.EnsureOptions(); _options = options; - _paginator = new Paginator(options.Items, Math.Min(options.PageSize, Height - 2), Optional.Create(options.DefaultValue), options.TextSelector) - { - LoopingSelection = options.LoopingSelection - }; - KeyHandlerMaps = new() - { - [ConsoleKey.UpArrow] = HandleUpArrow, - [ConsoleKey.DownArrow] = HandleDownArrow, - [ConsoleKey.LeftArrow] = HandleLeftArrow, - [ConsoleKey.RightArrow] = HandleRightArrow, - [ConsoleKey.Backspace] = HandleBackspace - }; + InitializePaginator(options.Items, options.PageSize, Optional.Create(options.DefaultValue), options.TextSelector, options.LoopingSelection); } private readonly SelectOptions _options; - private readonly Paginator _paginator; protected override void InputTemplate(OffscreenBuffer offscreenBuffer) { - _paginator.UpdatePageSize(Math.Min(_options.PageSize, Height - 2)); + Paginator.UpdatePageSize(Math.Min(_options.PageSize, Height - 2)); offscreenBuffer.WritePrompt(_options.Message); - offscreenBuffer.Write(_paginator.FilterKeyword); + offscreenBuffer.Write(Paginator.FilterKeyword); offscreenBuffer.PushCursor(); - var hasSelected = _paginator.TryGetSelectedItem(out var selectedItem); + var hasSelected = Paginator.TryGetSelectedItem(out var selectedItem); var comparer = EqualityComparer.Default; - foreach (var item in _paginator.CurrentItems) + foreach (var item in Paginator.CurrentItems) { var value = _options.TextSelector(item); @@ -52,7 +40,7 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer) if (hasSelected && comparer.Equals(item, selectedItem)) { - offscreenBuffer.WriteSelect($"{Prompt.Symbols.Selector} {value}"); + offscreenBuffer.WriteSelect($"{Configuration.Symbols.Selector} {value}"); } else { @@ -60,11 +48,7 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer) } } - if (_paginator.PageCount > 1) - { - offscreenBuffer.WriteLine(); - offscreenBuffer.WriteHint(_options.Pagination(_paginator.TotalCount, _paginator.CurrentPage + 1, _paginator.PageCount)); - } + RenderPagination(offscreenBuffer, _options.Pagination); } protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, T result) @@ -75,7 +59,7 @@ protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, T result protected override bool HandleEnter([NotNullWhen(true)] out T? result) { - if (_paginator.TryGetSelectedItem(out result)) + if (Paginator.TryGetSelectedItem(out result)) { return true; } @@ -84,54 +68,4 @@ protected override bool HandleEnter([NotNullWhen(true)] out T? result) return false; } - - protected override bool HandleTextInput(ConsoleKeyInfo keyInfo) - { - base.HandleTextInput(keyInfo); - - _paginator.UpdateFilter(InputBuffer.ToString()); - - return true; - } - - private bool HandleUpArrow(ConsoleKeyInfo keyInfo) - { - _paginator.PreviousItem(); - - return true; - } - - private bool HandleDownArrow(ConsoleKeyInfo keyInfo) - { - _paginator.NextItem(); - - return true; - } - - private bool HandleLeftArrow(ConsoleKeyInfo keyInfo) - { - _paginator.PreviousPage(); - - return true; - } - - private bool HandleRightArrow(ConsoleKeyInfo keyInfo) - { - _paginator.NextPage(); - - return true; - } - - private bool HandleBackspace(ConsoleKeyInfo keyInfo) - { - if (InputBuffer.IsStart) - { - return false; - } - - InputBuffer.Backspace(); - _paginator.UpdateFilter(InputBuffer.ToString()); - - return true; - } } diff --git a/Sharprompt/Forms/SelectFormBase.cs b/Sharprompt/Forms/SelectFormBase.cs new file mode 100644 index 0000000..08d632b --- /dev/null +++ b/Sharprompt/Forms/SelectFormBase.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; + +using Sharprompt.Internal; + +namespace Sharprompt.Forms; + +internal abstract class SelectFormBase : FormBase where TItem : notnull +{ + protected SelectFormBase(PromptConfiguration configuration) : base(configuration) + { + } + + protected Paginator Paginator { get; private set; } = null!; + + protected void InitializePaginator(IEnumerable items, int pageSize, Optional defaultValue, Func textSelector, bool loopingSelection) + { + Paginator = new Paginator(items, Math.Min(pageSize, Height - 2), defaultValue, textSelector) + { + LoopingSelection = loopingSelection + }; + + KeyHandlerMaps[ConsoleKey.UpArrow] = HandleUpArrow; + KeyHandlerMaps[ConsoleKey.DownArrow] = HandleDownArrow; + KeyHandlerMaps[ConsoleKey.LeftArrow] = HandleLeftArrow; + KeyHandlerMaps[ConsoleKey.RightArrow] = HandleRightArrow; + KeyHandlerMaps[ConsoleKey.Backspace] = HandleBackspace; + } + + protected override bool HandleTextInput(ConsoleKeyInfo keyInfo) + { + InputBuffer.Insert(keyInfo.KeyChar); + + Paginator.UpdateFilter(InputBuffer.ToString()); + + return true; + } + + protected void RenderPagination(OffscreenBuffer offscreenBuffer, Func pagination) + { + if (Paginator.PageCount > 1) + { + offscreenBuffer.WriteLine(); + offscreenBuffer.WriteHint(pagination(Paginator.TotalCount, Paginator.CurrentPage + 1, Paginator.PageCount)); + } + } + + private bool HandleUpArrow(ConsoleKeyInfo keyInfo) + { + Paginator.PreviousItem(); + + return true; + } + + private bool HandleDownArrow(ConsoleKeyInfo keyInfo) + { + Paginator.NextItem(); + + return true; + } + + private bool HandleLeftArrow(ConsoleKeyInfo keyInfo) + { + Paginator.PreviousPage(); + + return true; + } + + private bool HandleRightArrow(ConsoleKeyInfo keyInfo) + { + Paginator.NextPage(); + + return true; + } + + private bool HandleBackspace(ConsoleKeyInfo keyInfo) + { + if (InputBuffer.IsStart) + { + return false; + } + + InputBuffer.Backspace(); + + Paginator.UpdateFilter(InputBuffer.ToString()); + + return true; + } +} diff --git a/Sharprompt/Forms/TextFormBase.cs b/Sharprompt/Forms/TextFormBase.cs index bd12429..99dbd13 100644 --- a/Sharprompt/Forms/TextFormBase.cs +++ b/Sharprompt/Forms/TextFormBase.cs @@ -4,7 +4,7 @@ namespace Sharprompt.Forms; internal abstract class TextFormBase : FormBase { - protected TextFormBase() + protected TextFormBase(PromptConfiguration configuration) : base(configuration) { KeyHandlerMaps = new() { diff --git a/Sharprompt/InputOptions.cs b/Sharprompt/InputOptions.cs index ba70cbb..6e967a3 100644 --- a/Sharprompt/InputOptions.cs +++ b/Sharprompt/InputOptions.cs @@ -4,18 +4,11 @@ namespace Sharprompt; -public class InputOptions +public class InputOptions : PromptOptions { - public string Message { get; set; } = null!; - public string? Placeholder { get; set; } public object? DefaultValue { get; set; } public IList> Validators { get; } = []; - - internal void EnsureOptions() - { - ArgumentNullException.ThrowIfNull(Message); - } } diff --git a/Sharprompt/Internal/OffscreenBuffer.cs b/Sharprompt/Internal/OffscreenBuffer.cs index d6a080f..17ee9ea 100644 --- a/Sharprompt/Internal/OffscreenBuffer.cs +++ b/Sharprompt/Internal/OffscreenBuffer.cs @@ -5,16 +5,18 @@ namespace Sharprompt.Internal; -internal class OffscreenBuffer : IDisposable +internal class OffscreenBuffer { - public OffscreenBuffer(IConsoleDriver consoleDriver) + public OffscreenBuffer(IConsoleDriver consoleDriver, PromptConfiguration configuration) { _consoleDriver = consoleDriver; + _configuration = configuration; _cursorBottom = _consoleDriver.CursorTop; } private readonly IConsoleDriver _consoleDriver; + private readonly PromptConfiguration _configuration; private readonly List> _outputBuffer = [[]]; private int _cursorBottom; @@ -23,6 +25,8 @@ public OffscreenBuffer(IConsoleDriver consoleDriver) private int _cachedWrittenLineCount; private int _cachedBufferWidth; + internal PromptConfiguration Configuration => _configuration; + private int WrittenLineCount { get @@ -56,8 +60,6 @@ private int WrittenLineCount } } - public void Dispose() => _consoleDriver.Dispose(); - public void Write(string text) => Write(text, Console.ForegroundColor); public void Write(string text, ConsoleColor color) diff --git a/Sharprompt/Internal/OffscreenBufferExtensions.cs b/Sharprompt/Internal/OffscreenBufferExtensions.cs index 297d9c2..a4cee8b 100644 --- a/Sharprompt/Internal/OffscreenBufferExtensions.cs +++ b/Sharprompt/Internal/OffscreenBufferExtensions.cs @@ -4,23 +4,23 @@ internal static class OffscreenBufferExtensions { public static void WritePrompt(this OffscreenBuffer offscreenBuffer, string message) { - offscreenBuffer.Write(Prompt.Symbols.Prompt, Prompt.ColorSchema.PromptSymbol); + offscreenBuffer.Write(offscreenBuffer.Configuration.Symbols.Prompt, offscreenBuffer.Configuration.ColorSchema.PromptSymbol); offscreenBuffer.Write($" {message}: "); } public static void WriteDone(this OffscreenBuffer offscreenBuffer, string message) { - offscreenBuffer.Write(Prompt.Symbols.Done, Prompt.ColorSchema.DoneSymbol); + offscreenBuffer.Write(offscreenBuffer.Configuration.Symbols.Done, offscreenBuffer.Configuration.ColorSchema.DoneSymbol); offscreenBuffer.Write($" {message}: "); } - public static void WriteError(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write($"{Prompt.Symbols.Error} {message}", Prompt.ColorSchema.Error); + public static void WriteError(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write($"{offscreenBuffer.Configuration.Symbols.Error} {message}", offscreenBuffer.Configuration.ColorSchema.Error); - public static void WriteAnswer(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write(message, Prompt.ColorSchema.Answer); + public static void WriteAnswer(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write(message, offscreenBuffer.Configuration.ColorSchema.Answer); - public static void WriteSelect(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write(message, Prompt.ColorSchema.Select); + public static void WriteSelect(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write(message, offscreenBuffer.Configuration.ColorSchema.Select); - public static void WriteHint(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write(message, Prompt.ColorSchema.Hint); + public static void WriteHint(this OffscreenBuffer offscreenBuffer, string message) => offscreenBuffer.Write(message, offscreenBuffer.Configuration.ColorSchema.Hint); public static void WriteInput(this OffscreenBuffer offscreenBuffer, TextInputBuffer textInputBuffer) { diff --git a/Sharprompt/ListOptions.cs b/Sharprompt/ListOptions.cs index b4e5110..bebf64a 100644 --- a/Sharprompt/ListOptions.cs +++ b/Sharprompt/ListOptions.cs @@ -6,10 +6,8 @@ namespace Sharprompt; -public class ListOptions where T : notnull +public class ListOptions : PromptOptions where T : notnull { - public string Message { get; set; } = null!; - public IEnumerable DefaultValues { get; set; } = []; public int Minimum { get; set; } = 1; @@ -18,9 +16,9 @@ public class ListOptions where T : notnull public IList> Validators { get; } = []; - internal void EnsureOptions() + internal override void EnsureOptions() { - ArgumentNullException.ThrowIfNull(Message); + base.EnsureOptions(); if (Minimum < 0) { diff --git a/Sharprompt/MultiSelectOptions.cs b/Sharprompt/MultiSelectOptions.cs index 92bd64a..5aa3afb 100644 --- a/Sharprompt/MultiSelectOptions.cs +++ b/Sharprompt/MultiSelectOptions.cs @@ -5,7 +5,7 @@ namespace Sharprompt; -public class MultiSelectOptions where T : notnull +public class MultiSelectOptions : PromptOptions where T : notnull { public MultiSelectOptions() { @@ -16,8 +16,6 @@ public MultiSelectOptions() } } - public string Message { get; set; } = null!; - public IEnumerable Items { get; set; } = null!; public IEnumerable DefaultValues { get; set; } = []; @@ -34,9 +32,10 @@ public MultiSelectOptions() public bool LoopingSelection { get; set; } = true; - internal void EnsureOptions() + internal override void EnsureOptions() { - ArgumentNullException.ThrowIfNull(Message); + base.EnsureOptions(); + ArgumentNullException.ThrowIfNull(Items); ArgumentNullException.ThrowIfNull(DefaultValues); ArgumentNullException.ThrowIfNull(TextSelector); diff --git a/Sharprompt/PasswordOptions.cs b/Sharprompt/PasswordOptions.cs index c97d4ef..54365ce 100644 --- a/Sharprompt/PasswordOptions.cs +++ b/Sharprompt/PasswordOptions.cs @@ -4,19 +4,18 @@ namespace Sharprompt; -public class PasswordOptions +public class PasswordOptions : PromptOptions { - public string Message { get; set; } = null!; - public string? Placeholder { get; set; } public string PasswordChar { get; set; } = "*"; public IList> Validators { get; } = []; - internal void EnsureOptions() + internal override void EnsureOptions() { - ArgumentNullException.ThrowIfNull(Message); + base.EnsureOptions(); + ArgumentNullException.ThrowIfNull(PasswordChar); } } diff --git a/Sharprompt/Prompt.Basic.cs b/Sharprompt/Prompt.Basic.cs index 2a12620..05d2d5f 100644 --- a/Sharprompt/Prompt.Basic.cs +++ b/Sharprompt/Prompt.Basic.cs @@ -11,7 +11,7 @@ public static partial class Prompt { public static T Input(InputOptions options) { - using var form = new InputForm(options); + using var form = new InputForm(options, s_configuration); return form.Start(); } @@ -39,7 +39,7 @@ public static T Input(string message, object? defaultValue = default, string? public static string Password(PasswordOptions options) { - using var form = new PasswordForm(options); + using var form = new PasswordForm(options, s_configuration); return form.Start(); } @@ -67,7 +67,7 @@ public static string Password(string message, string passwordChar = "*", string? public static bool Confirm(ConfirmOptions options) { - using var form = new ConfirmForm(options); + using var form = new ConfirmForm(options, s_configuration); return form.Start(); } @@ -92,7 +92,7 @@ public static bool Confirm(string message, bool? defaultValue = default) public static T Select(SelectOptions options) where T : notnull { - using var form = new SelectForm(options); + using var form = new SelectForm(options, s_configuration); return form.Start(); } @@ -129,7 +129,7 @@ public static T Select(string message, IEnumerable? items = default, int p public static IEnumerable MultiSelect(MultiSelectOptions options) where T : notnull { - using var form = new MultiSelectForm(options); + using var form = new MultiSelectForm(options, s_configuration); return form.Start(); } @@ -172,7 +172,7 @@ public static IEnumerable MultiSelect(string message, IEnumerable? item public static IEnumerable List(ListOptions options) where T : notnull { - using var form = new ListForm(options); + using var form = new ListForm(options, s_configuration); return form.Start(); } diff --git a/Sharprompt/Prompt.Configuration.cs b/Sharprompt/Prompt.Configuration.cs index d873494..34314de 100644 --- a/Sharprompt/Prompt.Configuration.cs +++ b/Sharprompt/Prompt.Configuration.cs @@ -8,18 +8,20 @@ namespace Sharprompt; public static partial class Prompt { - public static bool ThrowExceptionOnCancel { get; set; } = false; + internal static readonly PromptConfiguration s_configuration = new(); - private static Func s_consoleDriverFactory = () => new DefaultConsoleDriver(); + public static PromptConfiguration Configuration => s_configuration; + + public static bool ThrowExceptionOnCancel + { + get => s_configuration.ThrowExceptionOnCancel; + set => s_configuration.ThrowExceptionOnCancel = value; + } public static Func ConsoleDriverFactory { - get => s_consoleDriverFactory; - set - { - ArgumentNullException.ThrowIfNull(value); - s_consoleDriverFactory = value; - } + get => s_configuration.ConsoleDriverFactory; + set => s_configuration.ConsoleDriverFactory = value; } public static CultureInfo Culture @@ -28,24 +30,7 @@ public static CultureInfo Culture set => Resource.Culture = value; } - public static class ColorSchema - { - public static ConsoleColor DoneSymbol { get; set; } = ConsoleColor.Green; - public static ConsoleColor PromptSymbol { get; set; } = ConsoleColor.Green; - public static ConsoleColor Answer { get; set; } = ConsoleColor.Cyan; - public static ConsoleColor Select { get; set; } = ConsoleColor.Green; - public static ConsoleColor Error { get; set; } = ConsoleColor.Red; - public static ConsoleColor Hint { get; set; } = ConsoleColor.DarkGray; - public static ConsoleColor DisabledOption { get; set; } = ConsoleColor.DarkCyan; - } + public static PromptColorSchema ColorSchema => s_configuration.ColorSchema; - public static class Symbols - { - public static Symbol Prompt { get; set; } = new("?", "?"); - public static Symbol Done { get; set; } = new("✔", "V"); - public static Symbol Error { get; set; } = new("»", ">>"); - public static Symbol Selector { get; set; } = new("›", ">"); - public static Symbol Selected { get; set; } = new("◉", "(*)"); - public static Symbol NotSelect { get; set; } = new("◯", "( )"); - } + public static PromptSymbols Symbols => s_configuration.Symbols; } diff --git a/Sharprompt/PromptConfiguration.cs b/Sharprompt/PromptConfiguration.cs new file mode 100644 index 0000000..aef59ca --- /dev/null +++ b/Sharprompt/PromptConfiguration.cs @@ -0,0 +1,47 @@ +using System; + +using Sharprompt.Drivers; + +namespace Sharprompt; + +public class PromptConfiguration +{ + public bool ThrowExceptionOnCancel { get; set; } + + private Func _consoleDriverFactory = () => new DefaultConsoleDriver(); + + public Func ConsoleDriverFactory + { + get => _consoleDriverFactory; + set + { + ArgumentNullException.ThrowIfNull(value); + _consoleDriverFactory = value; + } + } + + public PromptColorSchema ColorSchema { get; } = new(); + + public PromptSymbols Symbols { get; } = new(); +} + +public class PromptColorSchema +{ + public ConsoleColor DoneSymbol { get; set; } = ConsoleColor.Green; + public ConsoleColor PromptSymbol { get; set; } = ConsoleColor.Green; + public ConsoleColor Answer { get; set; } = ConsoleColor.Cyan; + public ConsoleColor Select { get; set; } = ConsoleColor.Green; + public ConsoleColor Error { get; set; } = ConsoleColor.Red; + public ConsoleColor Hint { get; set; } = ConsoleColor.DarkGray; + public ConsoleColor DisabledOption { get; set; } = ConsoleColor.DarkCyan; +} + +public class PromptSymbols +{ + public Symbol Prompt { get; set; } = new("?", "?"); + public Symbol Done { get; set; } = new("✔", "V"); + public Symbol Error { get; set; } = new("»", ">>"); + public Symbol Selector { get; set; } = new("›", ">"); + public Symbol Selected { get; set; } = new("◉", "(*)"); + public Symbol NotSelect { get; set; } = new("◯", "( )"); +} diff --git a/Sharprompt/PromptOptions.cs b/Sharprompt/PromptOptions.cs new file mode 100644 index 0000000..fee305e --- /dev/null +++ b/Sharprompt/PromptOptions.cs @@ -0,0 +1,13 @@ +using System; + +namespace Sharprompt; + +public abstract class PromptOptions +{ + public string Message { get; set; } = null!; + + internal virtual void EnsureOptions() + { + ArgumentNullException.ThrowIfNull(Message); + } +} diff --git a/Sharprompt/SelectOptions.cs b/Sharprompt/SelectOptions.cs index 14c8c30..b5452bc 100644 --- a/Sharprompt/SelectOptions.cs +++ b/Sharprompt/SelectOptions.cs @@ -5,7 +5,7 @@ namespace Sharprompt; -public class SelectOptions where T : notnull +public class SelectOptions : PromptOptions where T : notnull { public SelectOptions() { @@ -16,8 +16,6 @@ public SelectOptions() } } - public string Message { get; set; } = null!; - public IEnumerable Items { get; set; } = null!; public object? DefaultValue { get; set; } @@ -30,9 +28,10 @@ public SelectOptions() public bool LoopingSelection { get; set; } = true; - internal void EnsureOptions() + internal override void EnsureOptions() { - ArgumentNullException.ThrowIfNull(Message); + base.EnsureOptions(); + ArgumentNullException.ThrowIfNull(Items); ArgumentNullException.ThrowIfNull(TextSelector); ArgumentNullException.ThrowIfNull(Pagination);