SUMO - Simulation of Urban MObility
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') {
00171         setText(c[0]);
00172     }
00173     return 1;
00174 }
00175 
00176 // get value from int
00177 long FXSevenSegment::onCmdGetIntValue(FXObject* sender, FXSelector, void*) {
00178     FXint i = value - ASCII_ZERO;
00179     if (i < 0) {
00180         i = 0;
00181     }
00182     if (i > 9) {
00183         i = 9;
00184     }
00185     sender->handle(this, FXSEL(SEL_COMMAND, ID_SETINTVALUE), (void*)&i);
00186     return 1;
00187 }
00188 
00189 // set from int value
00190 long FXSevenSegment::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) {
00191     FXint i = *((FXint*)ptr);
00192     if (i < 0) {
00193         i = 0;
00194     }
00195     if (i > 9) {
00196         i = 9;
00197     }
00198     setText((FXchar)(i + ASCII_ZERO));
00199     return 1;
00200 }
00201 
00202 // get value from string
00203 long FXSevenSegment::onCmdGetStringValue(FXObject* sender, FXSelector, void*) {
00204     FXString s(value, 1);
00205     sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*)&s);
00206     return 1;
00207 }
00208 
00209 // set from string value
00210 long FXSevenSegment::onCmdSetStringValue(FXObject*, FXSelector, void* ptr) {
00211     FXString* s = (FXString*)ptr;
00212     if ((*s).length()) {
00213         setText((*s)[0]);
00214     }
00215     return 1;
00216 }
00217 
00218 // draw the specific character - figure out which segments to draw
00219 void FXSevenSegment::drawFigure(FXDCWindow& dc, FXchar figure) {
00220     switch (figure) {
00221         case ' ' :
00222             drawSegments(dc, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
00223             break;
00224         case '(' :
00225             drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
00226             break;
00227         case ')' :
00228             drawSegments(dc, TRUE , FALSE, TRUE , FALSE, FALSE, TRUE , TRUE);
00229             break;
00230         case '[' :
00231             drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
00232             break;
00233         case ']' :
00234             drawSegments(dc, TRUE , FALSE, TRUE , FALSE, FALSE, TRUE , TRUE);
00235             break;
00236         case '=' :
00237             drawSegments(dc, FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, TRUE);
00238             break;
00239 //    case '+' : drawSegments (dc, FALSE,FALSE,FALSE,TRUE ,FALSE,FALSE,FALSE); break;
00240         case '-' :
00241             drawSegments(dc, FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE);
00242             break;
00243         case '_' :
00244         case '.' :
00245             drawSegments(dc, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE);
00246             break;
00247         case '0' :
00248             drawSegments(dc, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE);
00249             break;
00250         case '1' :
00251             drawSegments(dc, FALSE, FALSE, TRUE , FALSE, FALSE, TRUE , FALSE);
00252             break;
00253         case '2' :
00254             drawSegments(dc, TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE);
00255             break;
00256         case '3' :
00257             drawSegments(dc, TRUE , FALSE, TRUE , TRUE , FALSE, TRUE , TRUE);
00258             break;
00259         case '4' :
00260             drawSegments(dc, FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , FALSE);
00261             break;
00262         case '5' :
00263             drawSegments(dc, TRUE , TRUE , FALSE, TRUE , FALSE, TRUE , TRUE);
00264             break;
00265         case '6' :
00266             drawSegments(dc, TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , TRUE);
00267             break;
00268         case '7' :
00269             drawSegments(dc, TRUE , FALSE, TRUE , FALSE, FALSE, TRUE , FALSE);
00270             break;
00271         case '8' :
00272             drawSegments(dc, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE);
00273             break;
00274         case '9' :
00275             drawSegments(dc, TRUE , TRUE , TRUE , TRUE , FALSE, TRUE , TRUE);
00276             break;
00277         case 'a' :
00278         case 'A' :
00279             drawSegments(dc, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE);
00280             break;
00281         case 'b' :
00282         case 'B' :
00283             drawSegments(dc, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , TRUE);
00284             break;
00285         case 'c' :
00286         case 'C' :
00287             drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
00288             break;
00289         case 'd' :
00290         case 'D' :
00291             drawSegments(dc, FALSE, FALSE, TRUE , TRUE , TRUE , TRUE , TRUE);
00292             break;
00293         case 'e' :
00294         case 'E' :
00295             drawSegments(dc, TRUE , TRUE , FALSE, TRUE , TRUE , FALSE, TRUE);
00296             break;
00297         case 'f' :
00298         case 'F' :
00299             drawSegments(dc, TRUE , TRUE , FALSE, TRUE , TRUE , FALSE, FALSE);
00300             break;
00301         case 'g' :
00302         case 'G' :
00303             drawSegments(dc, TRUE , TRUE , FALSE, FALSE, TRUE , TRUE , TRUE);
00304             break;
00305         case 'h' :
00306         case 'H' :
00307             drawSegments(dc, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , FALSE);
00308             break;
00309         case 'i' :
00310         case 'I' :
00311             drawSegments(dc, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE , FALSE);
00312             break;
00313         case 'j' :
00314         case 'J' :
00315             drawSegments(dc, FALSE, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE);
00316             break;
00317 //    case 'k' :
00318 //    case 'k' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00319         case 'l' :
00320         case 'L' :
00321             drawSegments(dc, FALSE, TRUE , FALSE, FALSE, TRUE , FALSE, TRUE);
00322             break;
00323 //    case 'm' :
00324 //    case 'M' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00325         case 'n' :
00326         case 'N' :
00327             drawSegments(dc, FALSE, FALSE, FALSE, TRUE , TRUE , TRUE , FALSE);
00328             break;
00329         case 'o' :
00330         case 'O' :
00331             drawSegments(dc, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE);
00332             break;
00333         case 'p' :
00334         case 'P' :
00335             drawSegments(dc, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE, FALSE);
00336             break;
00337         case 'q' :
00338         case 'Q' :
00339             drawSegments(dc, TRUE , TRUE , TRUE , TRUE , FALSE, TRUE , FALSE);
00340             break;
00341         case 'r' :
00342         case 'R' :
00343             drawSegments(dc, FALSE, FALSE, FALSE, TRUE , TRUE , FALSE, FALSE);
00344             break;
00345         case 's' :
00346         case 'S' :
00347             drawSegments(dc, TRUE , TRUE , FALSE, TRUE , FALSE, TRUE , TRUE);
00348             break;
00349         case 't' :
00350         case 'T' :
00351             drawSegments(dc, FALSE, TRUE , FALSE, TRUE , TRUE , FALSE, FALSE);
00352             break;
00353         case 'u' :
00354         case 'U' :
00355             drawSegments(dc, FALSE, TRUE , TRUE , FALSE, TRUE , TRUE , TRUE);
00356             break;
00357 //    case 'v' :
00358 //    case 'V' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00359 //    case 'w' :
00360 //    case 'W' : drawSegments (dc, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); break;
00361         case 'x' :
00362         case 'X' :
00363             drawSegments(dc, FALSE, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE);
00364             break;
00365         case 'y' :
00366         case 'Y' :
00367             drawSegments(dc, FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE);
00368             break;
00369 //    case 'z' :
00370 //    case 'Z' :
00371         default  :
00372             fxerror("FXSevenSegment doesnt support: %c\n", figure);
00373     }
00374 }
00375 
00376 // validates the sizes of the segment dimensions
00377 void FXSevenSegment::checkSize() {
00378     if (hsl < 3) {
00379         hsl = 3;
00380         st = 1;
00381     }
00382     if (vsl < 3) {
00383         vsl = 3;
00384         st = 1;
00385     }
00386     if (st < 1) {
00387         st = 1;
00388     }
00389     if (hsl < (st << 1)) {
00390         hsl = (st << 1) + 1;
00391     }
00392     if (vsl < (st << 1)) {
00393         vsl = (st << 1) + 1;
00394     }
00395     if (hsl < 8 || vsl < 8) {
00396         groove = 2;
00397     }
00398     if (hsl < 1 || vsl < 3 || st < 3) {
00399         groove = 1;
00400     }
00401     if (groove >= st) {
00402         groove = st - 1;
00403     }
00404 }
00405 
00406 // draw each segment, into the available drawing space
00407 // if widget is resizeable, caculate new sizes for length/width/grove of each segment
00408 void FXSevenSegment::drawSegments(FXDCWindow& dc, FXbool s1, FXbool s2, FXbool s3, FXbool s4, FXbool s5, FXbool s6, FXbool s7) {
00409     FXint sx = border + padleft, sy = border + padtop;
00410     FXint x, y;
00411     if (options & LAYOUT_FILL) {
00412         if (options & LAYOUT_FILL_X) {
00413             hsl = width - padleft - padright - (border << 1);
00414             if (hsl < 4) {
00415                 hsl = 4;
00416             }
00417         }
00418         if (options & LAYOUT_FILL_Y) {
00419             vsl = (height - padtop - padbottom - (border << 1)) >> 1;
00420             if (vsl < 4) {
00421                 vsl = 4;
00422             }
00423         }
00424         st = FXMIN(hsl, vsl) / 4;
00425         groove = st / 4;
00426         if (st < 1) {
00427             st = 1;
00428         }
00429         if (groove < 1) {
00430             groove = 1;
00431         }
00432         if (options & LAYOUT_FILL_X) {
00433             hsl -= groove << 1;
00434         }
00435         if (options & LAYOUT_FILL_Y) {
00436             vsl -= groove << 1;
00437         }
00438     }
00439     if (s1) {
00440         x = sx + groove;
00441         y = sy;
00442         drawTopSegment(dc, x, y);
00443     }
00444     if (s2) {
00445         x = sx;
00446         y = sy + groove;
00447         drawLeftTopSegment(dc, x, y);
00448     }
00449     if (s3) {
00450         x = sx + groove + hsl - st + groove;
00451         y = sy + groove;
00452         drawRightTopSegment(dc, x, y);
00453     }
00454     if (s4) {
00455         x = sx + groove;
00456         y = sy + groove + vsl - (st >> 1) + groove;
00457         drawMiddleSegment(dc, x, y);
00458     }
00459     if (s5) {
00460         x = sx;
00461         y = sy + (groove << 1) + vsl + groove;
00462         drawLeftBottomSegment(dc, x, y);
00463     }
00464     if (s6) {
00465         x = sx + groove + hsl - st + groove;
00466         y = sy + (groove << 1) + vsl + groove;
00467         drawRightBottomSegment(dc, x, y);
00468     }
00469     if (s7) {
00470         x = sx + groove;
00471         y = sy + (groove << 1) + vsl + groove + vsl + groove - st;
00472         drawBottomSegment(dc, x, y);
00473     }
00474 }
00475 
00476 void FXSevenSegment::drawTopSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00477     FXPoint points[4];
00478     points[0].x = x;
00479     points[0].y = y;
00480     points[1].x = x + hsl;
00481     points[1].y = y;
00482     points[2].x = x + hsl - st;
00483     points[2].y = y + st;
00484     points[3].x = x + st;
00485     points[3].y = y + st;
00486     dc.fillPolygon(points, 4);
00487 }
00488 
00489 void FXSevenSegment::drawLeftTopSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00490     FXPoint points[4];
00491     points[0].x = x;
00492     points[0].y = y;
00493     points[1].x = x + st;
00494     points[1].y = y + st;
00495     points[2].x = x + st;
00496     points[2].y = y + vsl - (st >> 1);
00497     points[3].x = x;
00498     points[3].y = y + vsl;
00499     dc.fillPolygon(points, 4);
00500 }
00501 
00502 void FXSevenSegment::drawRightTopSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00503     FXPoint points[4];
00504     points[0].x = x + st;
00505     points[0].y = y;
00506     points[1].x = x + st;
00507     points[1].y = y + vsl;
00508     points[2].x = x;
00509     points[2].y = y + vsl - (st >> 1);
00510     points[3].x = x;
00511     points[3].y = y + st;
00512     dc.fillPolygon(points, 4);
00513 }
00514 
00515 void FXSevenSegment::drawMiddleSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00516     FXPoint points[6];
00517     points[0].x = x + st;
00518     points[0].y = y;
00519     points[1].x = x + hsl - st;
00520     points[1].y = y;
00521     points[2].x = x + hsl;
00522     points[2].y = y + (st >> 1);
00523     points[3].x = x + hsl - st;
00524     points[3].y = y + st;
00525     points[4].x = x + st;
00526     points[4].y = y + st;
00527     points[5].x = x;
00528     points[5].y = y + (st >> 1);
00529     dc.fillPolygon(points, 6);
00530 }
00531 
00532 void FXSevenSegment::drawLeftBottomSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00533     FXPoint points[4];
00534     points[0].x = x;
00535     points[0].y = y;
00536     points[1].x = x + st;
00537     points[1].y = y + (st >> 1);
00538     points[2].x = x + st;
00539     points[2].y = y + vsl - st;
00540     points[3].x = x;
00541     points[3].y = y + vsl;
00542     dc.fillPolygon(points, 4);
00543 }
00544 
00545 void FXSevenSegment::drawRightBottomSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00546     FXPoint points[4];
00547     points[0].x = x + st;
00548     points[0].y = y;
00549     points[1].x = x + st;
00550     points[1].y = y + vsl;
00551     points[2].x = x;
00552     points[2].y = y + vsl - st;
00553     points[3].x = x;
00554     points[3].y = y + (st >> 1);
00555     dc.fillPolygon(points, 4);
00556 }
00557 
00558 void FXSevenSegment::drawBottomSegment(FXDCWindow& dc, FXshort x, FXshort y) {
00559     FXPoint points[4];
00560     points[0].x = x + st;
00561     points[0].y = y;
00562     points[1].x = x + hsl - st;
00563     points[1].y = y;
00564     points[2].x = x + hsl;
00565     points[2].y = y + st;
00566     points[3].x = x;
00567     points[3].y = y + st;
00568     dc.fillPolygon(points, 4);
00569 }
00570 
00571 void FXSevenSegment::save(FXStream& store) const {
00572     FXFrame::save(store);
00573     store << value;
00574     store << fgcolor;
00575     store << bgcolor;
00576     store << hsl;
00577     store << vsl;
00578     store << st;
00579     store << groove;
00580 }
00581 
00582 void FXSevenSegment::load(FXStream& store) {
00583     FXFrame::load(store);
00584     store >> value;
00585     store >> fgcolor;
00586     store >> bgcolor;
00587     store >> hsl;
00588     store >> vsl;
00589     store >> st;
00590     store >> groove;
00591 }
00592 
00593 // let parent show tip if appropriate
00594 long FXSevenSegment::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) {
00595     if (getParent()) {
00596         return getParent()->handle(sender, sel, ptr);
00597     }
00598     return 0;
00599 }
00600 
00601 // let parent show help if appropriate
00602 long FXSevenSegment::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) {
00603     if (getParent()) {
00604         return getParent()->handle(sender, sel, ptr);
00605     }
00606     return 0;
00607 }
00608 
00609 }
00610 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines