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