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