Line data Source code
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 122698242 : FXIMPLEMENT(MFXLCDLabel, FXHorizontalFrame, MFXLCDLabelMap, ARRAYNUMBER(MFXLCDLabelMap))
52 :
53 : // ===========================================================================
54 : // method definitions
55 : // ===========================================================================
56 :
57 39990 : 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 39990 : myNFigures(nfig),
60 39990 : myStaticToolTip(staticToolTip) {
61 39990 : if (nfig == 0) {
62 0 : fxerror("%s: must have at least one figure.\n", getClassName());
63 : }
64 : setTarget(tgt);
65 : setSelector(sel);
66 39990 : enable();
67 583854 : for (FXint i = 0; i < myNFigures; i++) {
68 543864 : new MFXSevenSegment(this, this, ID_SEVENSEGMENT, 0, 0, 0, 0);
69 : }
70 39990 : }
71 :
72 :
73 79810 : MFXLCDLabel::~MFXLCDLabel() {
74 : /*
75 : for (MFXSevenSegment *child=(MFXSevenSegment*)getFirst(); child; child=(MFXSevenSegment*)child->getNext()){
76 : delete child;
77 : }
78 : */
79 79810 : }
80 :
81 :
82 : void
83 39990 : MFXLCDLabel::create() {
84 39990 : FXHorizontalFrame::create();
85 583854 : for (FXWindow* child = getFirst(); child; child = child->getNext()) {
86 543864 : child->create();
87 : }
88 39990 : }
89 :
90 :
91 : void
92 0 : MFXLCDLabel::detach() {
93 0 : for (FXWindow* child = getFirst(); child; child = child->getNext()) {
94 0 : child->detach();
95 : }
96 0 : FXHorizontalFrame::detach();
97 0 : }
98 :
99 :
100 : void
101 0 : MFXLCDLabel::destroy() {
102 0 : for (FXWindow* child = getFirst(); child; child = child->getNext()) {
103 0 : child->destroy();
104 : }
105 0 : FXHorizontalFrame::destroy();
106 0 : }
107 :
108 :
109 : FXColor
110 0 : MFXLCDLabel::getFgColor() const {
111 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
112 0 : return child->getFgColor();
113 : }
114 :
115 :
116 : void
117 0 : MFXLCDLabel::setFgColor(FXColor clr) {
118 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
119 0 : if (clr != child->getFgColor()) {
120 0 : for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
121 0 : child->setFgColor(clr);
122 : }
123 : }
124 0 : }
125 :
126 :
127 : FXColor
128 0 : MFXLCDLabel::getBgColor() const {
129 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
130 0 : return child->getBgColor();
131 : }
132 :
133 :
134 : void
135 0 : MFXLCDLabel::setBgColor(FXColor clr) {
136 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
137 0 : if (clr != child->getBgColor()) {
138 0 : for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
139 0 : child->setBgColor(clr);
140 : }
141 : }
142 0 : }
143 :
144 :
145 : void
146 6540598 : MFXLCDLabel::setText(FXString lbl) {
147 6540598 : if (lbl != myLabel) {
148 2922477 : myLabel = lbl;
149 2922477 : recalc();
150 2922477 : update();
151 : }
152 6540598 : }
153 :
154 :
155 : FXString
156 0 : MFXLCDLabel::getText() const {
157 0 : return myLabel;
158 : }
159 :
160 :
161 : FXint
162 0 : MFXLCDLabel::getHorizontal() const {
163 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
164 0 : return child->getHorizontal();
165 : }
166 :
167 :
168 : void
169 39990 : MFXLCDLabel::setHorizontal(const FXint len) {
170 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
171 39990 : if (len != child->getHorizontal()) {
172 583854 : for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
173 543864 : child->setHorizontal(len);
174 : }
175 39990 : recalc();
176 39990 : update();
177 : }
178 39990 : }
179 :
180 :
181 : FXint
182 0 : MFXLCDLabel::getVertical() const {
183 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
184 0 : return child->getVertical();
185 : }
186 :
187 :
188 : void
189 39990 : MFXLCDLabel::setVertical(const FXint len) {
190 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
191 39990 : if (len != child->getVertical()) {
192 583854 : for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
193 543864 : child->setVertical(len);
194 : }
195 39990 : recalc();
196 39990 : update();
197 : }
198 39990 : }
199 :
200 :
201 : FXint
202 0 : MFXLCDLabel::getThickness() const {
203 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
204 0 : return child->getThickness();
205 : }
206 :
207 :
208 : void
209 39990 : MFXLCDLabel::setThickness(const FXint w) {
210 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
211 39990 : if (w != child->getThickness()) {
212 583854 : for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
213 543864 : child->setThickness(w);
214 : }
215 39990 : recalc();
216 39990 : update();
217 : }
218 39990 : }
219 :
220 :
221 : FXint
222 0 : MFXLCDLabel::getGroove() const {
223 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
224 0 : return child->getGroove();
225 : }
226 :
227 :
228 : void
229 39990 : MFXLCDLabel::setGroove(const FXint w) {
230 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
231 39990 : if (w != child->getGroove()) {
232 583854 : for (child = (MFXSevenSegment*)getFirst(); child; child = (MFXSevenSegment*)child->getNext()) {
233 543864 : child->setGroove(w);
234 : }
235 39990 : recalc();
236 39990 : update();
237 : }
238 39990 : }
239 :
240 :
241 : long
242 0 : MFXLCDLabel::onCmdSetValue(FXObject*, FXSelector, void* ptr) {
243 0 : setText((const FXchar*)ptr);
244 0 : return 1;
245 : }
246 :
247 :
248 : long
249 0 : MFXLCDLabel::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) {
250 0 : setText(FXStringVal(*((FXint*)ptr)));
251 0 : return 1;
252 : }
253 :
254 :
255 : long
256 0 : MFXLCDLabel::onCmdSetRealValue(FXObject*, FXSelector, void* ptr) {
257 0 : setText(FXStringVal(*((FXdouble*)ptr)));
258 0 : return 1;
259 : }
260 :
261 :
262 : long
263 0 : MFXLCDLabel::onCmdSetStringValue(FXObject*, FXSelector, void* ptr) {
264 0 : setText(*((FXString*)ptr));
265 0 : return 1;
266 : }
267 :
268 :
269 : long
270 0 : MFXLCDLabel::onCmdGetIntValue(FXObject*, FXSelector, void* ptr) {
271 0 : *((FXint*)ptr) = FXIntVal(getText());
272 0 : return 1;
273 : }
274 :
275 :
276 : long
277 0 : MFXLCDLabel::onCmdGetRealValue(FXObject*, FXSelector, void* ptr) {
278 0 : *((FXdouble*)ptr) = FXDoubleVal(getText());
279 0 : return 1;
280 : }
281 :
282 :
283 : long
284 0 : MFXLCDLabel::onCmdGetStringValue(FXObject*, FXSelector, void* ptr) {
285 0 : *((FXString*)ptr) = getText();
286 0 : return 1;
287 : }
288 :
289 :
290 : long
291 871360 : MFXLCDLabel::onPaint(FXObject*, FXSelector, void* ptr) {
292 : FXEvent* event = (FXEvent*) ptr;
293 871360 : FXDCWindow dc(this, event);
294 871360 : drawFrame(dc, 0, 0, width, height);
295 : MFXSevenSegment* child = (MFXSevenSegment*)getFirst();
296 : // Fill the background
297 871360 : dc.setForeground(child->getBgColor());
298 871360 : dc.fillRectangle(border, border, width - (border << 1), height - (border << 1));
299 : // Draw the current string
300 871360 : dc.setForeground(child->getFgColor());
301 871360 : drawString(myLabel);
302 871360 : return 1;
303 871360 : }
304 :
305 :
306 : long
307 0 : MFXLCDLabel::onEnter(FXObject* obj, FXSelector sel, void* ptr) {
308 : // show static toolTip depending of myToolTipText
309 0 : if (!myToolTipText.empty()) {
310 : // show tip show
311 0 : myStaticToolTip->showStaticToolTip(myToolTipText);
312 : } else {
313 0 : myStaticToolTip->hideStaticToolTip();
314 : }
315 0 : return FXHorizontalFrame::onEnter(obj, sel, ptr);
316 : }
317 :
318 :
319 : long
320 0 : MFXLCDLabel::onLeave(FXObject* obj, FXSelector sel, void* ptr) {
321 : // hide static toolTip
322 0 : myStaticToolTip->hideStaticToolTip();
323 0 : return FXHorizontalFrame::onLeave(obj, sel, ptr);
324 : }
325 :
326 :
327 : long
328 0 : MFXLCDLabel::onMotion(FXObject* sender, FXSelector sel, void* ptr) {
329 : // update static tooltip
330 0 : myStaticToolTip->onUpdate(sender, sel, ptr);
331 0 : return FXHorizontalFrame::onMotion(sender, sel, ptr);
332 : }
333 :
334 :
335 : long
336 121826882 : MFXLCDLabel::onRedirectEvent(FXObject*, FXSelector sel, void* ptr) {
337 : FXuint seltype = FXSELTYPE(sel);
338 121826882 : if (isEnabled()) {
339 121826882 : if (target) {
340 0 : target->handle(this, FXSEL(seltype, message), ptr);
341 : }
342 : }
343 121826882 : return 1;
344 : }
345 :
346 :
347 : FXint
348 1247730 : MFXLCDLabel::getDefaultWidth() {
349 1247730 : return padleft + getFirst()->getDefaultWidth() * myNFigures + hspacing * (myNFigures - 1) + padright + (border << 1);
350 : }
351 :
352 :
353 : FXint
354 1003651 : MFXLCDLabel::getDefaultHeight() {
355 1003651 : return padtop + getFirst()->getDefaultHeight() + padbottom + (border << 1);
356 : }
357 :
358 :
359 : void
360 7998 : MFXLCDLabel::setToolTipText(const FXString& text) {
361 7998 : myToolTipText = text;
362 7998 : }
363 :
364 :
365 : void
366 0 : MFXLCDLabel::save(FXStream& store) const {
367 0 : FXHorizontalFrame::save(store);
368 0 : store << myLabel;
369 0 : store << myNFigures;
370 0 : }
371 :
372 :
373 : void
374 0 : MFXLCDLabel::load(FXStream& store) {
375 0 : FXHorizontalFrame::load(store);
376 0 : store >> myLabel;
377 0 : store >> myNFigures;
378 0 : }
379 :
380 :
381 : long
382 0 : MFXLCDLabel::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) {
383 0 : if (getParent()) {
384 0 : return getParent()->handle(sender, sel, ptr);
385 : }
386 : return 0;
387 : }
388 :
389 :
390 : long
391 0 : MFXLCDLabel::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) {
392 0 : if (getParent()) {
393 0 : return getParent()->handle(sender, sel, ptr);
394 : }
395 : return 0;
396 : }
397 :
398 :
399 : void
400 871360 : MFXLCDLabel::drawString(const FXString& lbl) {
401 : FXint i = 0;
402 871360 : FXString displayString(' ', myNFigures);
403 871360 : if (options & LCDLABEL_LEADING_ZEROS && (FXIntVal(lbl) || lbl == "0")) {
404 0 : FXString txt = lbl;
405 0 : if (txt[0] == '-') {
406 0 : displayString.replace(0, '-');
407 0 : txt.erase(0);
408 : i = 1;
409 : }
410 0 : for (; (i + txt.length()) < myNFigures; i++) {
411 0 : displayString.replace(i, '0');
412 : }
413 0 : displayString.insert(i, txt);
414 871360 : } else if (options & JUSTIFY_RIGHT) {
415 9196124 : for (; (i + lbl.length()) < myNFigures; i++) {}
416 871360 : displayString.insert(i, lbl);
417 : } else {
418 0 : displayString.insert(0, lbl);
419 : }
420 871360 : 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 871360 : if (options & LAYOUT_FILL) {
429 0 : const FXint w = this->width - padleft - padright - (border << 1);
430 0 : const FXint h = this->height - padtop - padbottom - (border << 1);
431 0 : hspacing = FXMAX(w, h) / 50;
432 0 : if (hspacing < 1) {
433 0 : hspacing = 1;
434 : }
435 0 : FXint hsl = (w - (myNFigures - 1) * hspacing) / myNFigures;
436 0 : if (hsl < 5) {
437 : hsl = 5;
438 : }
439 0 : FXint vsl = h >> 1;
440 0 : if (vsl < 5) {
441 : vsl = 5;
442 : }
443 0 : FXint st = FXMIN(hsl, vsl) / 4;
444 : if (st < 1) {
445 : st = 1;
446 : }
447 0 : FXint groove = st / 4;
448 0 : if (groove < 1) {
449 : groove = 1;
450 : }
451 0 : if (options & LAYOUT_FILL_X) {
452 0 : hsl -= groove << 1;
453 0 : for (; child; child = (MFXSevenSegment*)child->getNext()) {
454 0 : child->setHorizontal(hsl);
455 : }
456 : child = (MFXSevenSegment*)getFirst();
457 : }
458 0 : if (options & LAYOUT_FILL_Y) {
459 0 : vsl -= groove << 1;
460 0 : for (; child; child = (MFXSevenSegment*)child->getNext()) {
461 0 : child->setVertical(vsl);
462 : }
463 : child = (MFXSevenSegment*)getFirst();
464 : }
465 0 : for (; child; child = (MFXSevenSegment*)child->getNext()) {
466 0 : child->setText(displayString[i++]);
467 0 : child->setGroove(groove);
468 0 : child->setThickness(st);
469 : }
470 : } else {
471 14813120 : for (; child; child = (MFXSevenSegment*)child->getNext()) {
472 13941760 : child->setText(displayString[i++]);
473 : }
474 : }
475 871360 : }
|