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 /********************************************************************************
2 * *
3 * LCD text label widget *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2003 by Mathew Robertson. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 *********************************************************************************/
22 /* =========================================================================
23  * included modules
24  * ======================================================================= */
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <fxver.h>
32 #include <xincs.h>
33 #include <fxdefs.h>
34 #include <fx.h>
35 /*
36 #include <FXStream.h>
37 #include <FXString.h>
38 #include <FXSize.h>
39 #include <FXPoint.h>
40 #include <FXRectangle.h>
41 #include <FXRegistry.h>
42 #include <FXHash.h>
43 #include <FXApp.h>
44 #include <FXDCWindow.h>
45 #include <FXLabel.h>
46 #include <FXFrame.h>
47 */
48 using namespace FX;
49 #include "FXSevenSegment.h"
50 #include "FXLCDLabel.h"
51 #include "FXBaseObject.h"
52 
53 #ifdef CHECK_MEMORY_LEAKS
54 #include <foreign/nvwa/debug_new.h>
55 #endif // CHECK_MEMORY_LEAKS
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) {
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