SUMO - Simulation of Urban MObility
|
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