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