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