Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
EditBox.cpp
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: EditBox.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  EditBox ActiveWindow class
13 */
14 
15 #include "MemDebug.h"
16 #include "EditBox.h"
17 #include "FormWindow.h"
18 #include "Video.h"
19 #include "Font.h"
20 #include "Keyboard.h"
21 #include "Mouse.h"
22 
23 DWORD GetRealTime();
24 
25 // +--------------------------------------------------------------------+
26 
27 static int old_cursor;
28 
29 // +--------------------------------------------------------------------+
30 
31 EditBox::EditBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid)
32 : ScrollWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p), caret_x(0), caret_y(0)
33 {
34  sel_start = 0;
35  sel_length = 0;
36  h_offset = 0;
37  pass_char = 0;
38 
40 
41  char buf[32];
42  sprintf_s(buf, "EditBox %d", id);
43  desc = buf;
44 }
45 
46 EditBox::EditBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid)
47 : ScrollWindow(s, ax, ay, aw, ah, aid), caret_x(0), caret_y(0)
48 {
49  sel_start = 0;
50  sel_length = 0;
51  h_offset = 0;
52  pass_char = 0;
53 
55 
56  char buf[32];
57  sprintf_s(buf, "EditBox %d", id);
58  desc = buf;
59 }
60 
62 {
63 }
64 
65 // +--------------------------------------------------------------------+
66 
67 void
68 EditBox::DrawContent(const Rect& ctrl_rect)
69 {
70  int h = rect.h;
71 
72  if (line_height < 1)
73  line_height = GetFont()->Height();
74  page_size = h / (line_height + leading);
75 }
76 
77 // +--------------------------------------------------------------------+
78 
79 void
81 {
82  if (font && text.length()) {
83  int border_size = 4;
84 
86  border_size = 8;
87 
88  Rect label_rect = rect;
89 
90  label_rect.x = border_size;
91  label_rect.y = border_size;
92  label_rect.w -= border_size * 2;
93  label_rect.h -= border_size * 2;
94 
95  if (focus)
97 
98  // if displaying in password mode, create a display string
99  // containing the proper number of password chars:
100  Text s = text;
101  if (pass_char)
102  s = Text(pass_char, text.length());
103 
104  // no tabs set:
105  if (tab[0] == 0) {
106  DWORD text_flags = DT_WORDBREAK | text_align;
107 
108  if (single_line)
109  text_flags = text_flags | DT_SINGLELINE;
110 
111  if (style & WIN_TEXT_SHADOW) {
112  label_rect.x++;
113  label_rect.y++;
114 
116  DrawText(s.data() + h_offset, 0, label_rect, text_flags);
117 
118  label_rect.x--;
119  label_rect.y--;
120  }
121 
123  DrawText(s.data() + h_offset, 0, label_rect, text_flags);
124  }
125 
126  // use tabs:
127  else {
128  }
129 
130  font->SetCaretIndex(-1);
131  }
132  else {
133  caret_x = 2;
134  caret_y = 3;
135  }
136 }
137 
138 // +--------------------------------------------------------------------+
139 
141 {
142  return selected_color;
143 }
144 
146 {
147  if (selected_color != c) {
148  selected_color = c;
149  }
150 }
151 
153 {
154  if (sel_start == 0 && sel_length == text.length())
155  return text;
156 
157  Text selection;
158  char* buf = new(__FILE__,__LINE__) char[sel_length+1];
159 
160  if (buf) {
161  for (int i = 0; i < sel_length; i++)
162  buf[i] = text[(int) (sel_start + i)];
163 
164  buf[sel_length] = 0;
165 
166  selection = buf;
167  delete [] buf;
168  }
169 
170  return selection;
171 }
172 
174 {
175  if (n >= 0 && n <= text.length())
176  sel_start = n;
177 }
178 
180 {
181  if (n <= text.length() - sel_start)
182  sel_length = n;
183 }
184 
186 {
187  if (!single_line) {
188  h_offset = 0;
189  return;
190  }
191 
192  if (sel_start < 0) {
193  sel_start = 0;
194  h_offset = 0;
195  }
196 
197  else if (sel_start > h_offset) {
198  int x_caret;
199  bool moved;
200 
201  do {
202  x_caret = 0;
203  moved = false;
204 
205  if (pass_char) {
207  x_caret += font->StringWidth(pass.data(), pass.length());
208  }
209  else {
211  x_caret += font->StringWidth(sub.data(), sub.length());
212  }
213 
214  if (x_caret >= Width()-4) {
215  if (h_offset < text.length()) {
216  h_offset++;
217  moved = true;
218  }
219  }
220  }
221  while (moved);
222  }
223 
224  else {
226  }
227 }
228 
229 bool EditBox::CanScroll(int dir, int nlines)
230 {
231  return false;
232 }
233 
234 void EditBox::Scroll(int direction, int nlines)
235 {
237 }
238 
239 void EditBox::ScrollTo(int index)
240 {
241 }
242 
244 {
245  return 1;
246 }
247 
249 {
250  return page_size;
251 }
252 
253 // +--------------------------------------------------------------------+
254 
256 {
258 
259  sel_start = text.length();
260  sel_length = 0;
261 }
262 
264 {
266 }
267 
268 // +--------------------------------------------------------------------+
269 
270 int EditBox::CaretFromPoint(int x, int y) const
271 {
272  return 0;
273 }
274 
275 // +--------------------------------------------------------------------+
276 
277 int EditBox::OnMouseMove(int x, int y)
278 {
279  return ActiveWindow::OnMouseMove(x,y);
280 }
281 
282 // +--------------------------------------------------------------------+
283 
284 int EditBox::OnLButtonDown(int x, int y)
285 {
286  return ActiveWindow::OnLButtonDown(x,y);
287 }
288 
289 // +--------------------------------------------------------------------+
290 
291 int EditBox::OnLButtonUp(int x, int y)
292 {
293  return ActiveWindow::OnLButtonUp(x,y);
294 }
295 
296 // +--------------------------------------------------------------------+
297 
299 {
300  int fire_click = !scrolling;
301 
302  if (scrolling == SCROLL_THUMB)
304 
305  if (fire_click)
306  return ActiveWindow::OnClick();
307 
308  return 0;
309 }
310 
311 // +--------------------------------------------------------------------+
312 
313 void EditBox::Insert(char c)
314 {
315  if (single_line && c == '\n')
316  return;
317 
318  if (sel_start < text.length()) {
319  if (sel_start == 0) {
320  text = Text(c) + text;
321  sel_start = 1;
322  }
323  else {
324  Text t1 = text.substring(0, sel_start);
326  text = t1 + Text(c) + t2;
327  sel_start++;
328  }
329  }
330  else {
331  text += c;
332  sel_start = text.length();
333  }
334 
336 }
337 
338 void EditBox::Insert(const char* s)
339 {
340 }
341 
343 {
344  if (sel_start < text.length()) {
345  if (sel_start == 0) {
346  text = text.substring(1, text.length()-1);
347  }
348  else {
349  Text t1 = text.substring(0, sel_start);
351  text = t1 + t2;
352  }
353  }
354 
356 }
357 
359 {
360  if (sel_start > 0) {
361  if (sel_start == text.length()) {
362  text = text.substring(0, sel_start-1);
363  }
364  else {
365  Text t1 = text.substring(0, sel_start-1);
367  text = t1 + t2;
368  }
369 
370  sel_start--;
372  }
373 }
374 
375 int EditBox::OnKeyDown(int vk, int flags)
376 {
377  if (vk >= 'A' && vk <= 'Z') {
378  if (flags & 1)
379  Insert((char) vk);
380  else
381  Insert((char) tolower(vk));
382  }
383  else {
384  switch (vk) {
385  case VK_LEFT:
386  if (sel_start > 0) sel_start--;
388  break;
389 
390  case VK_RIGHT:
391  if (sel_start < text.length()) sel_start++;
393  break;
394 
395  case VK_HOME:
396  sel_start = 0;
398  break;
399 
400  case VK_END:
401  sel_start = text.length();
403  break;
404 
405  case VK_DELETE: Delete(); break;
406  case VK_BACK: Backspace(); break;
407 
408  case VK_SPACE: Insert(' '); break;
409  case VK_RETURN: Insert('\n'); break;
410 
411  case VK_NUMPAD0: Insert('0'); break;
412  case VK_NUMPAD1: Insert('1'); break;
413  case VK_NUMPAD2: Insert('2'); break;
414  case VK_NUMPAD3: Insert('3'); break;
415  case VK_NUMPAD4: Insert('4'); break;
416  case VK_NUMPAD5: Insert('5'); break;
417  case VK_NUMPAD6: Insert('6'); break;
418  case VK_NUMPAD7: Insert('7'); break;
419  case VK_NUMPAD8: Insert('8'); break;
420  case VK_NUMPAD9: Insert('9'); break;
421  case VK_DECIMAL: Insert('.'); break;
422  case VK_ADD: Insert('+'); break;
423  case VK_SUBTRACT: Insert('-'); break;
424  case VK_MULTIPLY: Insert('*'); break;
425  case VK_DIVIDE: Insert('/'); break;
426 
427  case '0': if (flags & 1) Insert(')'); else Insert('0'); break;
428  case '1': if (flags & 1) Insert('!'); else Insert('1'); break;
429  case '2': if (flags & 1) Insert('@'); else Insert('2'); break;
430  case '3': if (flags & 1) Insert('#'); else Insert('3'); break;
431  case '4': if (flags & 1) Insert('$'); else Insert('4'); break;
432  case '5': if (flags & 1) Insert('%'); else Insert('5'); break;
433  case '6': if (flags & 1) Insert('^'); else Insert('6'); break;
434  case '7': if (flags & 1) Insert('&'); else Insert('7'); break;
435  case '8': if (flags & 1) Insert('*'); else Insert('8'); break;
436  case '9': if (flags & 1) Insert('('); else Insert('9'); break;
437  case 186: if (flags & 1) Insert(':'); else Insert(';'); break;
438  case 187: if (flags & 1) Insert('+'); else Insert('='); break;
439  case 188: if (flags & 1) Insert('<'); else Insert(','); break;
440  case 189: if (flags & 1) Insert('_'); else Insert('-'); break;
441  case 190: if (flags & 1) Insert('>'); else Insert('.'); break;
442  case 191: if (flags & 1) Insert('?'); else Insert('/'); break;
443  case 192: if (flags & 1) Insert('~'); else Insert('`'); break;
444  case 219: if (flags & 1) Insert('{'); else Insert('['); break;
445  case 221: if (flags & 1) Insert('}'); else Insert(']'); break;
446  case 220: if (flags & 1) Insert('|'); else Insert('\\'); break;
447  case 222: if (flags & 1) Insert('"'); else Insert('\''); break;
448  }
449  }
450 
451  return ActiveWindow::OnKeyDown(vk, flags);
452 }