Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/foxtools/MFXLCDLabel.cpp
169678 views
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
/****************************************************************************/
14
/// @file MFXLCDLabel.cpp
15
/// @author Mathew Robertson
16
/// @author Daniel Krajzewicz
17
/// @author Michael Behrisch
18
/// @date 2004-03-19
19
///
20
//
21
/****************************************************************************/
22
23
#include "MFXStaticToolTip.h"
24
#include "MFXSevenSegment.h"
25
#include "MFXBaseObject.h"
26
#include "MFXLCDLabel.h"
27
28
// ===========================================================================
29
// FOX callback mapping
30
// ===========================================================================
31
32
FXDEFMAP(MFXLCDLabel) MFXLCDLabelMap[] = {
33
FXMAPFUNC(SEL_PAINT, 0, MFXLCDLabel::onPaint),
34
FXMAPFUNC(SEL_ENTER, 0, MFXLCDLabel::onEnter),
35
FXMAPFUNC(SEL_LEAVE, 0, MFXLCDLabel::onLeave),
36
FXMAPFUNC(SEL_MOTION, 0, MFXLCDLabel::onMotion),
37
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETVALUE, MFXLCDLabel::onCmdSetValue),
38
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETINTVALUE, MFXLCDLabel::onCmdSetIntValue),
39
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETREALVALUE, MFXLCDLabel::onCmdSetRealValue),
40
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETSTRINGVALUE, MFXLCDLabel::onCmdSetStringValue),
41
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETINTVALUE, MFXLCDLabel::onCmdGetIntValue),
42
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETREALVALUE, MFXLCDLabel::onCmdGetRealValue),
43
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETSTRINGVALUE, MFXLCDLabel::onCmdGetStringValue),
44
//FXMAPFUNC(SEL_UPDATE, FXWindow::ID_QUERY_TIP, MFXLCDLabel::onQueryTip),
45
//FXMAPFUNC(SEL_UPDATE, FXWindow::ID_QUERY_HELP, MFXLCDLabel::onQueryHelp),
46
// map key
47
FXMAPKEY(MFXLCDLabel::ID_SEVENSEGMENT, MFXLCDLabel::onRedirectEvent),
48
};
49
50
// Object implementation
51
FXIMPLEMENT(MFXLCDLabel, FXHorizontalFrame, MFXLCDLabelMap, ARRAYNUMBER(MFXLCDLabelMap))
52
53
// ===========================================================================
54
// method definitions
55
// ===========================================================================
56
57
MFXLCDLabel::MFXLCDLabel(FXComposite* p, MFXStaticToolTip* staticToolTip, FXuint nfig, FXObject* tgt, FXSelector sel, FXuint opts, FXint pl, FXint pr, FXint pt, FXint pb, FXint hs) :
58
FXHorizontalFrame(p, opts, 0, 0, 0, 0, pl, pr, pt, pb, hs, 0),
59
myNFigures(nfig),
60
myStaticToolTip(staticToolTip) {
61
if (nfig == 0) {
62
fxerror("%s: must have at least one figure.\n", getClassName());
63
}
64
setTarget(tgt);
65
setSelector(sel);
66
enable();
67
for (FXint i = 0; i < myNFigures; i++) {
68
new MFXSevenSegment(this, this, ID_SEVENSEGMENT, 0, 0, 0, 0);
69
}
70
}
71
72
73
MFXLCDLabel::~MFXLCDLabel() {
74
/*
75
for (MFXSevenSegment *child=(MFXSevenSegment*)getFirst(); child; child=(MFXSevenSegment*)child->getNext()){
76
delete child;
77
}
78
*/
79
}
80
81
82
void
83
MFXLCDLabel::create() {
84
FXHorizontalFrame::create();
85
for (FXWindow* child = getFirst(); child; child = child->getNext()) {
86
child->create();
87
}
88
}
89
90
91
void
92
MFXLCDLabel::detach() {
93
for (FXWindow* child = getFirst(); child; child = child->getNext()) {
94
child->detach();
95
}
96
FXHorizontalFrame::detach();
97
}
98
99
100
void
101
MFXLCDLabel::destroy() {
102
for (FXWindow* child = getFirst(); child; child = child->getNext()) {
103
child->destroy();
104
}
105
FXHorizontalFrame::destroy();
106
}
107
108
109
FXColor
110
MFXLCDLabel::getFgColor() const {
111
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
112
return child->getFgColor();
113
}
114
115
116
void
117
MFXLCDLabel::setFgColor(FXColor clr) {
118
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
119
if (clr != child->getFgColor()) {
120
for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
121
child->setFgColor(clr);
122
}
123
}
124
}
125
126
127
FXColor
128
MFXLCDLabel::getBgColor() const {
129
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
130
return child->getBgColor();
131
}
132
133
134
void
135
MFXLCDLabel::setBgColor(FXColor clr) {
136
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
137
if (clr != child->getBgColor()) {
138
for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
139
child->setBgColor(clr);
140
}
141
}
142
}
143
144
145
void
146
MFXLCDLabel::setText(FXString lbl) {
147
if (lbl != myLabel) {
148
myLabel = lbl;
149
recalc();
150
update();
151
}
152
}
153
154
155
FXString
156
MFXLCDLabel::getText() const {
157
return myLabel;
158
}
159
160
161
FXint
162
MFXLCDLabel::getHorizontal() const {
163
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
164
return child->getHorizontal();
165
}
166
167
168
void
169
MFXLCDLabel::setHorizontal(const FXint len) {
170
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
171
if (len != child->getHorizontal()) {
172
for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
173
child->setHorizontal(len);
174
}
175
recalc();
176
update();
177
}
178
}
179
180
181
FXint
182
MFXLCDLabel::getVertical() const {
183
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
184
return child->getVertical();
185
}
186
187
188
void
189
MFXLCDLabel::setVertical(const FXint len) {
190
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
191
if (len != child->getVertical()) {
192
for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
193
child->setVertical(len);
194
}
195
recalc();
196
update();
197
}
198
}
199
200
201
FXint
202
MFXLCDLabel::getThickness() const {
203
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
204
return child->getThickness();
205
}
206
207
208
void
209
MFXLCDLabel::setThickness(const FXint w) {
210
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
211
if (w != child->getThickness()) {
212
for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
213
child->setThickness(w);
214
}
215
recalc();
216
update();
217
}
218
}
219
220
221
FXint
222
MFXLCDLabel::getGroove() const {
223
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
224
return child->getGroove();
225
}
226
227
228
void
229
MFXLCDLabel::setGroove(const FXint w) {
230
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
231
if (w != child->getGroove()) {
232
for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
233
child->setGroove(w);
234
}
235
recalc();
236
update();
237
}
238
}
239
240
241
long
242
MFXLCDLabel::onCmdSetValue(FXObject*, FXSelector, void* ptr) {
243
setText((const FXchar*)ptr);
244
return 1;
245
}
246
247
248
long
249
MFXLCDLabel::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) {
250
setText(FXStringVal(*((FXint*)ptr)));
251
return 1;
252
}
253
254
255
long
256
MFXLCDLabel::onCmdSetRealValue(FXObject*, FXSelector, void* ptr) {
257
setText(FXStringVal(*((FXdouble*)ptr)));
258
return 1;
259
}
260
261
262
long
263
MFXLCDLabel::onCmdSetStringValue(FXObject*, FXSelector, void* ptr) {
264
setText(*((FXString*)ptr));
265
return 1;
266
}
267
268
269
long
270
MFXLCDLabel::onCmdGetIntValue(FXObject*, FXSelector, void* ptr) {
271
*((FXint*)ptr) = FXIntVal(getText());
272
return 1;
273
}
274
275
276
long
277
MFXLCDLabel::onCmdGetRealValue(FXObject*, FXSelector, void* ptr) {
278
*((FXdouble*)ptr) = FXDoubleVal(getText());
279
return 1;
280
}
281
282
283
long
284
MFXLCDLabel::onCmdGetStringValue(FXObject*, FXSelector, void* ptr) {
285
*((FXString*)ptr) = getText();
286
return 1;
287
}
288
289
290
long
291
MFXLCDLabel::onPaint(FXObject*, FXSelector, void* ptr) {
292
FXEvent* event = (FXEvent*) ptr;
293
FXDCWindow dc(this, event);
294
drawFrame(dc, 0, 0, width, height);
295
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
296
// Fill the background
297
dc.setForeground(child->getBgColor());
298
dc.fillRectangle(border, border, width - (border << 1), height - (border << 1));
299
// Draw the current string
300
dc.setForeground(child->getFgColor());
301
drawString(myLabel);
302
return 1;
303
}
304
305
306
long
307
MFXLCDLabel::onEnter(FXObject* obj, FXSelector sel, void* ptr) {
308
// show static toolTip depending of myToolTipText
309
if (!myToolTipText.empty()) {
310
// show tip show
311
myStaticToolTip->showStaticToolTip(myToolTipText);
312
} else {
313
myStaticToolTip->hideStaticToolTip();
314
}
315
return FXHorizontalFrame::onEnter(obj, sel, ptr);
316
}
317
318
319
long
320
MFXLCDLabel::onLeave(FXObject* obj, FXSelector sel, void* ptr) {
321
// hide static toolTip
322
myStaticToolTip->hideStaticToolTip();
323
return FXHorizontalFrame::onLeave(obj, sel, ptr);
324
}
325
326
327
long
328
MFXLCDLabel::onMotion(FXObject* sender, FXSelector sel, void* ptr) {
329
// update static tooltip
330
myStaticToolTip->onUpdate(sender, sel, ptr);
331
return FXHorizontalFrame::onMotion(sender, sel, ptr);
332
}
333
334
335
long
336
MFXLCDLabel::onRedirectEvent(FXObject*, FXSelector sel, void* ptr) {
337
FXuint seltype = FXSELTYPE(sel);
338
if (isEnabled()) {
339
if (target) {
340
target->handle(this, FXSEL(seltype, message), ptr);
341
}
342
}
343
return 1;
344
}
345
346
347
FXint
348
MFXLCDLabel::getDefaultWidth() {
349
return padleft + getFirst()->getDefaultWidth() * myNFigures + hspacing * (myNFigures - 1) + padright + (border << 1);
350
}
351
352
353
FXint
354
MFXLCDLabel::getDefaultHeight() {
355
return padtop + getFirst()->getDefaultHeight() + padbottom + (border << 1);
356
}
357
358
359
void
360
MFXLCDLabel::setToolTipText(const FXString& text) {
361
myToolTipText = text;
362
}
363
364
365
void
366
MFXLCDLabel::save(FXStream& store) const {
367
FXHorizontalFrame::save(store);
368
store << myLabel;
369
store << myNFigures;
370
}
371
372
373
void
374
MFXLCDLabel::load(FXStream& store) {
375
FXHorizontalFrame::load(store);
376
store >> myLabel;
377
store >> myNFigures;
378
}
379
380
381
long
382
MFXLCDLabel::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) {
383
if (getParent()) {
384
return getParent()->handle(sender, sel, ptr);
385
}
386
return 0;
387
}
388
389
390
long
391
MFXLCDLabel::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) {
392
if (getParent()) {
393
return getParent()->handle(sender, sel, ptr);
394
}
395
return 0;
396
}
397
398
399
void
400
MFXLCDLabel::drawString(const FXString& lbl) {
401
FXint i = 0;
402
FXString displayString(' ', myNFigures);
403
if (options & LCDLABEL_LEADING_ZEROS && (FXIntVal(lbl) || lbl == "0")) {
404
FXString txt = lbl;
405
if (txt[0] == '-') {
406
displayString.replace(0, '-');
407
txt.erase(0);
408
i = 1;
409
}
410
for (; (i + txt.length()) < myNFigures; i++) {
411
displayString.replace(i, '0');
412
}
413
displayString.insert(i, txt);
414
} else if (options & JUSTIFY_RIGHT) {
415
for (; (i + lbl.length()) < myNFigures; i++) {}
416
displayString.insert(i, lbl);
417
} else {
418
displayString.insert(0, lbl);
419
}
420
displayString.trunc(myNFigures);
421
i = 0;
422
423
// FIXME: at the moment, if we resize the parent widget, we must use integer multiples
424
// of the SevenSegment width. The problem is that it makes the padding on the
425
// RHS look wrong. What we need to do is to extend the horizontal segment width
426
// for the last sevensegment, so as to fill the remaining space.
427
MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
428
if (options & LAYOUT_FILL) {
429
const FXint w = this->width - padleft - padright - (border << 1);
430
const FXint h = this->height - padtop - padbottom - (border << 1);
431
hspacing = FXMAX(w, h) / 50;
432
if (hspacing < 1) {
433
hspacing = 1;
434
}
435
FXint hsl = (w - (myNFigures - 1) * hspacing) / myNFigures;
436
if (hsl < 5) {
437
hsl = 5;
438
}
439
FXint vsl = h >> 1;
440
if (vsl < 5) {
441
vsl = 5;
442
}
443
FXint st = FXMIN(hsl, vsl) / 4;
444
if (st < 1) {
445
st = 1;
446
}
447
FXint groove = st / 4;
448
if (groove < 1) {
449
groove = 1;
450
}
451
if (options & LAYOUT_FILL_X) {
452
hsl -= groove << 1;
453
for (; child; child = (MFXSevenSegment*)child->getNext()) {
454
child->setHorizontal(hsl);
455
}
456
child = (MFXSevenSegment*)getFirst();
457
}
458
if (options & LAYOUT_FILL_Y) {
459
vsl -= groove << 1;
460
for (; child; child = (MFXSevenSegment*)child->getNext()) {
461
child->setVertical(vsl);
462
}
463
child = (MFXSevenSegment*)getFirst();
464
}
465
for (; child; child = (MFXSevenSegment*)child->getNext()) {
466
child->setText(displayString[i++]);
467
child->setGroove(groove);
468
child->setThickness(st);
469
}
470
} else {
471
for (; child; child = (MFXSevenSegment*)child->getNext()) {
472
child->setText(displayString[i++]);
473
}
474
}
475
}
476
477