SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FXSevenSegment.cpp
Go to the documentation of this file.
1 /********************************************************************************
2 * *
3 * Seven segment display widget *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2003 by Mathew Robertson. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 *********************************************************************************/
22 /* =========================================================================
23  * included modules
24  * ======================================================================= */
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <fxver.h>
32 #include <xincs.h>
33 #include <fxdefs.h>
34 #include <fx.h>
35 /*
36 #include <FXStream.h>
37 #include <FXString.h>
38 #include <FXSize.h>
39 #include <FXPoint.h>
40 #include <FXRectangle.h>
41 #include <FXRegistry.h>
42 #include <FXHash.h>
43 #include <FXApp.h>
44 #include <FXDCWindow.h>
45 */
46 using namespace FX;
47 #include "FXSevenSegment.h"
48 
49 #ifdef CHECK_MEMORY_LEAKS
50 #include <foreign/nvwa/debug_new.h>
51 #endif // CHECK_MEMORY_LEAKS
52 using namespace FXEX;
53 namespace FXEX {
54 
55 /* note: this class may change into FXLCDsegment, so as to support 7 or 14 segment display */
56 #define ASCII_ZERO 48
57 
58 // map
59 FXDEFMAP(FXSevenSegment) FXSevenSegmentMap[] = {
60  FXMAPFUNC(SEL_PAINT, 0, FXSevenSegment::onPaint),
61  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETVALUE, FXSevenSegment::onCmdSetValue),
62  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETINTVALUE, FXSevenSegment::onCmdSetIntValue),
63  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETINTVALUE, FXSevenSegment::onCmdGetIntValue),
64  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETSTRINGVALUE, FXSevenSegment::onCmdSetStringValue),
65  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETSTRINGVALUE, FXSevenSegment::onCmdGetStringValue),
66  // FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_TIP,FXSevenSegment::onQueryTip),
67  // FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_HELP,FXSevenSegment::onQueryHelp),
68 };
69 FXIMPLEMENT(FXSevenSegment, FXFrame, FXSevenSegmentMap, ARRAYNUMBER(FXSevenSegmentMap))
70 
71 // ctor
72 FXSevenSegment::FXSevenSegment(FXComposite* p, FXObject* tgt, FXSelector sel, FXuint opts, FXint pl, FXint pr, FXint pt, FXint pb) : FXFrame(p, opts, 0, 0, 0, 0, pl, pr, pt, pb), value(' '), fgcolor(FXRGB(0, 255, 0)), bgcolor(FXRGB(0, 0, 0)), hsl(8), vsl(8), st(3), groove(1) {
73  setTarget(tgt);
74  setSelector(sel);
75  enable();
76 }
77 
78 // minimum width
79 FXint FXSevenSegment::getDefaultWidth() {
80  return padleft + (groove << 1) + hsl + padright + (border << 1);
81 }
82 
83 // minimum height
84 FXint FXSevenSegment::getDefaultHeight() {
85  return padtop + (groove << 2) + (vsl << 1) + padbottom + (border << 1);
86 }
87 
88 // set value on widget
89 void FXSevenSegment::setText(FXchar val) {
90  if (FXString(val, 1).upper() != FXString(value, 1).upper()) {
91  value = val;
92  recalc();
93  update();
94  }
95 }
96 
97 // set foreground color
98 void FXSevenSegment::setFgColor(const FXColor clr) {
99  if (fgcolor != clr) {
100  fgcolor = clr;
101  recalc();
102  update();
103  }
104 }
105 
106 // set backgound color
107 void FXSevenSegment::setBgColor(const FXColor clr) {
108  if (bgcolor != clr) {
109  bgcolor = clr;
110  recalc();
111  update();
112  }
113 }
114 
115 // set horizontal segment length
116 void FXSevenSegment::setHorizontal(const FXint len) {
117  if (len != hsl) {
118  hsl = len;
119  checkSize();
120  recalc();
121  update();
122  }
123 }
124 
125 // set vertical segment length
126 void FXSevenSegment::setVertical(const FXint len) {
127  if (len != vsl) {
128  vsl = len;
129  checkSize();
130  recalc();
131  update();
132  }
133 }
134 
135 // set segment thickness
136 void FXSevenSegment::setThickness(const FXint width) {
137  if (width != st) {
138  st = width;
139  checkSize();
140  recalc();
141  update();
142  }
143 }
144 
145 // set groove thickness
146 void FXSevenSegment::setGroove(const FXint width) {
147  if (width != groove) {
148  groove = width;
149  checkSize();
150  recalc();
151  update();
152  }
153 }
154 
155 // draw/redraw object
156 long FXSevenSegment::onPaint(FXObject*, FXSelector, void* ptr) {
157  FXEvent* event = (FXEvent*) ptr;
158  FXDCWindow dc(this, event);
159  drawFrame(dc, 0, 0, width, height);
160  dc.setForeground(bgcolor);
161  dc.fillRectangle(border, border, width - (border << 1), height - (border << 1));
162  dc.setForeground(fgcolor);
163  drawFigure(dc, value);
164  return 1;
165 }
166 
167 // set from value
168 long FXSevenSegment::onCmdSetValue(FXObject*, FXSelector, void* ptr) {
169  FXchar* c = (FXchar*)ptr;
170  if (c[0] != '\0') {
171  setText(c[0]);
172  }
173  return 1;
174 }
175 
176 // get value from int
177 long FXSevenSegment::onCmdGetIntValue(FXObject* sender, FXSelector, void*) {
178  FXint i = value - ASCII_ZERO;
179  if (i < 0) {
180  i = 0;
181  }
182  if (i > 9) {
183  i = 9;
184  }
185  sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&i);
186  return 1;
187 }
188 
189 // set from int value
190 long FXSevenSegment::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) {
191  FXint i = *((FXint*)ptr);
192  if (i < 0) {
193  i = 0;
194  }
195  if (i > 9) {
196  i = 9;
197  }
198  setText((FXchar)(i + ASCII_ZERO));
199  return 1;
200 }
201 
202 // get value from string
203 long FXSevenSegment::onCmdGetStringValue(FXObject* sender, FXSelector, void*) {
204  FXString s(value, 1);
205  sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*)&s);
206  return 1;
207 }
208 
209 // set from string value
210 long FXSevenSegment::onCmdSetStringValue(FXObject*, FXSelector, void* ptr) {
211  FXString* s = (FXString*)ptr;
212  if ((*s).length()) {
213  setText((*s)[0]);
214  }
215  return 1;
216 }
217 
218 // draw the specific character - figure out which segments to draw
219 void FXSevenSegment::drawFigure(FXDCWindow& dc, FXchar figure) {
220  switch (figure) {
221  case ' ' :
222  drawSegments(dc, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
223  break;
224  case '(' :
225  drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
226  break;
227  case ')' :
228  drawSegments(dc, TRUE , FALSE, TRUE , FALSE, FALSE, TRUE , TRUE);
229  break;
230  case '[' :
231  drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
232  break;
233  case ']' :
234  drawSegments(dc, TRUE , FALSE, TRUE , FALSE, FALSE, TRUE , TRUE);
235  break;
236  case '=' :
237  drawSegments(dc, FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, TRUE);
238  break;
239 // case '+' : drawSegments (dc, FALSE,FALSE,FALSE,TRUE ,FALSE,FALSE,FALSE); break;
240  case '-' :
241  drawSegments(dc, FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE);
242  break;
243  case '_' :
244  case '.' :
245  drawSegments(dc, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE);
246  break;
247  case '0' :
248  drawSegments(dc, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE);
249  break;
250  case '1' :
251  drawSegments(dc, FALSE, FALSE, TRUE , FALSE, FALSE, TRUE , FALSE);
252  break;
253  case '2' :
254  drawSegments(dc, TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE);
255  break;
256  case '3' :
257  drawSegments(dc, TRUE , FALSE, TRUE , TRUE , FALSE, TRUE , TRUE);
258  break;
259  case '4' :
260  drawSegments(dc, FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , FALSE);
261  break;
262  case '5' :
263  drawSegments(dc, TRUE , TRUE , FALSE, TRUE , FALSE, TRUE , TRUE);
264  break;
265  case '6' :
266  drawSegments(dc, TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , TRUE);
267  break;
268  case '7' :
269  drawSegments(dc, TRUE , FALSE, TRUE , FALSE, FALSE, TRUE , FALSE);
270  break;
271  case '8' :
272  drawSegments(dc, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE);
273  break;
274  case '9' :
275  drawSegments(dc, TRUE , TRUE , TRUE , TRUE , FALSE, TRUE , TRUE);
276  break;
277  case 'a' :
278  case 'A' :
279  drawSegments(dc, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE);
280  break;
281  case 'b' :
282  case 'B' :
283  drawSegments(dc, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , TRUE);
284  break;
285  case 'c' :
286  case 'C' :
287  drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
288  break;
289  case 'd' :
290  case 'D' :
291  drawSegments(dc, FALSE, FALSE, TRUE , TRUE , TRUE , TRUE , TRUE);
292  break;
293  case 'e' :
294  case 'E' :
295  drawSegments(dc, TRUE , TRUE , FALSE, TRUE , TRUE , FALSE, TRUE);
296  break;
297  case 'f' :
298  case 'F' :
299  drawSegments(dc, TRUE , TRUE , FALSE, TRUE , TRUE , FALSE, FALSE);
300  break;
301  case 'g' :
302  case 'G' :
303  drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , TRUE , TRUE);
304  break;
305  case 'h' :
306  case 'H' :
307  drawSegments(dc, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , FALSE);
308  break;
309  case 'i' :
310  case 'I' :
311  drawSegments(dc, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE , FALSE);
312  break;
313  case 'j' :
314  case 'J' :
315  drawSegments(dc, FALSE, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE);
316  break;
317 // case 'k' :
318 // case 'k' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
319  case 'l' :
320  case 'L' :
321  drawSegments(dc, FALSE, TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
322  break;
323 // case 'm' :
324 // case 'M' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
325  case 'n' :
326  case 'N' :
327  drawSegments(dc, FALSE, FALSE, FALSE, TRUE , TRUE , TRUE , FALSE);
328  break;
329  case 'o' :
330  case 'O' :
331  drawSegments(dc, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE);
332  break;
333  case 'p' :
334  case 'P' :
335  drawSegments(dc, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE, FALSE);
336  break;
337  case 'q' :
338  case 'Q' :
339  drawSegments(dc, TRUE , TRUE , TRUE , TRUE , FALSE, TRUE , FALSE);
340  break;
341  case 'r' :
342  case 'R' :
343  drawSegments(dc, FALSE, FALSE, FALSE, TRUE , TRUE , FALSE, FALSE);
344  break;
345  case 's' :
346  case 'S' :
347  drawSegments(dc, TRUE , TRUE , FALSE, TRUE , FALSE, TRUE , TRUE);
348  break;
349  case 't' :
350  case 'T' :
351  drawSegments(dc, FALSE, TRUE , FALSE, TRUE , TRUE , FALSE, FALSE);
352  break;
353  case 'u' :
354  case 'U' :
355  drawSegments(dc, FALSE, TRUE , TRUE , FALSE, TRUE , TRUE , TRUE);
356  break;
357 // case 'v' :
358 // case 'V' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
359 // case 'w' :
360 // case 'W' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
361  case 'x' :
362  case 'X' :
363  drawSegments(dc, FALSE, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE);
364  break;
365  case 'y' :
366  case 'Y' :
367  drawSegments(dc, FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE);
368  break;
369 // case 'z' :
370 // case 'Z' :
371  default :
372  fxerror("FXSevenSegment doesnt support: %c\n", figure);
373  }
374 }
375 
376 // validates the sizes of the segment dimensions
377 void FXSevenSegment::checkSize() {
378  if (hsl < 3) {
379  hsl = 3;
380  st = 1;
381  }
382  if (vsl < 3) {
383  vsl = 3;
384  st = 1;
385  }
386  if (st < 1) {
387  st = 1;
388  }
389  if (hsl < (st << 1)) {
390  hsl = (st << 1) + 1;
391  }
392  if (vsl < (st << 1)) {
393  vsl = (st << 1) + 1;
394  }
395  if (hsl < 8 || vsl < 8) {
396  groove = 2;
397  }
398  if (hsl < 1 || vsl < 3 || st < 3) {
399  groove = 1;
400  }
401  if (groove >= st) {
402  groove = st - 1;
403  }
404 }
405 
406 // draw each segment, into the available drawing space
407 // if widget is resizeable, caculate new sizes for length/width/grove of each segment
408 void FXSevenSegment::drawSegments(FXDCWindow& dc, FXbool s1, FXbool s2, FXbool s3, FXbool s4, FXbool s5, FXbool s6, FXbool s7) {
409  FXint sx = border + padleft, sy = border + padtop;
410  FXint x, y;
411  if (options & LAYOUT_FILL) {
412  if (options & LAYOUT_FILL_X) {
413  hsl = width - padleft - padright - (border << 1);
414  if (hsl < 4) {
415  hsl = 4;
416  }
417  }
418  if (options & LAYOUT_FILL_Y) {
419  vsl = (height - padtop - padbottom - (border << 1)) >> 1;
420  if (vsl < 4) {
421  vsl = 4;
422  }
423  }
424  st = FXMIN(hsl, vsl) / 4;
425  groove = st / 4;
426  if (st < 1) {
427  st = 1;
428  }
429  if (groove < 1) {
430  groove = 1;
431  }
432  if (options & LAYOUT_FILL_X) {
433  hsl -= groove << 1;
434  }
435  if (options & LAYOUT_FILL_Y) {
436  vsl -= groove << 1;
437  }
438  }
439  if (s1) {
440  x = sx + groove;
441  y = sy;
442  drawTopSegment(dc, x, y);
443  }
444  if (s2) {
445  x = sx;
446  y = sy + groove;
447  drawLeftTopSegment(dc, x, y);
448  }
449  if (s3) {
450  x = sx + groove + hsl - st + groove;
451  y = sy + groove;
452  drawRightTopSegment(dc, x, y);
453  }
454  if (s4) {
455  x = sx + groove;
456  y = sy + groove + vsl - (st >> 1) + groove;
457  drawMiddleSegment(dc, x, y);
458  }
459  if (s5) {
460  x = sx;
461  y = sy + (groove << 1) + vsl + groove;
462  drawLeftBottomSegment(dc, x, y);
463  }
464  if (s6) {
465  x = sx + groove + hsl - st + groove;
466  y = sy + (groove << 1) + vsl + groove;
467  drawRightBottomSegment(dc, x, y);
468  }
469  if (s7) {
470  x = sx + groove;
471  y = sy + (groove << 1) + vsl + groove + vsl + groove - st;
472  drawBottomSegment(dc, x, y);
473  }
474 }
475 
476 void FXSevenSegment::drawTopSegment(FXDCWindow& dc, FXshort x, FXshort y) {
477  FXPoint points[4];
478  points[0].x = x;
479  points[0].y = y;
480  points[1].x = x + hsl;
481  points[1].y = y;
482  points[2].x = x + hsl - st;
483  points[2].y = y + st;
484  points[3].x = x + st;
485  points[3].y = y + st;
486  dc.fillPolygon(points, 4);
487 }
488 
489 void FXSevenSegment::drawLeftTopSegment(FXDCWindow& dc, FXshort x, FXshort y) {
490  FXPoint points[4];
491  points[0].x = x;
492  points[0].y = y;
493  points[1].x = x + st;
494  points[1].y = y + st;
495  points[2].x = x + st;
496  points[2].y = y + vsl - (st >> 1);
497  points[3].x = x;
498  points[3].y = y + vsl;
499  dc.fillPolygon(points, 4);
500 }
501 
502 void FXSevenSegment::drawRightTopSegment(FXDCWindow& dc, FXshort x, FXshort y) {
503  FXPoint points[4];
504  points[0].x = x + st;
505  points[0].y = y;
506  points[1].x = x + st;
507  points[1].y = y + vsl;
508  points[2].x = x;
509  points[2].y = y + vsl - (st >> 1);
510  points[3].x = x;
511  points[3].y = y + st;
512  dc.fillPolygon(points, 4);
513 }
514 
515 void FXSevenSegment::drawMiddleSegment(FXDCWindow& dc, FXshort x, FXshort y) {
516  FXPoint points[6];
517  points[0].x = x + st;
518  points[0].y = y;
519  points[1].x = x + hsl - st;
520  points[1].y = y;
521  points[2].x = x + hsl;
522  points[2].y = y + (st >> 1);
523  points[3].x = x + hsl - st;
524  points[3].y = y + st;
525  points[4].x = x + st;
526  points[4].y = y + st;
527  points[5].x = x;
528  points[5].y = y + (st >> 1);
529  dc.fillPolygon(points, 6);
530 }
531 
532 void FXSevenSegment::drawLeftBottomSegment(FXDCWindow& dc, FXshort x, FXshort y) {
533  FXPoint points[4];
534  points[0].x = x;
535  points[0].y = y;
536  points[1].x = x + st;
537  points[1].y = y + (st >> 1);
538  points[2].x = x + st;
539  points[2].y = y + vsl - st;
540  points[3].x = x;
541  points[3].y = y + vsl;
542  dc.fillPolygon(points, 4);
543 }
544 
545 void FXSevenSegment::drawRightBottomSegment(FXDCWindow& dc, FXshort x, FXshort y) {
546  FXPoint points[4];
547  points[0].x = x + st;
548  points[0].y = y;
549  points[1].x = x + st;
550  points[1].y = y + vsl;
551  points[2].x = x;
552  points[2].y = y + vsl - st;
553  points[3].x = x;
554  points[3].y = y + (st >> 1);
555  dc.fillPolygon(points, 4);
556 }
557 
558 void FXSevenSegment::drawBottomSegment(FXDCWindow& dc, FXshort x, FXshort y) {
559  FXPoint points[4];
560  points[0].x = x + st;
561  points[0].y = y;
562  points[1].x = x + hsl - st;
563  points[1].y = y;
564  points[2].x = x + hsl;
565  points[2].y = y + st;
566  points[3].x = x;
567  points[3].y = y + st;
568  dc.fillPolygon(points, 4);
569 }
570 
571 void FXSevenSegment::save(FXStream& store) const {
572  FXFrame::save(store);
573  store << value;
574  store << fgcolor;
575  store << bgcolor;
576  store << hsl;
577  store << vsl;
578  store << st;
579  store << groove;
580 }
581 
582 void FXSevenSegment::load(FXStream& store) {
583  FXFrame::load(store);
584  store >> value;
585  store >> fgcolor;
586  store >> bgcolor;
587  store >> hsl;
588  store >> vsl;
589  store >> st;
590  store >> groove;
591 }
592 
593 // let parent show tip if appropriate
594 long FXSevenSegment::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) {
595  if (getParent()) {
596  return getParent()->handle(sender, sel, ptr);
597  }
598  return 0;
599 }
600 
601 // let parent show help if appropriate
602 long FXSevenSegment::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) {
603  if (getParent()) {
604  return getParent()->handle(sender, sel, ptr);
605  }
606  return 0;
607 }
608 
609 }
610