-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConsoleDisplayManager.cs
214 lines (183 loc) · 6.56 KB
/
ConsoleDisplayManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
//============================================================
// Student Number : S10203296, S10205301
// Student Name : Benedict Woo, Melvin Kee
// Module Group : T06
//============================================================
using System;
using System.Collections.Generic;
using COVIDMonitoringSystem.ConsoleApp.Display.Elements;
using COVIDMonitoringSystem.ConsoleApp.Utilities;
namespace COVIDMonitoringSystem.ConsoleApp.Display
{
public class ConsoleDisplayManager
{
private AbstractScreen currentAbstractScreen;
private Dictionary<string, AbstractScreen> ScreenMap { get; }
public Stack<AbstractScreen> ScreenStack { get; set; }
public AbstractScreen CurrentAbstractScreen
{
get => currentAbstractScreen;
set
{
currentAbstractScreen = value;
ScreenUpdated = true;
}
}
public Dictionary<ConsoleKey, Action<ConsoleKeyInfo>> KeyActionMap { get; set; }
private bool Running { get; set; }
public bool ScreenUpdated { get; set; }
public InputResolverManager ResolveManager { get; }
public InputValuesManager ValuesManager { get; }
public ConsoleDisplayManager()
{
ScreenMap = new Dictionary<string, AbstractScreen>();
KeyActionMap = new Dictionary<ConsoleKey, Action<ConsoleKeyInfo>>();
ResolveManager = new InputResolverManager();
ValuesManager = new InputValuesManager();
SetDefaultKeyMap();
}
private void SetDefaultKeyMap()
{
KeyActionMap.Add(ConsoleKey.Tab, OnTab);
KeyActionMap.Add(ConsoleKey.DownArrow, NextSelection);
KeyActionMap.Add(ConsoleKey.UpArrow, PreviousSelection);
KeyActionMap.Add(ConsoleKey.Enter, DoSelection);
KeyActionMap.Add(ConsoleKey.Escape, EscapeBack);
}
private void OnTab(ConsoleKeyInfo key)
{
if (CurrentAbstractScreen.SelectedElement is Input inputElement)
{
var result = inputElement.NextSuggestion();
if (!result)
{
return;
}
}
CurrentAbstractScreen.SelectNext();
}
private void NextSelection(ConsoleKeyInfo key)
{
CurrentAbstractScreen.SelectNext();
}
private void PreviousSelection(ConsoleKeyInfo key)
{
CurrentAbstractScreen.SelectPrevious();
}
private void DoSelection(ConsoleKeyInfo key)
{
if (CurrentAbstractScreen.SelectedElement is Button buttonElement)
{
buttonElement.Run();
return;
}
if (CurrentAbstractScreen.SelectedElement is Input inputElement)
{
inputElement.ApplySuggestion();
CurrentAbstractScreen.SelectNext();
}
}
private void TypeInput(ConsoleKeyInfo key)
{
if (CurrentAbstractScreen.SelectedElement is Input inputElement)
{
if (key.Key == ConsoleKey.Backspace)
{
if (inputElement.Text.Length == 0)
{
return;
}
inputElement.Text = inputElement.Text.Substring(0, inputElement.Text.Length - 1);
}
else if (key.KeyChar >= 32 && key.KeyChar <= 126)
{
inputElement.Text += key.KeyChar;
}
}
}
private void EscapeBack(ConsoleKeyInfo key)
{
if (CurrentAbstractScreen.HasSelection())
{
CurrentAbstractScreen.ClearSelection();
return;
}
PopScreen();
}
public void RegisterScreen(AbstractScreen abstractScreen)
{
if (abstractScreen.DisplayManager != this)
{
throw new InvalidOperationException("Screen does not belong to this manager.");
}
ScreenMap.Add(abstractScreen.Name, abstractScreen);
}
public void Run(string startingScreenName)
{
if (Running)
{
throw new InvalidOperationException("Nested console running is not supported.");
}
CHelper.DidChangeWindowSize();
ScreenStack = new Stack<AbstractScreen>(ScreenMap.Count);
PushScreen(startingScreenName);
Running = true;
while (Running)
{
if (ScreenUpdated)
{
ScreenUpdated = false;
CurrentAbstractScreen.PreLoad();
CurrentAbstractScreen.Load();
CurrentAbstractScreen.OnView();
}
if (CHelper.DidChangeWindowSize())
{
CurrentAbstractScreen.Render();
}
CurrentAbstractScreen.Update();
var keyPressed = Console.ReadKey(true);
RunKeyAction(keyPressed);
}
}
private void RunKeyAction(ConsoleKeyInfo keyInfo)
{
var keyAction = KeyActionMap.GetValueOrDefault(keyInfo.Key, TypeInput);
keyAction?.Invoke(keyInfo);
}
public void PushScreen(string screenName, object data = null)
{
if (ScreenStack.Count > 0)
{
var closingScreen = ScreenStack.Peek();
closingScreen.OnClose();
closingScreen.Unload();
closingScreen.Closed();
}
var targetScreen = ScreenMap[screenName];
ScreenStack.Push(targetScreen);
CurrentAbstractScreen = targetScreen;
CurrentAbstractScreen.PrePassData(data);
}
public void PopScreen(bool doQuit = false)
{
if (ScreenStack.Count == 1 && !doQuit)
{
return;
}
var closingScreen = ScreenStack.Pop();
closingScreen.OnClose();
closingScreen.Unload();
if (ScreenStack.Count == 0)
{
Running = false;
return;
}
CurrentAbstractScreen = ScreenStack.Peek();
}
public void Stop()
{
Running = false;
}
}
}