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