Eclipse SUMO - Simulation of Urban MObility
FXLCDLabel.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-2020 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 
23 
24 /* =========================================================================
25  * included modules
26  * ======================================================================= */
27 #include <config.h>
28 
29 #include <fxver.h>
30 #define NOMINMAX
31 #include <xincs.h>
32 #undef NOMINMAX
33 #include <fxdefs.h>
34 #include <fx.h>
35 /*
36 #include <FXStream.h>
37 #include <FXString.h>
38 #include <FXSize.h>
39 #include <FXPoint.h>
40 #include <FXRectangle.h>
41 #include <FXRegistry.h>
42 #include <FXHash.h>
43 #include <FXApp.h>
44 #include <FXDCWindow.h>
45 #include <FXLabel.h>
46 #include <FXFrame.h>
47 */
48 using namespace FX;
49 #include "FXSevenSegment.h"
50 #include "FXLCDLabel.h"
51 #include "FXBaseObject.h"
52 
53 using namespace FXEX;
54 namespace FXEX {
55 
56 FXDEFMAP(FXLCDLabel) FXLCDLabelMap[] = {
57  FXMAPFUNC(SEL_PAINT, 0, FXLCDLabel::onPaint),
58  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETVALUE, FXLCDLabel::onCmdSetValue),
59  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETINTVALUE, FXLCDLabel::onCmdSetIntValue),
60  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETREALVALUE, FXLCDLabel::onCmdSetRealValue),
61  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETSTRINGVALUE, FXLCDLabel::onCmdSetStringValue),
62  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETINTVALUE, FXLCDLabel::onCmdGetIntValue),
63  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETREALVALUE, FXLCDLabel::onCmdGetRealValue),
64  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETSTRINGVALUE, FXLCDLabel::onCmdGetStringValue),
65  // FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_TIP,FXLCDLabel::onQueryTip),
66  // FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_HELP,FXLCDLabel::onQueryHelp),
67  FXMAPKEY(FXLCDLabel::ID_SEVENSEGMENT, FXLCDLabel::onRedirectEvent),
68 };
69 FXIMPLEMENT(FXLCDLabel, FXHorizontalFrame, FXLCDLabelMap, ARRAYNUMBER(FXLCDLabelMap))
70 
71 FXLCDLabel::FXLCDLabel(FXComposite* p, FXuint nfig, FXObject* tgt, FXSelector sel, FXuint opts, FXint pl, FXint pr, FXint pt, FXint pb, FXint hs) : FXHorizontalFrame(p, opts, 0, 0, 0, 0, pl, pr, pt, pb, hs, 0) {
72  if (nfig == 0) {
73  fxerror("%s: must have at least one figure.\n", getClassName());
74  }
75  nfigures = nfig;
76  setTarget(tgt);
77  setSelector(sel);
78  enable();
79  for (FXint i = 0; i < nfigures; i++) {
80  new FXSevenSegment(this, this, ID_SEVENSEGMENT, 0, 0, 0, 0);
81  }
82 }
83 
84 FXLCDLabel::~FXLCDLabel() {
85  /*
86  for (FXSevenSegment *child=(FXSevenSegment*)getFirst(); child; child=(FXSevenSegment*)child->getNext()){
87  delete child;
88  }
89  */
90 }
91 
92 // create resources
93 void FXLCDLabel::create() {
94  FXHorizontalFrame::create();
95  for (FXWindow* child = getFirst(); child; child = child->getNext()) {
96  child->create();
97  }
98 }
99 
100 // detach resources
101 void FXLCDLabel::detach() {
102  for (FXWindow* child = getFirst(); child; child = child->getNext()) {
103  child->detach();
104  }
105  FXHorizontalFrame::detach();
106 }
107 
108 // destroy resources
109 void FXLCDLabel::destroy() {
110  for (FXWindow* child = getFirst(); child; child = child->getNext()) {
111  child->destroy();
112  }
113  FXHorizontalFrame::destroy();
114 }
115 
116 // get the foreground color
117 FXColor FXLCDLabel::getFgColor() const {
118  FXSevenSegment* child = (FXSevenSegment*)getFirst();
119  return child->getFgColor();
120 }
121 
122 // set the foreground color
123 void FXLCDLabel::setFgColor(FXColor clr) {
124  FXSevenSegment* child = (FXSevenSegment*)getFirst();
125  if (clr != child->getFgColor()) {
126  for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) {
127  child->setFgColor(clr);
128  }
129  }
130 }
131 
132 // get the background color
133 FXColor FXLCDLabel::getBgColor() const {
134  FXSevenSegment* child = (FXSevenSegment*)getFirst();
135  return child->getBgColor();
136 }
137 
138 // set the background color
139 void FXLCDLabel::setBgColor(FXColor clr) {
140  FXSevenSegment* child = (FXSevenSegment*)getFirst();
141  if (clr != child->getBgColor()) {
142  for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) {
143  child->setBgColor(clr);
144  }
145  }
146 }
147 
148 // set the text
149 void FXLCDLabel::setText(FXString lbl) {
150  if (lbl != label) {
151  label = lbl;
152  recalc();
153  update();
154  }
155 }
156 
157 // get the length of the horizontal segments
158 FXint FXLCDLabel::getHorizontal() const {
159  FXSevenSegment* child = (FXSevenSegment*)getFirst();
160  return child->getHorizontal();
161 }
162 
163 // set the length of the horizontal segments
164 void FXLCDLabel::setHorizontal(const FXint len) {
165  FXSevenSegment* child = (FXSevenSegment*)getFirst();
166  if (len != child->getHorizontal()) {
167  for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) {
168  child->setHorizontal(len);
169  }
170  recalc();
171  update();
172  }
173 }
174 
175 // get the length of the vertical segments
176 FXint FXLCDLabel::getVertical() const {
177  FXSevenSegment* child = (FXSevenSegment*)getFirst();
178  return child->getVertical();
179 }
180 
181 // set the length of the vertical segments
182 void FXLCDLabel::setVertical(const FXint len) {
183  FXSevenSegment* child = (FXSevenSegment*)getFirst();
184  if (len != child->getVertical()) {
185  for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) {
186  child->setVertical(len);
187  }
188  recalc();
189  update();
190  }
191 }
192 
193 // get the width of the segments
194 FXint FXLCDLabel::getThickness() const {
195  FXSevenSegment* child = (FXSevenSegment*)getFirst();
196  return child->getThickness();
197 }
198 
199 // set the width of the segments
200 void FXLCDLabel::setThickness(const FXint width) {
201  FXSevenSegment* child = (FXSevenSegment*)getFirst();
202  if (width != child->getThickness()) {
203  for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) {
204  child->setThickness(width);
205  }
206  recalc();
207  update();
208  }
209 }
210 
211 // get the width of the segments
212 FXint FXLCDLabel::getGroove() const {
213  FXSevenSegment* child = (FXSevenSegment*)getFirst();
214  return child->getGroove();
215 }
216 
217 // set the groove width
218 void FXLCDLabel::setGroove(const FXint width) {
219  FXSevenSegment* child = (FXSevenSegment*)getFirst();
220  if (width != child->getGroove()) {
221  for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) {
222  child->setGroove(width);
223  }
224  recalc();
225  update();
226  }
227 }
228 
229 // Update value from a message
230 long FXLCDLabel::onCmdSetValue(FXObject*, FXSelector, void* ptr) {
231  setText((const FXchar*)ptr);
232  return 1;
233 }
234 
235 // Update value from a message
236 long FXLCDLabel::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) {
237  setText(FXStringVal(*((FXint*)ptr)));
238  return 1;
239 }
240 
241 // Update value from a message
242 long FXLCDLabel::onCmdSetRealValue(FXObject*, FXSelector, void* ptr) {
243  setText(FXStringVal(*((FXdouble*)ptr)));
244  return 1;
245 }
246 
247 // Update value from a message
248 long FXLCDLabel::onCmdSetStringValue(FXObject*, FXSelector, void* ptr) {
249  setText(*((FXString*)ptr));
250  return 1;
251 }
252 
253 // Obtain value from text field
254 long FXLCDLabel::onCmdGetIntValue(FXObject*, FXSelector, void* ptr) {
255  *((FXint*)ptr) = FXIntVal(getText());
256  return 1;
257 }
258 
259 // Obtain value from text field
260 long FXLCDLabel::onCmdGetRealValue(FXObject*, FXSelector, void* ptr) {
261  *((FXdouble*)ptr) = FXDoubleVal(getText());
262  return 1;
263 }
264 
265 // Obtain value from text field
266 long FXLCDLabel::onCmdGetStringValue(FXObject*, FXSelector, void* ptr) {
267  *((FXString*)ptr) = getText();
268  return 1;
269 }
270 
271 // handle paint event
272 long FXLCDLabel::onPaint(FXObject*, FXSelector, void* ptr) {
273  FXEvent* event = (FXEvent*) ptr;
274  FXDCWindow dc(this, event);
275  drawFrame(dc, 0, 0, width, height);
276  FXSevenSegment* child = (FXSevenSegment*)getFirst();
277  // Fill the background
278  dc.setForeground(child->getBgColor());
279  dc.fillRectangle(border, border, width - (border << 1), height - (border << 1));
280  // Draw the current string
281  dc.setForeground(child->getFgColor());
282  drawString(label);
283  return 1;
284 }
285 
286 // draw a specified string/label
287 void FXLCDLabel::drawString(const FXString& lbl) {
288  FXint i = 0;
289  FXString displayString(' ', nfigures);
290  if (options & LCDLABEL_LEADING_ZEROS && (FXIntVal(lbl) || lbl == "0")) {
291  FXString txt = lbl;
292  if (txt[0] == '-') {
293  displayString.replace(0, '-');
294  txt.erase(0);
295  i = 1;
296  }
297  for (; (i + txt.length()) < nfigures; i++) {
298  displayString.replace(i, '0');
299  }
300  displayString.insert(i, txt);
301  } else if (options & JUSTIFY_RIGHT) {
302  for (; (i + lbl.length()) < nfigures; i++) {}
303  displayString.insert(i, lbl);
304  } else {
305  displayString.insert(0, lbl);
306  }
307  displayString.trunc(nfigures);
308  i = 0;
309 
310  // FIXME: at the moment, if we resize the parent widget, we must use integer multiples
311  // of the SevenSegment width. The problem is that it makes the padding on the
312  // RHS look wrong. What we need to do is to extend the horizontal segment width
313  // for the last sevensegment, so as to fill the remaining space.
314  FXSevenSegment* child = (FXSevenSegment*)getFirst();
315  if (options & LAYOUT_FILL) {
316  FXint width = this->width - padleft - padright - (border << 1);
317  FXint height = this->height - padtop - padbottom - (border << 1);
318  hspacing = FXMAX(width, height) / 50;
319  if (hspacing < 1) {
320  hspacing = 1;
321  }
322  FXint hsl = (width - (nfigures - 1) * hspacing) / nfigures;
323  if (hsl < 5) {
324  hsl = 5;
325  }
326  FXint vsl = height >> 1;
327  if (vsl < 5) {
328  vsl = 5;
329  }
330  FXint st = FXMIN(hsl, vsl) / 4;
331  if (st < 1) {
332  st = 1;
333  }
334  FXint groove = st / 4;
335  if (groove < 1) {
336  groove = 1;
337  }
338  if (options & LAYOUT_FILL_X) {
339  hsl -= groove << 1;
340  for (; child; child = (FXSevenSegment*)child->getNext()) {
341  child->setHorizontal(hsl);
342  }
343  child = (FXSevenSegment*)getFirst();
344  }
345  if (options & LAYOUT_FILL_Y) {
346  vsl -= groove << 1;
347  for (; child; child = (FXSevenSegment*)child->getNext()) {
348  child->setVertical(vsl);
349  }
350  child = (FXSevenSegment*)getFirst();
351  }
352  for (; child; child = (FXSevenSegment*)child->getNext()) {
353  child->setText(displayString[i++]);
354  child->setGroove(groove);
355  child->setThickness(st);
356  }
357  } else {
358  for (; child; child = (FXSevenSegment*)child->getNext()) {
359  child->setText(displayString[i++]);
360  }
361  }
362 }
363 
364 // redirect events to main window
365 long FXLCDLabel::onRedirectEvent(FXObject*, FXSelector sel, void* ptr) {
366  FXuint seltype = FXSELTYPE(sel);
367  if (isEnabled()) {
368  if (target) {
369  target->handle(this, FXSEL(seltype, message), ptr);
370  }
371  }
372  return 1;
373 }
374 
375 // return minimum width
376 FXint FXLCDLabel::getDefaultWidth() {
377  return padleft + getFirst()->getDefaultWidth() * nfigures + hspacing * (nfigures - 1) + padright + (border << 1);
378 }
379 
380 // return minimum height
381 FXint FXLCDLabel::getDefaultHeight() {
382  return padtop + getFirst()->getDefaultHeight() + padbottom + (border << 1);
383 }
384 
385 // save resources
386 void FXLCDLabel::save(FXStream& store) const {
387  FXHorizontalFrame::save(store);
388  store << label;
389  store << nfigures;
390 }
391 
392 // load resources
393 void FXLCDLabel::load(FXStream& store) {
394  FXHorizontalFrame::load(store);
395  store >> label;
396  store >> nfigures;
397 }
398 
399 // let parent show tip if appropriate
400 long FXLCDLabel::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) {
401  if (getParent()) {
402  return getParent()->handle(sender, sel, ptr);
403  }
404  return 0;
405 }
406 
407 // let parent show help if appropriate
408 long FXLCDLabel::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) {
409  if (getParent()) {
410  return getParent()->handle(sender, sel, ptr);
411  }
412  return 0;
413 }
414 
415 }
416 
#define FXMAPKEY(key, func)
Definition: FXBaseObject.h:47
FXColor getBgColor() const
FXColor getFgColor() const
void setGroove(const FXint width)
get/set groove thickness
void setText(const FXchar val)
set the text on the display
FXint getHorizontal() const
FXint getThickness() const
void setVertical(const FXint len)
get/set vertical segment length
FXint getVertical() const
void setFgColor(const FXColor clr)
get/set foreground color
void setThickness(const FXint width)
get/set segment thickness
void setHorizontal(const FXint len)
get/set horizontal segment length
void setBgColor(const FXColor clr)
get/set background color
FXint getGroove() const
FXDEFMAP(FXLCDLabel) FXLCDLabelMap[]
@ LCDLABEL_LEADING_ZEROS
Definition: FXLCDLabel.h:39