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