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