1
2
3
4
5
6 using System;
7
8 namespace System.Screen
9 {
10 public class TextBoxCreateParams
11 {
12 public nothrow TextBoxCreateParams() : controlCreateParams(), focusedForeColor(ConsoleColor.defaultColor), focusedBackColor(ConsoleColor.defaultColor)
13 {
14 }
15 public TextBoxCreateParams& Defaults()
16 {
17 return *this;
18 }
19 public nothrow TextBoxCreateParams& SetLocation(const Point& loc)
20 {
21 controlCreateParams.SetLocation(loc);
22 return *this;
23 }
24 public nothrow TextBoxCreateParams& SetSize(const Size& size_)
25 {
26 controlCreateParams.SetSize(size_);
27 return *this;
28 }
29 public nothrow TextBoxCreateParams& SetForeColor(ConsoleColor foreColor_)
30 {
31 controlCreateParams.SetForeColor(foreColor_);
32 return *this;
33 }
34 public nothrow TextBoxCreateParams& SetBackColor(ConsoleColor backColor_)
35 {
36 controlCreateParams.SetBackColor(backColor_);
37 return *this;
38 }
39 public nothrow TextBoxCreateParams& SetText(const string& text_)
40 {
41 text = ToUtf32(text_);
42 return *this;
43 }
44 public nothrow TextBoxCreateParams& SetFocusedForeColor(ConsoleColor focusedForeColor_)
45 {
46 focusedForeColor = focusedForeColor_;
47 return *this;
48 }
49 public nothrow TextBoxCreateParams& SetFocusedBackColor(ConsoleColor focusedBackColor_)
50 {
51 focusedBackColor = focusedBackColor_;
52 return *this;
53 }
54 public ControlCreateParams controlCreateParams;
55 public ustring text;
56 public ConsoleColor focusedForeColor;
57 public ConsoleColor focusedBackColor;
58 }
59
60 public class TextBox : Control
61 {
62 public nothrow TextBox(TextBoxCreateParams& createParams) :
63 base(createParams.controlCreateParams),
64 text(),
65 pos(0),
66 focusedForeColor(createParams.focusedForeColor),
67 focusedBackColor(createParams.focusedBackColor)
68 {
69 InvalidateGuard invalidateGuard(this, InvalidateKind.dontInvalidate);
70 if (ForeColor() == ConsoleColor.defaultColor)
71 {
72 SetForeColor(ConsoleColor.gray);
73 }
74 if (BackColor() == ConsoleColor.defaultColor)
75 {
76 SetBackColor(ConsoleColor.black);
77 }
78 if (focusedForeColor == ConsoleColor.defaultColor)
79 {
80 focusedForeColor = ConsoleColor.white;
81 }
82 if (focusedBackColor == ConsoleColor.defaultColor)
83 {
84 focusedBackColor = ConsoleColor.darkBlue;
85 }
86 SetCursorPos();
87 }
88 public void SetText(const ustring& text_)
89 {
90 if (text != text_)
91 {
92 text = text_;
93 OnTextChanged();
94 Invalidate();
95 }
96 }
97 public void SetText(const string& text_)
98 {
99 SetText(ToUtf32(text_));
100 }
101 public nothrow const ustring& Text() const
102 {
103 return text;
104 }
105 public override void OnWriteScreen(WriteScreenEventArgs& args)
106 {
107 base->OnWriteScreen(args);
108 Rect updateRect = GetRect();
109 if (!args.GetRect().IsDefault())
110 {
111 updateRect = Rect.Intersection(updateRect, args.GetRect());
112 }
113 if (updateRect.IsEmpty()) return;
114 Clear(updateRect, ForeColor(), BackColor());
115 ConsoleColor foreColor = ForeColor();
116 ConsoleColor backColor = BackColor();
117 if (IsFocused())
118 {
119 foreColor = focusedForeColor;
120 backColor = focusedBackColor;
121 }
122 Clear(updateRect, foreColor, backColor);
123 Point cp = Location();
124 SetCursorPos(cp.x, cp.y);
125 if (text.Length() < updateRect.size.w)
126 {
127 Terminal.Out() << text;
128 }
129 else
130 {
131 int startPos = StartPos();
132 ustring txt = text.Substring(startPos, updateRect.size.w);
133 Terminal.Out() << txt;
134 }
135 SetCursorPos();
136 }
137 public override void OnKeyPressed(KeyEventArgs& args)
138 {
139 base->OnKeyPressed(args);
140 if (IsEnabled() && !args.Handled())
141 {
142 int prevStartPos = StartPos();
143 uchar key = args.Key();
144 if (key < specialKeyStart)
145 {
146 if (key == keyNewline)
147 {
148 args.SetHandled();
149 OnTextEntered();
150 }
151 else if (key == keyBackspace)
152 {
153 args.SetHandled();
154 if (pos > 0)
155 {
156 CursorLeft(prevStartPos);
157 DeleteChar();
158 }
159 }
160 else
161 {
162 if (key >= ' ' && key < specialKeyStart)
163 {
164 args.SetHandled();
165 InsertChar(key);
166 }
167 }
168 }
169 else
170 {
171 switch (key)
172 {
173 case keyDel:
174 {
175 args.SetHandled();
176 DeleteChar();
177 break;
178 }
179 case keyLeft:
180 {
181 args.SetHandled();
182 CursorLeft(prevStartPos);
183 break;
184 }
185 case keyRight:
186 {
187 args.SetHandled();
188 CursorRight(prevStartPos);
189 break;
190 }
191 case keyHome:
192 {
193 args.SetHandled();
194 CursorToStart(prevStartPos);
195 break;
196 }
197 case keyEnd:
198 {
199 args.SetHandled();
200 CursorToEnd(prevStartPos);
201 break;
202 }
203 }
204 }
205 }
206 }
207 public virtual void OnTextChanged()
208 {
209 textChangedEvent.Fire();
210 }
211 public virtual void OnTextEntered()
212 {
213 textEnteredEvent.Fire();
214 }
215 public nothrow Event<ChangedEventHandler>& TextChangedEvent()
216 {
217 return textChangedEvent;
218 }
219 public nothrow Event<SelectEventHandler>& TextEnteredEvent()
220 {
221 return textEnteredEvent;
222 }
223 private int StartPos()
224 {
225 Rect rect = GetRect();
226 return Max(cast<int>(0), cast<int>(pos - rect.size.w));
227 }
228 private void CursorLeft(int prevStartPos)
229 {
230 if (pos > 0)
231 {
232 --pos;
233 SetCursorPos();
234 if (StartPos() != prevStartPos)
235 {
236 Invalidate(GetRect());
237 }
238 }
239 }
240 private void CursorRight(int prevStartPos)
241 {
242 if (pos < text.Length())
243 {
244 ++pos;
245 SetCursorPos();
246 if (StartPos() != prevStartPos)
247 {
248 Invalidate(GetRect());
249 }
250 }
251 }
252 private void CursorToStart(int prevStartPos)
253 {
254 if (pos != 0)
255 {
256 pos = 0;
257 SetCursorPos();
258 if (StartPos() != prevStartPos)
259 {
260 Invalidate(GetRect());
261 }
262 }
263 }
264 private void CursorToEnd(int prevStartPos)
265 {
266 if (pos != text.Length())
267 {
268 pos = cast<int>(text.Length());
269 SetCursorPos();
270 if (StartPos() != prevStartPos)
271 {
272 Invalidate(GetRect());
273 }
274 }
275 }
276 private void DeleteChar()
277 {
278 if (pos < text.Length())
279 {
280 text.Remove(pos, 1);
281 OnTextChanged();
282 Invalidate(GetRect());
283 }
284 }
285 private void InsertChar(uchar ch)
286 {
287 if (pos < text.Length())
288 {
289 text.Insert(pos, ch);
290 ++pos;
291 OnTextChanged();
292 Invalidate(GetRect());
293 }
294 else
295 {
296 text.Append(ch);
297 ++pos;
298 OnTextChanged();
299 Invalidate(GetRect());
300 }
301 }
302 private void SetCursorPos()
303 {
304 Point cp = Location();
305 cp.x = cp.x + pos;
306 SetControlCursorPos(cp);
307 SetCursorPos(cp.x, cp.y);
308 }
309 private ustring text;
310 private int pos;
311 private int startPos;
312 private Event<ChangedEventHandler> textChangedEvent;
313 private Event<SelectEventHandler> textEnteredEvent;
314 private ConsoleColor focusedForeColor;
315 private ConsoleColor focusedBackColor;
316 }
317 }