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