Skip to content

Commit 0b4204d

Browse files
authored
Rearchitecture of each form implementation (#242)
* Rearchitecture of each form implementation * Reduce nest of if statement
1 parent 9fbe6e9 commit 0b4204d

19 files changed

+486
-388
lines changed

Sharprompt/Forms/ConfirmForm.cs

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Sharprompt.Forms;
77

8-
internal class ConfirmForm : FormBase<bool>
8+
internal class ConfirmForm : TextFormBase<bool>
99
{
1010
public ConfirmForm(ConfirmOptions options)
1111
{
@@ -16,51 +16,6 @@ public ConfirmForm(ConfirmOptions options)
1616

1717
private readonly ConfirmOptions _options;
1818

19-
private readonly TextInputBuffer _textInputBuffer = new();
20-
21-
protected override bool TryGetResult(out bool result)
22-
{
23-
do
24-
{
25-
var keyInfo = ConsoleDriver.ReadKey();
26-
27-
switch (keyInfo.Key)
28-
{
29-
case ConsoleKey.Enter:
30-
return HandleEnter(out result);
31-
case ConsoleKey.LeftArrow when !_textInputBuffer.IsStart:
32-
_textInputBuffer.MoveBackward();
33-
break;
34-
case ConsoleKey.RightArrow when !_textInputBuffer.IsEnd:
35-
_textInputBuffer.MoveForward();
36-
break;
37-
case ConsoleKey.Backspace when !_textInputBuffer.IsStart:
38-
_textInputBuffer.Backspace();
39-
break;
40-
case ConsoleKey.Delete when !_textInputBuffer.IsEnd:
41-
_textInputBuffer.Delete();
42-
break;
43-
case ConsoleKey.LeftArrow:
44-
case ConsoleKey.RightArrow:
45-
case ConsoleKey.Backspace:
46-
case ConsoleKey.Delete:
47-
ConsoleDriver.Beep();
48-
break;
49-
default:
50-
if (!char.IsControl(keyInfo.KeyChar))
51-
{
52-
_textInputBuffer.Insert(keyInfo.KeyChar);
53-
}
54-
break;
55-
}
56-
57-
} while (ConsoleDriver.KeyAvailable);
58-
59-
result = default;
60-
61-
return false;
62-
}
63-
6419
protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
6520
{
6621
offscreenBuffer.WritePrompt(_options.Message);
@@ -81,7 +36,7 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
8136
}
8237

8338
offscreenBuffer.WriteHint($"({answerYes}/{answerNo}) ");
84-
offscreenBuffer.WriteInput(_textInputBuffer);
39+
offscreenBuffer.WriteInput(InputBuffer);
8540
}
8641

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

93-
private bool HandleEnter(out bool result)
48+
protected override bool HandleEnter(out bool result)
9449
{
95-
var input = _textInputBuffer.ToString();
50+
var input = InputBuffer.ToString();
9651

9752
if (string.IsNullOrEmpty(input))
9853
{
@@ -123,6 +78,8 @@ private bool HandleEnter(out bool result)
12378
return true;
12479
}
12580

81+
InputBuffer.Clear();
82+
12683
SetError(Resource.Validation_Invalid);
12784
}
12885

Sharprompt/Forms/FormBase.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ protected FormBase()
2626

2727
protected IConsoleDriver ConsoleDriver { get; }
2828

29+
protected TextInputBuffer InputBuffer { get; } = new();
30+
31+
protected Dictionary<ConsoleKey, Func<ConsoleKeyInfo, bool>> KeyHandlerMaps { get; set; } = new();
32+
2933
public void Dispose() => _formRenderer.Dispose();
3034

3135
public T Start()
@@ -45,12 +49,51 @@ public T Start()
4549
}
4650
}
4751

48-
protected abstract bool TryGetResult([NotNullWhen(true)] out T? result);
52+
protected bool TryGetResult([NotNullWhen(true)] out T? result)
53+
{
54+
do
55+
{
56+
var keyInfo = ConsoleDriver.ReadKey();
57+
58+
if (keyInfo.Key == ConsoleKey.Enter)
59+
{
60+
return HandleEnter(out result);
61+
}
62+
63+
if (KeyHandlerMaps.TryGetValue(keyInfo.Key, out var keyHandler) && keyHandler(keyInfo))
64+
{
65+
continue;
66+
}
67+
68+
if (!char.IsControl(keyInfo.KeyChar))
69+
{
70+
HandleTextInput(keyInfo);
71+
}
72+
else
73+
{
74+
ConsoleDriver.Beep();
75+
}
76+
77+
} while (ConsoleDriver.KeyAvailable);
78+
79+
result = default;
80+
81+
return false;
82+
}
4983

5084
protected abstract void InputTemplate(OffscreenBuffer offscreenBuffer);
5185

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

88+
protected abstract bool HandleEnter([NotNullWhen(true)] out T? result);
89+
90+
protected virtual bool HandleTextInput(ConsoleKeyInfo keyInfo)
91+
{
92+
InputBuffer.Insert(keyInfo.KeyChar);
93+
94+
return true;
95+
}
96+
5497
protected void SetError(string errorMessage) => _formRenderer.ErrorMessage = errorMessage;
5598

5699
protected void SetError(Exception exception) => SetError(exception.Message);

Sharprompt/Forms/FormRenderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void Render(Action<OffscreenBuffer> template)
3636
}
3737
}
3838

39-
public void Render<TModel>(Action<OffscreenBuffer, TModel> template, TModel result)
39+
public void Render<T>(Action<OffscreenBuffer, T> template, T result)
4040
{
4141
using (_offscreenBuffer.BeginRender())
4242
{

Sharprompt/Forms/InputForm.cs

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Sharprompt.Forms;
88

9-
internal class InputForm<T> : FormBase<T>
9+
internal class InputForm<T> : TextFormBase<T>
1010
{
1111
public InputForm(InputOptions<T> options)
1212
{
@@ -20,72 +20,6 @@ public InputForm(InputOptions<T> options)
2020
private readonly InputOptions<T> _options;
2121
private readonly Optional<T> _defaultValue;
2222

23-
private readonly TextInputBuffer _textInputBuffer = new();
24-
25-
protected override bool TryGetResult([NotNullWhen(true)] out T? result)
26-
{
27-
do
28-
{
29-
var keyInfo = ConsoleDriver.ReadKey();
30-
var controlPressed = keyInfo.Modifiers.HasFlag(ConsoleModifiers.Control);
31-
32-
switch (keyInfo.Key)
33-
{
34-
case ConsoleKey.Enter:
35-
return HandleEnter(out result);
36-
case ConsoleKey.LeftArrow when controlPressed && !_textInputBuffer.IsStart:
37-
_textInputBuffer.MoveToPreviousWord();
38-
break;
39-
case ConsoleKey.RightArrow when controlPressed && !_textInputBuffer.IsEnd:
40-
_textInputBuffer.MoveToNextWord();
41-
break;
42-
case ConsoleKey.LeftArrow when !_textInputBuffer.IsStart:
43-
_textInputBuffer.MoveBackward();
44-
break;
45-
case ConsoleKey.RightArrow when !_textInputBuffer.IsEnd:
46-
_textInputBuffer.MoveForward();
47-
break;
48-
case ConsoleKey.Home when !_textInputBuffer.IsStart:
49-
_textInputBuffer.MoveToStart();
50-
break;
51-
case ConsoleKey.End when !_textInputBuffer.IsEnd:
52-
_textInputBuffer.MoveToEnd();
53-
break;
54-
case ConsoleKey.Backspace when controlPressed && !_textInputBuffer.IsStart:
55-
_textInputBuffer.BackspaceWord();
56-
break;
57-
case ConsoleKey.Delete when controlPressed && !_textInputBuffer.IsEnd:
58-
_textInputBuffer.DeleteWord();
59-
break;
60-
case ConsoleKey.Backspace when !_textInputBuffer.IsStart:
61-
_textInputBuffer.Backspace();
62-
break;
63-
case ConsoleKey.Delete when !_textInputBuffer.IsEnd:
64-
_textInputBuffer.Delete();
65-
break;
66-
case ConsoleKey.LeftArrow:
67-
case ConsoleKey.RightArrow:
68-
case ConsoleKey.Home:
69-
case ConsoleKey.End:
70-
case ConsoleKey.Backspace:
71-
case ConsoleKey.Delete:
72-
ConsoleDriver.Beep();
73-
break;
74-
default:
75-
if (!char.IsControl(keyInfo.KeyChar))
76-
{
77-
_textInputBuffer.Insert(keyInfo.KeyChar);
78-
}
79-
break;
80-
}
81-
82-
} while (ConsoleDriver.KeyAvailable);
83-
84-
result = default;
85-
86-
return false;
87-
}
88-
8923
protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
9024
{
9125
offscreenBuffer.WritePrompt(_options.Message);
@@ -95,13 +29,13 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
9529
offscreenBuffer.WriteHint($"({_defaultValue.Value}) ");
9630
}
9731

98-
if (_textInputBuffer.Length == 0 && !string.IsNullOrEmpty(_options.Placeholder))
32+
if (InputBuffer.Length == 0 && !string.IsNullOrEmpty(_options.Placeholder))
9933
{
10034
offscreenBuffer.PushCursor();
10135
offscreenBuffer.WriteHint(_options.Placeholder);
10236
}
10337

104-
offscreenBuffer.WriteInput(_textInputBuffer);
38+
offscreenBuffer.WriteInput(InputBuffer);
10539
}
10640

10741
protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, T result)
@@ -114,9 +48,9 @@ protected override void FinishTemplate(OffscreenBuffer offscreenBuffer, T result
11448
}
11549
}
11650

117-
private bool HandleEnter([NotNullWhen(true)] out T? result)
51+
protected override bool HandleEnter([NotNullWhen(true)] out T? result)
11852
{
119-
var input = _textInputBuffer.ToString();
53+
var input = InputBuffer.ToString();
12054

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

141-
if (TryValidate(result, _options.Validators))
142-
{
143-
return true;
144-
}
145-
75+
return TryValidate(result, _options.Validators);
14676
}
14777
catch (Exception ex)
14878
{

Sharprompt/Forms/ListForm.cs

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Sharprompt.Forms;
1010

11-
internal class ListForm<T> : FormBase<IEnumerable<T>> where T : notnull
11+
internal class ListForm<T> : TextFormBase<IEnumerable<T>> where T : notnull
1212
{
1313
public ListForm(ListOptions<T> options)
1414
{
@@ -22,62 +22,12 @@ public ListForm(ListOptions<T> options)
2222
private readonly ListOptions<T> _options;
2323

2424
private readonly List<T> _inputItems = new();
25-
private readonly TextInputBuffer _textInputBuffer = new();
26-
27-
protected override bool TryGetResult([NotNullWhen(true)] out IEnumerable<T>? result)
28-
{
29-
do
30-
{
31-
var keyInfo = ConsoleDriver.ReadKey();
32-
33-
switch (keyInfo.Key)
34-
{
35-
case ConsoleKey.Enter:
36-
return HandleEnter(out result);
37-
case ConsoleKey.LeftArrow when !_textInputBuffer.IsStart:
38-
_textInputBuffer.MoveBackward();
39-
break;
40-
case ConsoleKey.RightArrow when !_textInputBuffer.IsEnd:
41-
_textInputBuffer.MoveForward();
42-
break;
43-
case ConsoleKey.Backspace when !_textInputBuffer.IsStart:
44-
_textInputBuffer.Backspace();
45-
break;
46-
case ConsoleKey.Delete when !_textInputBuffer.IsEnd:
47-
_textInputBuffer.Delete();
48-
break;
49-
case ConsoleKey.Delete when keyInfo.Modifiers == ConsoleModifiers.Control:
50-
if (_inputItems.Any())
51-
{
52-
_inputItems.RemoveAt(_inputItems.Count - 1);
53-
}
54-
break;
55-
case ConsoleKey.LeftArrow:
56-
case ConsoleKey.RightArrow:
57-
case ConsoleKey.Backspace:
58-
case ConsoleKey.Delete:
59-
ConsoleDriver.Beep();
60-
break;
61-
default:
62-
if (!char.IsControl(keyInfo.KeyChar))
63-
{
64-
_textInputBuffer.Insert(keyInfo.KeyChar);
65-
}
66-
break;
67-
}
68-
69-
} while (ConsoleDriver.KeyAvailable);
70-
71-
result = default;
72-
73-
return false;
74-
}
7525

7626
protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
7727
{
7828
offscreenBuffer.WritePrompt(_options.Message);
7929

80-
offscreenBuffer.WriteInput(_textInputBuffer);
30+
offscreenBuffer.WriteInput(InputBuffer);
8131

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

95-
private bool HandleEnter(out IEnumerable<T>? result)
45+
protected override bool HandleEnter([NotNullWhen(true)] out IEnumerable<T>? result)
9646
{
97-
var input = _textInputBuffer.ToString();
47+
var input = InputBuffer.ToString();
9848

9949
try
10050
{
@@ -126,7 +76,7 @@ private bool HandleEnter(out IEnumerable<T>? result)
12676
return false;
12777
}
12878

129-
_textInputBuffer.Clear();
79+
InputBuffer.Clear();
13080

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

14090
return false;
14191
}
92+
93+
protected override bool HandleDelete(ConsoleKeyInfo keyInfo)
94+
{
95+
if (keyInfo.Modifiers == ConsoleModifiers.Control && _inputItems.Any())
96+
{
97+
_inputItems.RemoveAt(_inputItems.Count - 1);
98+
99+
return true;
100+
}
101+
102+
return base.HandleDelete(keyInfo);
103+
}
142104
}

0 commit comments

Comments
 (0)