Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ComboBox.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: ComboBox.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Drop-down list of Buttons class
13 */
14 
15 #include "MemDebug.h"
16 #include "ComboBox.h"
17 #include "ComboList.h"
18 #include "Button.h"
19 #include "Video.h"
20 #include "Screen.h"
21 #include "Bitmap.h"
22 #include "Font.h"
23 #include "EventDispatch.h"
24 
25 // +--------------------------------------------------------------------+
26 // DECLARE MAPPING FUNCTIONS:
27 DEF_MAP_CLIENT(ComboBox, OnListSelect);
28 DEF_MAP_CLIENT(ComboBox, OnListExit);
29 
30 // +--------------------------------------------------------------------+
31 
32 ComboBox::ComboBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid)
33 : ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p)
34 {
35  button_state = 0;
36  captured = 0;
37  pre_state = 0;
38  seln = 0;
39  list = 0;
40  list_showing = false;
41  border = true;
42  animated = true;
43  bevel_width = 5;
44 
45  char buf[32];
46  sprintf_s(buf, "ComboBox %d", id);
47  desc = buf;
48 }
49 
50 ComboBox::ComboBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid)
51 : ActiveWindow(s, ax, ay, aw, ah, aid)
52 {
53  button_state = 0;
54  captured = 0;
55  pre_state = 0;
56  seln = 0;
57  list = 0;
58  list_showing = false;
59  border = true;
60  animated = true;
61  bevel_width = 5;
62 
63  char buf[32];
64  sprintf_s(buf, "ComboBox %d", id);
65  desc = buf;
66 }
67 
68 // +--------------------------------------------------------------------+
69 
71 {
72  items.destroy();
73 
74  if (list && !list_showing)
75  delete list;
76 }
77 
78 // +--------------------------------------------------------------------+
79 
80 void ComboBox::SetBevelWidth(short nNewValue)
81 {
82  if (nNewValue < 0) nNewValue = 0;
83  bevel_width = nNewValue;
84 }
85 
86 void ComboBox::SetBorder(bool bNewValue)
87 {
88  border = bNewValue;
89 }
90 
92 {
93  border_color = newValue;
94 }
95 
97 {
98  active_color = newValue;
99 }
100 
101 void ComboBox::SetAnimated(bool bNewValue)
102 {
103  animated = bNewValue;
104 }
105 
106 // +--------------------------------------------------------------------+
107 
108 void
110 {
111  int x = 0;
112  int y = 0;
113  int w = rect.w;
114  int h = rect.h;
115 
116  if (w < 1 || h < 1 || !shown)
117  return;
118 
119  Rect btn_rect(x,y,w,h);
120 
121  // draw the bevel:
122  DrawRectSimple(btn_rect, button_state);
123 
124  // draw the border:
125  if (border)
126  DrawRect(0,0,w-1,h-1,border_color);
127 
128  // draw the arrow:
129  POINT arrow[3];
130  double h3 = (double)h/3.0;
131 
132  arrow[0].x = (int) (w-2*h3);
133  arrow[0].y = (int) (h3);
134  arrow[1].x = (int) (w-h3);
135  arrow[1].y = (int) (h3);
136  arrow[2].x = (int) ((arrow[1].x + arrow[0].x)/2);
137  arrow[2].y = (int) (2*h3);
138 
139  FillPoly(3, arrow, border_color);
140 
141  // draw text here:
142  Text caption = text;
143  if (GetSelectedIndex() >= 0)
144  caption = GetSelectedItem();
145 
146  if (font && caption.length()) {
147  int border_size = 4;
148 
150  border_size = 8;
151 
152  Rect label_rect = CalcLabelRect();
153  int vert_space = label_rect.h;
154  int horz_space = label_rect.w;
155 
156  DrawText(caption.data(), 0, label_rect, DT_CALCRECT | DT_WORDBREAK | text_align);
157  vert_space = (vert_space - label_rect.h)/2;
158 
159  label_rect.w = horz_space;
160 
161  if (vert_space > 0)
162  label_rect.y += vert_space;
163 
164  if (animated && button_state > 0) {
165  label_rect.x += button_state;
166  label_rect.y += button_state;
167  }
168 
170  DrawText(caption.data(), 0, label_rect, DT_WORDBREAK | text_align);
171  }
172 }
173 
175 {
176  // fit the text in the bevel:
177  Rect label_rect;
178  label_rect.x = 0;
179  label_rect.y = 0;
180  label_rect.w = rect.w;
181  label_rect.h = rect.h;
182 
183  label_rect.Deflate(bevel_width, bevel_width);
184 
185  return label_rect;
186 }
187 
188 // +--------------------------------------------------------------------+
189 
190 void
192 {
193  if (state && active_color != Color::Black)
194  FillRect(rect, active_color);
195  else
196  FillRect(rect, back_color);
197 }
198 
199 // +--------------------------------------------------------------------+
200 
201 int ComboBox::OnMouseMove(int x, int y)
202 {
203  bool dirty = false;
204 
205  if (captured)
206  {
207  ActiveWindow* test = GetCapture();
208 
209  if (test != this)
210  {
211  captured = false;
212  button_state = 0;
213  dirty = true;
214  }
215 
216  else
217  {
218  if (button_state == 1)
219  {
220  if (!rect.Contains(x,y))
221  {
222  button_state = 0;
223  dirty = true;
224  }
225  }
226  else
227  {
228  if (rect.Contains(x,y))
229  {
230  button_state = 1;
231  dirty = true;
232  }
233  }
234  }
235  }
236 
237  return ActiveWindow::OnMouseMove(x,y);
238 }
239 
240 int ComboBox::OnLButtonDown(int x, int y)
241 {
242  if (!captured)
243  captured = SetCapture();
244 
245  button_state = 1;
246 
247  return ActiveWindow::OnLButtonDown(x,y);
248 }
249 
250 int ComboBox::OnLButtonUp(int x, int y)
251 {
252  if (captured) {
253  ReleaseCapture();
254  captured = 0;
255  }
256 
257  button_state = -1;
258  ShowList();
260  return ActiveWindow::OnLButtonUp(x,y);
261 }
262 
264 {
265  return ActiveWindow::OnClick();
266 }
267 
268 int ComboBox::OnMouseEnter(int mx, int my)
269 {
270  if (button_state == 0)
271  button_state = -1;
272 
273  return ActiveWindow::OnMouseEnter(mx, my);
274 }
275 
276 int ComboBox::OnMouseExit(int mx, int my)
277 {
278  if (button_state == -1)
279  button_state = 0;
280 
281  return ActiveWindow::OnMouseExit(mx, my);
282 }
283 
284 // +--------------------------------------------------------------------+
285 
286 void ComboBox::MoveTo(const Rect& r)
287 {
289 
290  if (list) {
291  delete list;
292  list = 0;
293  }
294 }
295 
297 {
298  if (!list) {
299  list = new(__FILE__,__LINE__) ComboList(this, screen,
300  rect.x, rect.y,
301  rect.w, rect.h,
302  items.size());
303 
304  }
305 
306  if (list) {
308  list->SetFont(font);
309  list->SetText(text);
311  list->SetItems(items);
312 
313  list->Show();
314  list_showing = true;
315 
317  if (dispatch) {
318  dispatch->MouseEnter(list);
319  dispatch->SetFocus(list);
320  }
321 
324  }
325 }
326 
328 {
329  if (list) {
330  // These will be handled by the list window itself (i hope)
333 
334  list->Hide();
335  list_showing = false;
336  }
337 }
338 
339 // +--------------------------------------------------------------------+
340 
342 {
343  if (list) {
344  int new_seln = list->GetSelectedIndex();
345 
346  if (new_seln >= 0 && new_seln < items.size())
347  seln = new_seln;
348 
349  HideList();
350  OnSelect();
352  }
353 }
354 
356 {
357  //HideList();
358  //Button::PlaySound(Button::SND_COMBO_CLOSE);
359 }
360 
361 // +--------------------------------------------------------------------+
362 
364 {
365  return items.size();
366 }
367 
369 {
370  items.destroy();
371  seln = 0;
372 }
373 
374 void ComboBox::AddItem(const char* item)
375 {
376  Text* t = new(__FILE__,__LINE__) Text(item);
377 
378  if (t) items.append(t);
379 }
380 
381 const char* ComboBox::GetItem(int index)
382 {
383  if (index >= 0 && index < items.size())
384  return items[index]->data();
385  else
386  return 0;
387 }
388 
389 void ComboBox::SetItem(int index, const char* item)
390 {
391  if (index >= 0 && index < items.size()) {
392  *items[index] = item;
393  }
394 
395  else {
396  Text* t = new(__FILE__,__LINE__) Text(item);
397  if (t)
398  items.append(t);
399  }
400 }
401 
402 void ComboBox::SetLabel(const char* label)
403 {
404  SetText(label);
405 }
406 
408 {
409  return items.size();
410 }
411 
413 {
414  if (seln >= 0 && seln < items.size())
415  return items[seln]->data();
416  else
417  return 0;
418 }
419 
421 {
422  if (seln >= 0 && seln < items.size())
423  return seln;
424  else
425  return -1;
426 }
427 
428 void ComboBox::SetSelection(int index)
429 {
430  if (seln != index && index >= 0 && index < items.size()) {
431  seln = index;
432  }
433 }
434