FXSevenSegment.cpp

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                  Seven segment display 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 */
00046 using namespace FX;
00047 #include "FXSevenSegment.h"
00048 
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052 using namespace FXEX;
00053 namespace FXEX {
00054 
00055 /* note: this class may change into FXLCDsegment, so as to support 7 or 14 segment display */
00056 #define ASCII_ZERO 48
00057 
00058 // map
00059 FXDEFMAP(FXSevenSegment) FXSevenSegmentMap[]={
00060     FXMAPFUNC(SEL_PAINT,0,FXSevenSegment::onPaint),
00061     FXMAPFUNC(SEL_COMMAND,FXWindow::ID_SETVALUE,FXSevenSegment::onCmdSetValue),
00062     FXMAPFUNC(SEL_COMMAND,FXWindow::ID_SETINTVALUE,FXSevenSegment::onCmdSetIntValue),
00063     FXMAPFUNC(SEL_COMMAND,FXWindow::ID_GETINTVALUE,FXSevenSegment::onCmdGetIntValue),
00064     FXMAPFUNC(SEL_COMMAND,FXWindow::ID_SETSTRINGVALUE,FXSevenSegment::onCmdSetStringValue),
00065     FXMAPFUNC(SEL_COMMAND,FXWindow::ID_GETSTRINGVALUE,FXSevenSegment::onCmdGetStringValue),
00066     //  FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_TIP,FXSevenSegment::onQueryTip),
00067     //  FXMAPFUNC(SEL_UPDATE,FXWindow::ID_QUERY_HELP,FXSevenSegment::onQueryHelp),
00068 };
00069 FXIMPLEMENT(FXSevenSegment,FXFrame,FXSevenSegmentMap,ARRAYNUMBER(FXSevenSegmentMap))
00070 
00071 // ctor
00072 FXSevenSegment::FXSevenSegment(FXComposite* p,FXObject *tgt,FXSelector sel,FXuint opts,FXint pl,FXint pr,FXint pt,FXint pb) : FXFrame(p,opts,0,0,0,0,pl,pr,pt,pb),value(' '),fgcolor(FXRGB(0,255,0)),bgcolor(FXRGB(0,0,0)),hsl(8),vsl(8),st(3),groove(1) {
00073     setTarget(tgt);
00074     setSelector(sel);
00075     enable();
00076 }
00077 
00078 // minimum width
00079 FXint FXSevenSegment::getDefaultWidth() {
00080     return padleft + (groove<<1) + hsl + padright + (border<<1);
00081 }
00082 
00083 // minimum height
00084 FXint FXSevenSegment::getDefaultHeight() {
00085     return padtop + (groove<<2) + (vsl<<1) + padbottom + (border<<1);
00086 }
00087 
00088 // set value on widget
00089 void FXSevenSegment::setText(FXchar val) {
00090     if (FXString(val,1).upper() != FXString(value,1).upper()) {
00091         value=val;
00092         recalc();
00093         update();
00094     }
00095 }
00096 
00097 // set foreground color
00098 void FXSevenSegment::setFgColor(const FXColor clr) {
00099     if (fgcolor!=clr) {
00100         fgcolor=clr;
00101         recalc();
00102         update();
00103     }
00104 }
00105 
00106 // set backgound color
00107 void FXSevenSegment::setBgColor(const FXColor clr) {
00108     if (bgcolor!=clr) {
00109         bgcolor=clr;
00110         recalc();
00111         update();
00112     }
00113 }
00114 
00115 // set horizontal segment length
00116 void FXSevenSegment::setHorizontal(const FXint len) {
00117     if (len!=hsl) {
00118         hsl=len;
00119         checkSize();
00120         recalc();
00121         update();
00122     }
00123 }
00124 
00125 // set vertical segment length
00126 void FXSevenSegment::setVertical(const FXint len) {
00127     if (len!=vsl) {
00128         vsl=len;
00129         checkSize();
00130         recalc();
00131         update();
00132     }
00133 }
00134 
00135 // set segment thickness
00136 void FXSevenSegment::setThickness(const FXint width) {
00137     if (width!=st) {
00138         st=width;
00139         checkSize();
00140         recalc();
00141         update();
00142     }
00143 }
00144 
00145 // set groove thickness
00146 void FXSevenSegment::setGroove(const FXint width) {
00147     if (width!=groove) {
00148         groove=width;
00149         checkSize();
00150         recalc();
00151         update();
00152     }
00153 }
00154 
00155 // draw/redraw object
00156 long FXSevenSegment::onPaint(FXObject*,FXSelector,void *ptr) {
00157     FXEvent *event= (FXEvent*) ptr;
00158     FXDCWindow dc(this, event);
00159     drawFrame(dc,0,0,width,height);
00160     dc.setForeground(bgcolor);
00161     dc.fillRectangle(border, border, width-(border<<1), height-(border<<1));
00162     dc.setForeground(fgcolor);
00163     drawFigure(dc,value);
00164     return 1;
00165 }
00166 
00167 // set from value
00168 long FXSevenSegment::onCmdSetValue(FXObject*,FXSelector,void *ptr) {
00169     FXchar *c=(FXchar*)ptr;
00170     if (c[0] != '\0') setText(c[0]);
00171     return 1;
00172 }
00173 
00174 // get value from int
00175 long FXSevenSegment::onCmdGetIntValue(FXObject *sender,FXSelector,void*) {
00176     FXint i=value-ASCII_ZERO;
00177     if (i < 0) i=0;
00178     if (i > 9) i=9;
00179     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&i);
00180     return 1;
00181 }
00182 
00183 // set from int value
00184 long FXSevenSegment::onCmdSetIntValue(FXObject*,FXSelector,void *ptr) {
00185     FXint i=*((FXint*)ptr);
00186     if (i < 0) i=0;
00187     if (i > 9) i=9;
00188     setText((FXchar)(i+ASCII_ZERO));
00189     return 1;
00190 }
00191 
00192 // get value from string
00193 long FXSevenSegment::onCmdGetStringValue(FXObject *sender,FXSelector,void*) {
00194     FXString s(value,1);
00195     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE),(void*)&s);
00196     return 1;
00197 }
00198 
00199 // set from string value
00200 long FXSevenSegment::onCmdSetStringValue(FXObject*,FXSelector,void *ptr) {
00201     FXString *s=(FXString*)ptr;
00202     if ((*s).length()) setText((*s)[0]);
00203     return 1;
00204 }
00205 
00206 // draw the specific character - figure out which segments to draw
00207 void FXSevenSegment::drawFigure(FXDCWindow &dc,FXchar figure) {
00208     switch (figure) {
00209     case ' ' :
00210         drawSegments(dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE);
00211         break;
00212     case '(' :
00213         drawSegments(dc, TRUE ,TRUE ,FALSE,FALSE,TRUE ,FALSE,TRUE);
00214         break;
00215     case ')' :
00216         drawSegments(dc, TRUE ,FALSE,TRUE ,FALSE,FALSE,TRUE ,TRUE);
00217         break;
00218     case '[' :
00219         drawSegments(dc, TRUE ,TRUE ,FALSE,FALSE,TRUE ,FALSE,TRUE);
00220         break;
00221     case ']' :
00222         drawSegments(dc, TRUE ,FALSE,TRUE ,FALSE,FALSE,TRUE ,TRUE);
00223         break;
00224     case '=' :
00225         drawSegments(dc, FALSE,FALSE,FALSE,TRUE ,FALSE,FALSE,TRUE);
00226         break;
00227 //    case '+' : drawSegments (dc, FALSE,FALSE,FALSE,TRUE ,FALSE,FALSE,FALSE); break;
00228     case '-' :
00229         drawSegments(dc, FALSE,FALSE,FALSE,TRUE ,FALSE,FALSE,FALSE);
00230         break;
00231     case '_' :
00232         drawSegments(dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE);
00233         break;
00234     case '0' :
00235         drawSegments(dc, TRUE ,TRUE ,TRUE ,FALSE,TRUE ,TRUE ,TRUE);
00236         break;
00237     case '1' :
00238         drawSegments(dc, FALSE,FALSE,TRUE ,FALSE,FALSE,TRUE ,FALSE);
00239         break;
00240     case '2' :
00241         drawSegments(dc, TRUE ,FALSE,TRUE ,TRUE ,TRUE ,FALSE,TRUE);
00242         break;
00243     case '3' :
00244         drawSegments(dc, TRUE ,FALSE,TRUE ,TRUE ,FALSE,TRUE ,TRUE);
00245         break;
00246     case '4' :
00247         drawSegments(dc, FALSE,TRUE ,TRUE ,TRUE ,FALSE,TRUE ,FALSE);
00248         break;
00249     case '5' :
00250         drawSegments(dc, TRUE ,TRUE ,FALSE,TRUE ,FALSE,TRUE ,TRUE);
00251         break;
00252     case '6' :
00253         drawSegments(dc, TRUE ,TRUE ,FALSE,TRUE ,TRUE ,TRUE ,TRUE);
00254         break;
00255     case '7' :
00256         drawSegments(dc, TRUE ,FALSE,TRUE ,FALSE,FALSE,TRUE ,FALSE);
00257         break;
00258     case '8' :
00259         drawSegments(dc, TRUE ,TRUE ,TRUE ,TRUE ,TRUE ,TRUE ,TRUE);
00260         break;
00261     case '9' :
00262         drawSegments(dc, TRUE ,TRUE ,TRUE ,TRUE ,FALSE,TRUE ,TRUE);
00263         break;
00264     case 'a' :
00265     case 'A' :
00266         drawSegments(dc, TRUE ,TRUE ,TRUE ,TRUE ,TRUE ,TRUE ,FALSE);
00267         break;
00268     case 'b' :
00269     case 'B' :
00270         drawSegments(dc, FALSE,TRUE ,FALSE,TRUE ,TRUE ,TRUE ,TRUE);
00271         break;
00272     case 'c' :
00273     case 'C' :
00274         drawSegments(dc, TRUE ,TRUE ,FALSE,FALSE,TRUE ,FALSE,TRUE);
00275         break;
00276     case 'd' :
00277     case 'D' :
00278         drawSegments(dc, FALSE,FALSE,TRUE ,TRUE ,TRUE ,TRUE ,TRUE);
00279         break;
00280     case 'e' :
00281     case 'E' :
00282         drawSegments(dc, TRUE ,TRUE ,FALSE,TRUE ,TRUE ,FALSE,TRUE);
00283         break;
00284     case 'f' :
00285     case 'F' :
00286         drawSegments(dc, TRUE ,TRUE ,FALSE,TRUE ,TRUE ,FALSE,FALSE);
00287         break;
00288     case 'g' :
00289     case 'G' :
00290         drawSegments(dc, TRUE ,TRUE ,FALSE,FALSE,TRUE ,TRUE ,TRUE);
00291         break;
00292     case 'h' :
00293     case 'H' :
00294         drawSegments(dc, FALSE,TRUE ,FALSE,TRUE ,TRUE ,TRUE ,FALSE);
00295         break;
00296     case 'i' :
00297     case 'I' :
00298         drawSegments(dc, FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,FALSE);
00299         break;
00300     case 'j' :
00301     case 'J' :
00302         drawSegments(dc, FALSE,FALSE,TRUE ,FALSE,TRUE ,TRUE ,TRUE);
00303         break;
00304 //    case 'k' :
00305 //    case 'k' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00306     case 'l' :
00307     case 'L' :
00308         drawSegments(dc, FALSE,TRUE ,FALSE,FALSE,TRUE ,FALSE,TRUE);
00309         break;
00310 //    case 'm' :
00311 //    case 'M' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00312     case 'n' :
00313     case 'N' :
00314         drawSegments(dc, FALSE,FALSE,FALSE,TRUE ,TRUE ,TRUE ,FALSE);
00315         break;
00316     case 'o' :
00317     case 'O' :
00318         drawSegments(dc, TRUE ,TRUE ,TRUE ,FALSE,TRUE ,TRUE ,TRUE);
00319         break;
00320     case 'p' :
00321     case 'P' :
00322         drawSegments(dc, TRUE ,TRUE ,TRUE ,TRUE ,TRUE ,FALSE,FALSE);
00323         break;
00324     case 'q' :
00325     case 'Q' :
00326         drawSegments(dc, TRUE ,TRUE ,TRUE ,TRUE ,FALSE,TRUE ,FALSE);
00327         break;
00328     case 'r' :
00329     case 'R' :
00330         drawSegments(dc, FALSE,FALSE,FALSE,TRUE ,TRUE ,FALSE,FALSE);
00331         break;
00332     case 's' :
00333     case 'S' :
00334         drawSegments(dc, TRUE ,TRUE ,FALSE,TRUE ,FALSE,TRUE ,TRUE);
00335         break;
00336     case 't' :
00337     case 'T' :
00338         drawSegments(dc, FALSE,TRUE ,FALSE,TRUE ,TRUE ,FALSE,FALSE);
00339         break;
00340     case 'u' :
00341     case 'U' :
00342         drawSegments(dc, FALSE,TRUE ,TRUE ,FALSE,TRUE ,TRUE ,TRUE);
00343         break;
00344 //    case 'v' :
00345 //    case 'V' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00346 //    case 'w' :
00347 //    case 'W' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00348     case 'x' :
00349     case 'X' :
00350         drawSegments(dc, FALSE,TRUE ,TRUE ,TRUE ,TRUE ,TRUE ,FALSE);
00351         break;
00352     case 'y' :
00353     case 'Y' :
00354         drawSegments(dc, FALSE,TRUE ,TRUE ,TRUE ,FALSE,TRUE ,TRUE);
00355         break;
00356 //    case 'z' :
00357 //    case 'Z' :
00358     default  :
00359         fxerror("FXSevenSegment doesnt support: %c\n",figure);
00360     }
00361 }
00362 
00363 // validates the sizes of the segment dimensions
00364 void FXSevenSegment::checkSize() {
00365     if (hsl<3) {
00366         hsl=3;
00367         st=1;
00368     }
00369     if (vsl<3) {
00370         vsl=3;
00371         st=1;
00372     }
00373     if (st<1) st=1;
00374     if (hsl<(st<<1)) hsl=(st<<1)+1;
00375     if (vsl<(st<<1)) vsl=(st<<1)+1;
00376     if (hsl<8 || vsl<8) groove=2;
00377     if (hsl<1 || vsl<3 || st<3) groove=1;
00378     if (groove>=st) groove=st-1;
00379 }
00380 
00381 // draw each segment, into the available drawing space
00382 // if widget is resizeable, caculate new sizes for length/width/grove of each segment
00383 void FXSevenSegment::drawSegments(FXDCWindow &dc,FXbool s1,FXbool s2,FXbool s3,FXbool s4,FXbool s5,FXbool s6,FXbool s7) {
00384     FXint sx=border+padleft, sy=border+padtop;
00385     FXint x,y;
00386     if (options&LAYOUT_FILL) {
00387         if (options&LAYOUT_FILL_X) {
00388             hsl=width-padleft-padright-(border<<1);
00389             if (hsl<4) hsl=4;
00390         }
00391         if (options&LAYOUT_FILL_Y) {
00392             vsl=(height-padtop-padbottom-(border<<1))>>1;
00393             if (vsl<4) vsl=4;
00394         }
00395         st=FXMIN(hsl,vsl)/4;
00396         groove=st/4;
00397         if (st<1) st=1;
00398         if (groove<1) groove=1;
00399         if (options&LAYOUT_FILL_X) hsl-=groove<<1;
00400         if (options&LAYOUT_FILL_Y) vsl-=groove<<1;
00401     }
00402     if (s1) {
00403         x=sx+groove;
00404         y=sy;
00405         drawTopSegment(dc,x,y);
00406     }
00407     if (s2) {
00408         x=sx;
00409         y=sy+groove;
00410         drawLeftTopSegment(dc,x,y);
00411     }
00412     if (s3) {
00413         x=sx+groove+hsl-st+groove;
00414         y=sy+groove;
00415         drawRightTopSegment(dc,x,y);
00416     }
00417     if (s4) {
00418         x=sx+groove;
00419         y=sy+groove+vsl-(st>>1)+groove;
00420         drawMiddleSegment(dc,x,y);
00421     }
00422     if (s5) {
00423         x=sx;
00424         y=sy+(groove<<1)+vsl+groove;
00425         drawLeftBottomSegment(dc,x,y);
00426     }
00427     if (s6) {
00428         x=sx+groove+hsl-st+groove;
00429         y=sy+(groove<<1)+vsl+groove;
00430         drawRightBottomSegment(dc,x,y);
00431     }
00432     if (s7) {
00433         x=sx+groove;
00434         y=sy+(groove<<1)+vsl+groove+vsl+groove-st;
00435         drawBottomSegment(dc,x,y);
00436     }
00437 }
00438 
00439 void FXSevenSegment::drawTopSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00440     FXPoint points[4];
00441     points[0].x=x;
00442     points[0].y=y;
00443     points[1].x=x+hsl;
00444     points[1].y=y;
00445     points[2].x=x+hsl-st;
00446     points[2].y=y+st;
00447     points[3].x=x+st;
00448     points[3].y=y+st;
00449     dc.fillPolygon(points,4);
00450 }
00451 
00452 void FXSevenSegment::drawLeftTopSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00453     FXPoint points[4];
00454     points[0].x=x;
00455     points[0].y=y;
00456     points[1].x=x+st;
00457     points[1].y=y+st;
00458     points[2].x=x+st;
00459     points[2].y=y+vsl-(st>>1);
00460     points[3].x=x;
00461     points[3].y=y+vsl;
00462     dc.fillPolygon(points,4);
00463 }
00464 
00465 void FXSevenSegment::drawRightTopSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00466     FXPoint points[4];
00467     points[0].x=x+st;
00468     points[0].y=y;
00469     points[1].x=x+st;
00470     points[1].y=y+vsl;
00471     points[2].x=x;
00472     points[2].y=y+vsl-(st>>1);
00473     points[3].x=x;
00474     points[3].y=y+st;
00475     dc.fillPolygon(points,4);
00476 }
00477 
00478 void FXSevenSegment::drawMiddleSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00479     FXPoint points[6];
00480     points[0].x=x+st;
00481     points[0].y=y;
00482     points[1].x=x+hsl-st;
00483     points[1].y=y;
00484     points[2].x=x+hsl;
00485     points[2].y=y+(st>>1);
00486     points[3].x=x+hsl-st;
00487     points[3].y=y+st;
00488     points[4].x=x+st;
00489     points[4].y=y+st;
00490     points[5].x=x;
00491     points[5].y=y+(st>>1);
00492     dc.fillPolygon(points,6);
00493 }
00494 
00495 void FXSevenSegment::drawLeftBottomSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00496     FXPoint points[4];
00497     points[0].x=x;
00498     points[0].y=y;
00499     points[1].x=x+st;
00500     points[1].y=y+(st>>1);
00501     points[2].x=x+st;
00502     points[2].y=y+vsl-st;
00503     points[3].x=x;
00504     points[3].y=y+vsl;
00505     dc.fillPolygon(points,4);
00506 }
00507 
00508 void FXSevenSegment::drawRightBottomSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00509     FXPoint points[4];
00510     points[0].x=x+st;
00511     points[0].y=y;
00512     points[1].x=x+st;
00513     points[1].y=y+vsl;
00514     points[2].x=x;
00515     points[2].y=y+vsl-st;
00516     points[3].x=x;
00517     points[3].y=y+(st>>1);
00518     dc.fillPolygon(points,4);
00519 }
00520 
00521 void FXSevenSegment::drawBottomSegment(FXDCWindow &dc,FXshort x,FXshort y) {
00522     FXPoint points[4];
00523     points[0].x=x+st;
00524     points[0].y=y;
00525     points[1].x=x+hsl-st;
00526     points[1].y=y;
00527     points[2].x=x+hsl;
00528     points[2].y=y+st;
00529     points[3].x=x;
00530     points[3].y=y+st;
00531     dc.fillPolygon(points,4);
00532 }
00533 
00534 void FXSevenSegment::save(FXStream &store) const {
00535     FXFrame::save(store);
00536     store << value;
00537     store << fgcolor;
00538     store << bgcolor;
00539     store << hsl;
00540     store << vsl;
00541     store << st;
00542     store << groove;
00543 }
00544 
00545 void FXSevenSegment::load(FXStream &store) {
00546     FXFrame::load(store);
00547     store >> value;
00548     store >> fgcolor;
00549     store >> bgcolor;
00550     store >> hsl;
00551     store >> vsl;
00552     store >> st;
00553     store >> groove;
00554 }
00555 
00556 // let parent show tip if appropriate
00557 long FXSevenSegment::onQueryTip(FXObject *sender,FXSelector sel,void *ptr) {
00558     if (getParent()) return getParent()->handle(sender,sel,ptr);
00559     return 0;
00560 }
00561 
00562 // let parent show help if appropriate
00563 long FXSevenSegment::onQueryHelp(FXObject *sender,FXSelector sel,void *ptr) {
00564     if (getParent()) return getParent()->handle(sender,sel,ptr);
00565     return 0;
00566 }
00567 
00568 }
00569 

Generated on Wed May 5 00:06:29 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6