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