SUMO - Simulation of Urban MObility
|
00001 /******************************************************************************** 00002 * * 00003 * LCD text label widget * 00004 * * 00005 ********************************************************************************* 00006 * Copyright (C) 2003 by Mathew Robertson. All Rights Reserved. * 00007 ********************************************************************************* 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * 00021 *********************************************************************************/ 00022 /* ========================================================================= 00023 * included modules 00024 * ======================================================================= */ 00025 #ifdef _MSC_VER 00026 #include <windows_config.h> 00027 #else 00028 #include <config.h> 00029 #endif 00030 00031 #include <fxver.h> 00032 #include <xincs.h> 00033 #include <fxdefs.h> 00034 #include <fx.h> 00035 /* 00036 #include <FXStream.h> 00037 #include <FXString.h> 00038 #include <FXSize.h> 00039 #include <FXPoint.h> 00040 #include <FXRectangle.h> 00041 #include <FXRegistry.h> 00042 #include <FXHash.h> 00043 #include <FXApp.h> 00044 #include <FXDCWindow.h> 00045 #include <FXLabel.h> 00046 #include <FXFrame.h> 00047 */ 00048 using namespace FX; 00049 #include "FXSevenSegment.h" 00050 #include "FXLCDLabel.h" 00051 #include "FXBaseObject.h" 00052 00053 #ifdef CHECK_MEMORY_LEAKS 00054 #include <foreign/nvwa/debug_new.h> 00055 #endif // CHECK_MEMORY_LEAKS 00056 using namespace FXEX; 00057 namespace FXEX { 00058 00059 FXDEFMAP(FXLCDLabel) FXLCDLabelMap[] = { 00060 FXMAPFUNC(SEL_PAINT, 0, FXLCDLabel::onPaint), 00061 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETVALUE, FXLCDLabel::onCmdSetValue), 00062 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETINTVALUE, FXLCDLabel::onCmdSetIntValue), 00063 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETREALVALUE, FXLCDLabel::onCmdSetRealValue), 00064 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETSTRINGVALUE, FXLCDLabel::onCmdSetStringValue), 00065 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETINTVALUE, FXLCDLabel::onCmdGetIntValue), 00066 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETREALVALUE, FXLCDLabel::onCmdGetRealValue), 00067 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETSTRINGVALUE, FXLCDLabel::onCmdGetStringValue), 00068 // FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_TIP,FXLCDLabel::onQueryTip), 00069 // FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_HELP,FXLCDLabel::onQueryHelp), 00070 FXMAPKEY(FXLCDLabel::ID_SEVENSEGMENT, FXLCDLabel::onRedirectEvent), 00071 }; 00072 FXIMPLEMENT(FXLCDLabel, FXHorizontalFrame, FXLCDLabelMap, ARRAYNUMBER(FXLCDLabelMap)) 00073 00074 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) { 00075 if (nfig == 0) { 00076 fxerror("%s: must have at least one figure.\n", getClassName()); 00077 } 00078 nfigures = nfig; 00079 setTarget(tgt); 00080 setSelector(sel); 00081 enable(); 00082 for (FXint i = 0; i < nfigures; i++) { 00083 new FXSevenSegment(this, this, ID_SEVENSEGMENT, 0, 0, 0, 0); 00084 } 00085 } 00086 00087 FXLCDLabel::~FXLCDLabel() { 00088 /* 00089 for (FXSevenSegment *child=(FXSevenSegment*)getFirst(); child; child=(FXSevenSegment*)child->getNext()){ 00090 delete child; 00091 } 00092 */ 00093 } 00094 00095 // create resources 00096 void FXLCDLabel::create() { 00097 FXHorizontalFrame::create(); 00098 for (FXWindow* child = getFirst(); child; child = child->getNext()) { 00099 child->create(); 00100 } 00101 } 00102 00103 // detach resources 00104 void FXLCDLabel::detach() { 00105 for (FXWindow* child = getFirst(); child; child = child->getNext()) { 00106 child->detach(); 00107 } 00108 FXHorizontalFrame::detach(); 00109 } 00110 00111 // destroy resources 00112 void FXLCDLabel::destroy() { 00113 for (FXWindow* child = getFirst(); child; child = child->getNext()) { 00114 child->destroy(); 00115 } 00116 FXHorizontalFrame::destroy(); 00117 } 00118 00119 // get the foreground color 00120 FXColor FXLCDLabel::getFgColor() const { 00121 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00122 return child->getFgColor(); 00123 } 00124 00125 // set the foreground color 00126 void FXLCDLabel::setFgColor(FXColor clr) { 00127 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00128 if (clr != child->getFgColor()) { 00129 for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) { 00130 child->setFgColor(clr); 00131 } 00132 } 00133 } 00134 00135 // get the background color 00136 FXColor FXLCDLabel::getBgColor() const { 00137 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00138 return child->getBgColor(); 00139 } 00140 00141 // set the background color 00142 void FXLCDLabel::setBgColor(FXColor clr) { 00143 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00144 if (clr != child->getBgColor()) { 00145 for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) { 00146 child->setBgColor(clr); 00147 } 00148 } 00149 } 00150 00151 // set the text 00152 void FXLCDLabel::setText(FXString lbl) { 00153 if (lbl != label) { 00154 label = lbl; 00155 recalc(); 00156 update(); 00157 } 00158 } 00159 00160 // get the length of the horizontal segments 00161 FXint FXLCDLabel::getHorizontal() const { 00162 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00163 return child->getHorizontal(); 00164 } 00165 00166 // set the length of the horizontal segments 00167 void FXLCDLabel::setHorizontal(const FXint len) { 00168 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00169 if (len != child->getHorizontal()) { 00170 for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) { 00171 child->setHorizontal(len); 00172 } 00173 recalc(); 00174 update(); 00175 } 00176 } 00177 00178 // get the length of the vertical segments 00179 FXint FXLCDLabel::getVertical() const { 00180 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00181 return child->getVertical(); 00182 } 00183 00184 // set the length of the vertical segments 00185 void FXLCDLabel::setVertical(const FXint len) { 00186 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00187 if (len != child->getVertical()) { 00188 for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) { 00189 child->setVertical(len); 00190 } 00191 recalc(); 00192 update(); 00193 } 00194 } 00195 00196 // get the width of the segments 00197 FXint FXLCDLabel::getThickness() const { 00198 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00199 return child->getThickness(); 00200 } 00201 00202 // set the width of the segments 00203 void FXLCDLabel::setThickness(const FXint width) { 00204 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00205 if (width != child->getThickness()) { 00206 for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) { 00207 child->setThickness(width); 00208 } 00209 recalc(); 00210 update(); 00211 } 00212 } 00213 00214 // get the width of the segments 00215 FXint FXLCDLabel::getGroove() const { 00216 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00217 return child->getGroove(); 00218 } 00219 00220 // set the groove width 00221 void FXLCDLabel::setGroove(const FXint width) { 00222 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00223 if (width != child->getGroove()) { 00224 for (child = (FXSevenSegment*)getFirst(); child; child = (FXSevenSegment*)child->getNext()) { 00225 child->setGroove(width); 00226 } 00227 recalc(); 00228 update(); 00229 } 00230 } 00231 00232 // Update value from a message 00233 long FXLCDLabel::onCmdSetValue(FXObject*, FXSelector, void* ptr) { 00234 setText((const FXchar*)ptr); 00235 return 1; 00236 } 00237 00238 // Update value from a message 00239 long FXLCDLabel::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) { 00240 setText(FXStringVal(*((FXint*)ptr))); 00241 return 1; 00242 } 00243 00244 // Update value from a message 00245 long FXLCDLabel::onCmdSetRealValue(FXObject*, FXSelector, void* ptr) { 00246 setText(FXStringVal(*((FXdouble*)ptr))); 00247 return 1; 00248 } 00249 00250 // Update value from a message 00251 long FXLCDLabel::onCmdSetStringValue(FXObject*, FXSelector, void* ptr) { 00252 setText(*((FXString*)ptr)); 00253 return 1; 00254 } 00255 00256 // Obtain value from text field 00257 long FXLCDLabel::onCmdGetIntValue(FXObject*, FXSelector, void* ptr) { 00258 *((FXint*)ptr) = FXIntVal(getText()); 00259 return 1; 00260 } 00261 00262 // Obtain value from text field 00263 long FXLCDLabel::onCmdGetRealValue(FXObject*, FXSelector, void* ptr) { 00264 *((FXdouble*)ptr) = FXDoubleVal(getText()); 00265 return 1; 00266 } 00267 00268 // Obtain value from text field 00269 long FXLCDLabel::onCmdGetStringValue(FXObject*, FXSelector, void* ptr) { 00270 *((FXString*)ptr) = getText(); 00271 return 1; 00272 } 00273 00274 // handle paint event 00275 long FXLCDLabel::onPaint(FXObject*, FXSelector, void* ptr) { 00276 FXEvent* event = (FXEvent*) ptr; 00277 FXDCWindow dc(this, event); 00278 drawFrame(dc, 0, 0, width, height); 00279 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00280 // Fill the background 00281 dc.setForeground(child->getBgColor()); 00282 dc.fillRectangle(border, border, width - (border << 1), height - (border << 1)); 00283 // Draw the current string 00284 dc.setForeground(child->getFgColor()); 00285 drawString(label); 00286 return 1; 00287 } 00288 00289 // draw a specified string/label 00290 void FXLCDLabel::drawString(const FXString& lbl) { 00291 FXint i = 0; 00292 FXString displayString(' ', nfigures); 00293 if (options & LCDLABEL_LEADING_ZEROS && (FXIntVal(lbl) || lbl == "0")) { 00294 FXString txt = lbl; 00295 if (txt[0] == '-') { 00296 displayString.replace(0, '-'); 00297 txt.erase(0); 00298 i = 1; 00299 } 00300 for (; (i + txt.length()) < nfigures; i++) { 00301 displayString.replace(i, '0'); 00302 } 00303 displayString.insert(i, txt); 00304 } else if (options & JUSTIFY_RIGHT) { 00305 for (; (i + lbl.length()) < nfigures; i++) {} 00306 displayString.insert(i, lbl); 00307 } else { 00308 displayString.insert(0, lbl); 00309 } 00310 displayString.trunc(nfigures); 00311 i = 0; 00312 00313 // FIXME: at the moment, if we resize the parent widget, we must use integer multiples 00314 // of the SevenSegment width. The problem is that it makes the padding on the 00315 // RHS look wrong. What we need to do is to extend the horizontal segment width 00316 // for the last sevensegment, so as to fill the remaining space. 00317 FXSevenSegment* child = (FXSevenSegment*)getFirst(); 00318 if (options & LAYOUT_FILL) { 00319 FXint width = this->width - padleft - padright - (border << 1); 00320 FXint height = this->height - padtop - padbottom - (border << 1); 00321 hspacing = FXMAX(width, height) / 50; 00322 if (hspacing < 1) { 00323 hspacing = 1; 00324 } 00325 FXint hsl = (width - (nfigures - 1) * hspacing) / nfigures; 00326 if (hsl < 5) { 00327 hsl = 5; 00328 } 00329 FXint vsl = height >> 1; 00330 if (vsl < 5) { 00331 vsl = 5; 00332 } 00333 FXint st = FXMIN(hsl, vsl) / 4; 00334 if (st < 1) { 00335 st = 1; 00336 } 00337 FXint groove = st / 4; 00338 if (groove < 1) { 00339 groove = 1; 00340 } 00341 if (options & LAYOUT_FILL_X) { 00342 hsl -= groove << 1; 00343 for (; child; child = (FXSevenSegment*)child->getNext()) { 00344 child->setHorizontal(hsl); 00345 } 00346 child = (FXSevenSegment*)getFirst(); 00347 } 00348 if (options & LAYOUT_FILL_Y) { 00349 vsl -= groove << 1; 00350 for (; child; child = (FXSevenSegment*)child->getNext()) { 00351 child->setVertical(vsl); 00352 } 00353 child = (FXSevenSegment*)getFirst(); 00354 } 00355 for (; child; child = (FXSevenSegment*)child->getNext()) { 00356 child->setText(displayString[i++]); 00357 child->setGroove(groove); 00358 child->setThickness(st); 00359 } 00360 } else { 00361 for (; child; child = (FXSevenSegment*)child->getNext()) { 00362 child->setText(displayString[i++]); 00363 } 00364 } 00365 } 00366 00367 // redirect events to main window 00368 long FXLCDLabel::onRedirectEvent(FXObject*, FXSelector sel, void* ptr) { 00369 FXuint seltype = FXSELTYPE(sel); 00370 if (isEnabled()) { 00371 if (target) { 00372 target->handle(this, FXSEL(seltype, message), ptr); 00373 } 00374 } 00375 return 1; 00376 } 00377 00378 // return minimum width 00379 FXint FXLCDLabel::getDefaultWidth() { 00380 return padleft + getFirst()->getDefaultWidth() * nfigures + hspacing * (nfigures - 1) + padright + (border << 1); 00381 } 00382 00383 // return minimum height 00384 FXint FXLCDLabel::getDefaultHeight() { 00385 return padtop + getFirst()->getDefaultHeight() + padbottom + (border << 1); 00386 } 00387 00388 // save resources 00389 void FXLCDLabel::save(FXStream& store) const { 00390 FXHorizontalFrame::save(store); 00391 store << label; 00392 store << nfigures; 00393 } 00394 00395 // load resources 00396 void FXLCDLabel::load(FXStream& store) { 00397 FXHorizontalFrame::load(store); 00398 store >> label; 00399 store >> nfigures; 00400 } 00401 00402 // let parent show tip if appropriate 00403 long FXLCDLabel::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) { 00404 if (getParent()) { 00405 return getParent()->handle(sender, sel, ptr); 00406 } 00407 return 0; 00408 } 00409 00410 // let parent show help if appropriate 00411 long FXLCDLabel::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) { 00412 if (getParent()) { 00413 return getParent()->handle(sender, sel, ptr); 00414 } 00415 return 0; 00416 } 00417 00418 } 00419