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