Skip to content

Commit

Permalink
Rearchitecture of each form implementation (#242)
Browse files Browse the repository at this point in the history
* Rearchitecture of each form implementation

* Reduce nest of if statement
  • Loading branch information
shibayan authored Nov 13, 2022
1 parent 9fbe6e9 commit 0b4204d
Show file tree
Hide file tree
Showing 19 changed files with 486 additions and 388 deletions.
55 changes: 6 additions & 49 deletions Sharprompt/Forms/ConfirmForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Sharprompt.Forms;

internal class ConfirmForm : FormBase<bool>
internal class ConfirmForm : TextFormBase<bool>
{
public ConfirmForm(ConfirmOptions options)
{
Expand All @@ -16,51 +16,6 @@ public ConfirmForm(ConfirmOptions options)

private readonly ConfirmOptions _options;

private readonly TextInputBuffer _textInputBuffer = new();

protected override bool TryGetResult(out bool result)
{
do
{
var keyInfo = ConsoleDriver.ReadKey();

switch (keyInfo.Key)
{
case ConsoleKey.Enter:
return HandleEnter(out result);
case ConsoleKey.LeftArrow when !_textInputBuffer.IsStart:
_textInputBuffer.MoveBackward();
break;
case ConsoleKey.RightArrow when !_textInputBuffer.IsEnd:
_textInputBuffer.MoveForward();
break;
case ConsoleKey.Backspace when !_textInputBuffer.IsStart:
_textInputBuffer.Backspace();
break;
case ConsoleKey.Delete when !_textInputBuffer.IsEnd:
_textInputBuffer.Delete();
break;
case ConsoleKey.LeftArrow:
case ConsoleKey.RightArrow:
case ConsoleKey.Backspace:
case ConsoleKey.Delete:
ConsoleDriver.Beep();
break;
default:
if (!char.IsControl(keyInfo.KeyChar))
{
_textInputBuffer.Insert(keyInfo.KeyChar);
}
break;
}

} while (ConsoleDriver.KeyAvailable);

result = default;

return false;
}

protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
{
offscreenBuffer.WritePrompt(_options.Message);
Expand All @@ -81,7 +36,7 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
}

offscreenBuffer.WriteHint($"({answerYes}/{answerNo}) ");
offscreenBuffer.WriteInput(_textInputBuffer);
offscreenBuffer.WriteInput(InputBuffer);
}

protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, bool result)
Expand All @@ -90,9 +45,9 @@ protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, bool res
offscreenBuffer.WriteAnswer(result ? Resource.ConfirmForm_Answer_Yes : Resource.ConfirmForm_Answer_No);
}

private bool HandleEnter(out bool result)
protected override bool HandleEnter(out bool result)
{
var input = _textInputBuffer.ToString();
var input = InputBuffer.ToString();

if (string.IsNullOrEmpty(input))
{
Expand Down Expand Up @@ -123,6 +78,8 @@ private bool HandleEnter(out bool result)
return true;
}

InputBuffer.Clear();

SetError(Resource.Validation_Invalid);
}

Expand Down
45 changes: 44 additions & 1 deletion Sharprompt/Forms/FormBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ protected FormBase()

protected IConsoleDriver ConsoleDriver { get; }

protected TextInputBuffer InputBuffer { get; } = new();

protected Dictionary<ConsoleKey, Func<ConsoleKeyInfo, bool>> KeyHandlerMaps { get; set; } = new();

public void Dispose() => _formRenderer.Dispose();

public T Start()
Expand All @@ -45,12 +49,51 @@ public T Start()
}
}

protected abstract bool TryGetResult([NotNullWhen(true)] out T? result);
protected bool TryGetResult([NotNullWhen(true)] out T? result)
{
do
{
var keyInfo = ConsoleDriver.ReadKey();

if (keyInfo.Key == ConsoleKey.Enter)
{
return HandleEnter(out result);
}

if (KeyHandlerMaps.TryGetValue(keyInfo.Key, out var keyHandler) && keyHandler(keyInfo))
{
continue;
}

if (!char.IsControl(keyInfo.KeyChar))
{
HandleTextInput(keyInfo);
}
else
{
ConsoleDriver.Beep();
}

} while (ConsoleDriver.KeyAvailable);

result = default;

return false;
}

protected abstract void InputTemplate(OffscreenBuffer offscreenBuffer);

protected abstract void FinishTemplate(OffscreenBuffer offscreenBuffer, T result);

protected abstract bool HandleEnter([NotNullWhen(true)] out T? result);

protected virtual bool HandleTextInput(ConsoleKeyInfo keyInfo)
{
InputBuffer.Insert(keyInfo.KeyChar);

return true;
}

protected void SetError(string errorMessage) => _formRenderer.ErrorMessage = errorMessage;

protected void SetError(Exception exception) => SetError(exception.Message);
Expand Down
2 changes: 1 addition & 1 deletion Sharprompt/Forms/FormRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void Render(Action<OffscreenBuffer> template)
}
}

public void Render<TModel>(Action<OffscreenBuffer, TModel> template, TModel result)
public void Render<T>(Action<OffscreenBuffer, T> template, T result)
{
using (_offscreenBuffer.BeginRender())
{
Expand Down
82 changes: 6 additions & 76 deletions Sharprompt/Forms/InputForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Sharprompt.Forms;

internal class InputForm<T> : FormBase<T>
internal class InputForm<T> : TextFormBase<T>
{
public InputForm(InputOptions<T> options)
{
Expand All @@ -20,72 +20,6 @@ public InputForm(InputOptions<T> options)
private readonly InputOptions<T> _options;
private readonly Optional<T> _defaultValue;

private readonly TextInputBuffer _textInputBuffer = new();

protected override bool TryGetResult([NotNullWhen(true)] out T? result)
{
do
{
var keyInfo = ConsoleDriver.ReadKey();
var controlPressed = keyInfo.Modifiers.HasFlag(ConsoleModifiers.Control);

switch (keyInfo.Key)
{
case ConsoleKey.Enter:
return HandleEnter(out result);
case ConsoleKey.LeftArrow when controlPressed && !_textInputBuffer.IsStart:
_textInputBuffer.MoveToPreviousWord();
break;
case ConsoleKey.RightArrow when controlPressed && !_textInputBuffer.IsEnd:
_textInputBuffer.MoveToNextWord();
break;
case ConsoleKey.LeftArrow when !_textInputBuffer.IsStart:
_textInputBuffer.MoveBackward();
break;
case ConsoleKey.RightArrow when !_textInputBuffer.IsEnd:
_textInputBuffer.MoveForward();
break;
case ConsoleKey.Home when !_textInputBuffer.IsStart:
_textInputBuffer.MoveToStart();
break;
case ConsoleKey.End when !_textInputBuffer.IsEnd:
_textInputBuffer.MoveToEnd();
break;
case ConsoleKey.Backspace when controlPressed && !_textInputBuffer.IsStart:
_textInputBuffer.BackspaceWord();
break;
case ConsoleKey.Delete when controlPressed && !_textInputBuffer.IsEnd:
_textInputBuffer.DeleteWord();
break;
case ConsoleKey.Backspace when !_textInputBuffer.IsStart:
_textInputBuffer.Backspace();
break;
case ConsoleKey.Delete when !_textInputBuffer.IsEnd:
_textInputBuffer.Delete();
break;
case ConsoleKey.LeftArrow:
case ConsoleKey.RightArrow:
case ConsoleKey.Home:
case ConsoleKey.End:
case ConsoleKey.Backspace:
case ConsoleKey.Delete:
ConsoleDriver.Beep();
break;
default:
if (!char.IsControl(keyInfo.KeyChar))
{
_textInputBuffer.Insert(keyInfo.KeyChar);
}
break;
}

} while (ConsoleDriver.KeyAvailable);

result = default;

return false;
}

protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
{
offscreenBuffer.WritePrompt(_options.Message);
Expand All @@ -95,13 +29,13 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
offscreenBuffer.WriteHint($"({_defaultValue.Value}) ");
}

if (_textInputBuffer.Length == 0 && !string.IsNullOrEmpty(_options.Placeholder))
if (InputBuffer.Length == 0 && !string.IsNullOrEmpty(_options.Placeholder))
{
offscreenBuffer.PushCursor();
offscreenBuffer.WriteHint(_options.Placeholder);
}

offscreenBuffer.WriteInput(_textInputBuffer);
offscreenBuffer.WriteInput(InputBuffer);
}

protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, T result)
Expand All @@ -114,9 +48,9 @@ protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, T result
}
}

private bool HandleEnter([NotNullWhen(true)] out T? result)
protected override bool HandleEnter([NotNullWhen(true)] out T? result)
{
var input = _textInputBuffer.ToString();
var input = InputBuffer.ToString();

try
{
Expand All @@ -138,11 +72,7 @@ private bool HandleEnter([NotNullWhen(true)] out T? result)
result = TypeHelper<T>.ConvertTo(input);
}

if (TryValidate(result, _options.Validators))
{
return true;
}

return TryValidate(result, _options.Validators);
}
catch (Exception ex)
{
Expand Down
72 changes: 17 additions & 55 deletions Sharprompt/Forms/ListForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Sharprompt.Forms;

internal class ListForm<T> : FormBase<IEnumerable<T>> where T : notnull
internal class ListForm<T> : TextFormBase<IEnumerable<T>> where T : notnull
{
public ListForm(ListOptions<T> options)
{
Expand All @@ -22,62 +22,12 @@ public ListForm(ListOptions<T> options)
private readonly ListOptions<T> _options;

private readonly List<T> _inputItems = new();
private readonly TextInputBuffer _textInputBuffer = new();

protected override bool TryGetResult([NotNullWhen(true)] out IEnumerable<T>? result)
{
do
{
var keyInfo = ConsoleDriver.ReadKey();

switch (keyInfo.Key)
{
case ConsoleKey.Enter:
return HandleEnter(out result);
case ConsoleKey.LeftArrow when !_textInputBuffer.IsStart:
_textInputBuffer.MoveBackward();
break;
case ConsoleKey.RightArrow when !_textInputBuffer.IsEnd:
_textInputBuffer.MoveForward();
break;
case ConsoleKey.Backspace when !_textInputBuffer.IsStart:
_textInputBuffer.Backspace();
break;
case ConsoleKey.Delete when !_textInputBuffer.IsEnd:
_textInputBuffer.Delete();
break;
case ConsoleKey.Delete when keyInfo.Modifiers == ConsoleModifiers.Control:
if (_inputItems.Any())
{
_inputItems.RemoveAt(_inputItems.Count - 1);
}
break;
case ConsoleKey.LeftArrow:
case ConsoleKey.RightArrow:
case ConsoleKey.Backspace:
case ConsoleKey.Delete:
ConsoleDriver.Beep();
break;
default:
if (!char.IsControl(keyInfo.KeyChar))
{
_textInputBuffer.Insert(keyInfo.KeyChar);
}
break;
}

} while (ConsoleDriver.KeyAvailable);

result = default;

return false;
}

protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
{
offscreenBuffer.WritePrompt(_options.Message);

offscreenBuffer.WriteInput(_textInputBuffer);
offscreenBuffer.WriteInput(InputBuffer);

foreach (var inputItem in _inputItems)
{
Expand All @@ -92,9 +42,9 @@ protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, IEnumera
offscreenBuffer.WriteAnswer(string.Join(", ", result));
}

private bool HandleEnter(out IEnumerable<T>? result)
protected override bool HandleEnter([NotNullWhen(true)] out IEnumerable<T>? result)
{
var input = _textInputBuffer.ToString();
var input = InputBuffer.ToString();

try
{
Expand Down Expand Up @@ -126,7 +76,7 @@ private bool HandleEnter(out IEnumerable<T>? result)
return false;
}

_textInputBuffer.Clear();
InputBuffer.Clear();

_inputItems.Add(inputValue);
}
Expand All @@ -139,4 +89,16 @@ private bool HandleEnter(out IEnumerable<T>? result)

return false;
}

protected override bool HandleDelete(ConsoleKeyInfo keyInfo)
{
if (keyInfo.Modifiers == ConsoleModifiers.Control && _inputItems.Any())
{
_inputItems.RemoveAt(_inputItems.Count - 1);

return true;
}

return base.HandleDelete(keyInfo);
}
}
Loading

0 comments on commit 0b4204d

Please sign in to comment.