|
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