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