kdeui Library API Documentation

kled.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1998 Jörg Habenicht (j.habenicht@europemail.com) 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 00021 #define PAINT_BENCH 00022 #undef PAINT_BENCH 00023 00024 #ifdef PAINT_BENCH 00025 #include <qdatetime.h> 00026 #include <stdio.h> 00027 #endif 00028 00029 00030 #include <qpainter.h> 00031 #include <qimage.h> 00032 #include <qcolor.h> 00033 #include <kapplication.h> 00034 #include <kpixmapeffect.h> 00035 #include "kled.h" 00036 00037 00038 class KLed::KLedPrivate 00039 { 00040 friend class KLed; 00041 00042 int dark_factor; 00043 QColor offcolor; 00044 QPixmap *off_map; 00045 QPixmap *on_map; 00046 }; 00047 00048 00049 00050 KLed::KLed(QWidget *parent, const char *name) 00051 : QWidget( parent, name), 00052 led_state(On), 00053 led_look(Raised), 00054 led_shape(Circular) 00055 { 00056 QColor col(green); 00057 d = new KLed::KLedPrivate; 00058 d->dark_factor = 300; 00059 d->offcolor = col.dark(300); 00060 d->off_map = 0; 00061 d->on_map = 0; 00062 00063 setColor(col); 00064 } 00065 00066 00067 KLed::KLed(const QColor& col, QWidget *parent, const char *name) 00068 : QWidget( parent, name), 00069 led_state(On), 00070 led_look(Raised), 00071 led_shape(Circular) 00072 { 00073 d = new KLed::KLedPrivate; 00074 d->dark_factor = 300; 00075 d->offcolor = col.dark(300); 00076 d->off_map = 0; 00077 d->on_map = 0; 00078 00079 setColor(col); 00080 //setShape(Circular); 00081 } 00082 00083 KLed::KLed(const QColor& col, KLed::State state, 00084 KLed::Look look, KLed::Shape shape, QWidget *parent, const char *name ) 00085 : QWidget(parent, name), 00086 led_state(state), 00087 led_look(look), 00088 led_shape(shape) 00089 { 00090 d = new KLed::KLedPrivate; 00091 d->dark_factor = 300; 00092 d->offcolor = col.dark(300); 00093 d->off_map = 0; 00094 d->on_map = 0; 00095 00096 //setShape(shape); 00097 setColor(col); 00098 } 00099 00100 00101 KLed::~KLed() 00102 { 00103 delete d->off_map; 00104 delete d->on_map; 00105 delete d; 00106 } 00107 00108 void 00109 KLed::paintEvent(QPaintEvent *) 00110 { 00111 #ifdef PAINT_BENCH 00112 const int rounds = 1000; 00113 QTime t; 00114 t.start(); 00115 for (int i=0; i<rounds; i++) { 00116 #endif 00117 switch(led_shape) 00118 { 00119 case Rectangular: 00120 switch (led_look) 00121 { 00122 case Sunken : 00123 paintRectFrame(false); 00124 break; 00125 case Raised : 00126 paintRectFrame(true); 00127 break; 00128 case Flat : 00129 paintRect(); 00130 break; 00131 default : 00132 qWarning("%s: in class KLed: no KLed::Look set",qApp->argv()[0]); 00133 } 00134 break; 00135 case Circular: 00136 switch (led_look) 00137 { 00138 case Flat : 00139 paintFlat(); 00140 break; 00141 case Raised : 00142 paintRound(); 00143 break; 00144 case Sunken : 00145 paintSunken(); 00146 break; 00147 default: 00148 qWarning("%s: in class KLed: no KLed::Look set",qApp->argv()[0]); 00149 } 00150 break; 00151 default: 00152 qWarning("%s: in class KLed: no KLed::Shape set",qApp->argv()[0]); 00153 break; 00154 } 00155 #ifdef PAINT_BENCH 00156 } 00157 int ready = t.elapsed(); 00158 qWarning("elapsed: %d msec. for %d rounds", ready, rounds); 00159 #endif 00160 } 00161 00162 int 00163 KLed::ensureRoundLed() 00164 { 00165 // Initialize coordinates, width, and height of the LED 00166 // 00167 int width = this->width(); 00168 // Make sure the LED is round! 00169 if (width > this->height()) 00170 width = this->height(); 00171 width -= 2; // leave one pixel border 00172 if (width < 0) 00173 width = 0; 00174 00175 return width; 00176 } 00177 00178 bool 00179 KLed::paintCachedPixmap() 00180 { 00181 if (led_state) { 00182 if (d->on_map) { 00183 QPainter paint(this); 00184 paint.drawPixmap(0, 0, *d->on_map); 00185 return true; 00186 } 00187 } else { 00188 if (d->off_map) { 00189 QPainter paint(this); 00190 paint.drawPixmap(0, 0, *d->off_map); 00191 return true; 00192 } 00193 } 00194 00195 return false; 00196 } 00197 00198 void 00199 KLed::paintFlat() // paint a ROUND FLAT led lamp 00200 { 00201 if (paintCachedPixmap()) return; 00202 00203 QPainter paint; 00204 QColor color; 00205 QBrush brush; 00206 QPen pen; 00207 00208 int width = ensureRoundLed(); 00209 00210 00211 int scale = 3; 00212 QPixmap *tmpMap = 0; 00213 00214 width *= scale; 00215 00216 tmpMap = new QPixmap(width + 6, width + 6); 00217 tmpMap->fill(paletteBackgroundColor()); 00218 00219 // start painting widget 00220 // 00221 paint.begin(tmpMap); 00222 00223 // Set the color of the LED according to given parameters 00224 color = ( led_state ) ? led_color : d->offcolor; 00225 00226 // Set the brush to SolidPattern, this fills the entire area 00227 // of the ellipse which is drawn with a thin gray "border" (pen) 00228 brush.setStyle( QBrush::SolidPattern ); 00229 brush.setColor( color ); 00230 00231 pen.setWidth( scale ); 00232 color = colorGroup().dark(); 00233 pen.setColor( color ); // Set the pen accordingly 00234 00235 paint.setPen( pen ); // Select pen for drawing 00236 paint.setBrush( brush ); // Assign the brush to the painter 00237 00238 // Draws a "flat" LED with the given color: 00239 paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 ); 00240 00241 paint.end(); 00242 // 00243 // painting done 00244 QPixmap *&dest = led_state ? d->on_map : d->off_map; 00245 QImage i = tmpMap->convertToImage(); 00246 width /= 3; 00247 i = i.smoothScale(width, width); 00248 delete tmpMap; 00249 dest = new QPixmap(i); 00250 paint.begin(this); 00251 paint.drawPixmap(0, 0, *dest); 00252 paint.end(); 00253 00254 } 00255 00256 void 00257 KLed::paintRound() // paint a ROUND RAISED led lamp 00258 { 00259 if (paintCachedPixmap()) return; 00260 00261 QPainter paint; 00262 QColor color; 00263 QBrush brush; 00264 QPen pen; 00265 00266 // Initialize coordinates, width, and height of the LED 00267 int width = ensureRoundLed(); 00268 00269 int scale = 3; 00270 QPixmap *tmpMap = 0; 00271 00272 width *= scale; 00273 00274 tmpMap = new QPixmap(width + 6, width + 6); 00275 tmpMap->fill(paletteBackgroundColor()); 00276 paint.begin(tmpMap); 00277 00278 // Set the color of the LED according to given parameters 00279 color = ( led_state ) ? led_color : d->offcolor; 00280 00281 // Set the brush to SolidPattern, this fills the entire area 00282 // of the ellipse which is drawn first 00283 brush.setStyle( QBrush::SolidPattern ); 00284 brush.setColor( color ); 00285 paint.setBrush( brush ); // Assign the brush to the painter 00286 00287 // Draws a "flat" LED with the given color: 00288 paint.drawEllipse( scale, scale, width - scale*2, width - scale*2 ); 00289 00290 // Draw the bright light spot of the LED now, using modified "old" 00291 // painter routine taken from KDEUI´s KLed widget: 00292 00293 // Setting the new width of the pen is essential to avoid "pixelized" 00294 // shadow like it can be observed with the old LED code 00295 pen.setWidth( 2 * scale ); 00296 00297 // shrink the light on the LED to a size about 2/3 of the complete LED 00298 int pos = width/5 + 1; 00299 int light_width = width; 00300 light_width *= 2; 00301 light_width /= 3; 00302 00303 // Calculate the LED´s "light factor": 00304 int light_quote = (130*2/(light_width?light_width:1))+100; 00305 00306 // Now draw the bright spot on the LED: 00307 while (light_width) { 00308 color = color.light( light_quote ); // make color lighter 00309 pen.setColor( color ); // set color as pen color 00310 paint.setPen( pen ); // select the pen for drawing 00311 paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle) 00312 light_width--; 00313 if (!light_width) 00314 break; 00315 paint.drawEllipse( pos, pos, light_width, light_width ); 00316 light_width--; 00317 if (!light_width) 00318 break; 00319 paint.drawEllipse( pos, pos, light_width, light_width ); 00320 pos++; light_width--; 00321 } 00322 00323 // Drawing of bright spot finished, now draw a thin gray border 00324 // around the LED; it looks nicer that way. We do this here to 00325 // avoid that the border can be erased by the bright spot of the LED 00326 00327 pen.setWidth( 2 * scale + 1 ); 00328 color = colorGroup().dark(); 00329 pen.setColor( color ); // Set the pen accordingly 00330 paint.setPen( pen ); // Select pen for drawing 00331 brush.setStyle( QBrush::NoBrush ); // Switch off the brush 00332 paint.setBrush( brush ); // This avoids filling of the ellipse 00333 00334 paint.drawEllipse( 2, 2, width, width ); 00335 00336 paint.end(); 00337 // 00338 // painting done 00339 QPixmap *&dest = led_state ? d->on_map : d->off_map; 00340 QImage i = tmpMap->convertToImage(); 00341 width /= 3; 00342 i = i.smoothScale(width, width); 00343 delete tmpMap; 00344 dest = new QPixmap(i); 00345 paint.begin(this); 00346 paint.drawPixmap(0, 0, *dest); 00347 paint.end(); 00348 00349 } 00350 00351 void 00352 KLed::paintSunken() // paint a ROUND SUNKEN led lamp 00353 { 00354 if (paintCachedPixmap()) return; 00355 00356 QPainter paint; 00357 QColor color; 00358 QBrush brush; 00359 QPen pen; 00360 00361 // First of all we want to know what area should be updated 00362 // Initialize coordinates, width, and height of the LED 00363 int width = ensureRoundLed(); 00364 00365 int scale = 3; 00366 QPixmap *tmpMap = 0; 00367 00368 width *= scale; 00369 00370 tmpMap = new QPixmap(width, width); 00371 tmpMap->fill(paletteBackgroundColor()); 00372 paint.begin(tmpMap); 00373 00374 // Set the color of the LED according to given parameters 00375 color = ( led_state ) ? led_color : d->offcolor; 00376 00377 // Set the brush to SolidPattern, this fills the entire area 00378 // of the ellipse which is drawn first 00379 brush.setStyle( QBrush::SolidPattern ); 00380 brush.setColor( color ); 00381 paint.setBrush( brush ); // Assign the brush to the painter 00382 00383 // Draws a "flat" LED with the given color: 00384 paint.drawEllipse( scale, scale, width - scale*2, width - scale*2 ); 00385 00386 // Draw the bright light spot of the LED now, using modified "old" 00387 // painter routine taken from KDEUI´s KLed widget: 00388 00389 // Setting the new width of the pen is essential to avoid "pixelized" 00390 // shadow like it can be observed with the old LED code 00391 pen.setWidth( 2 * scale ); 00392 00393 // shrink the light on the LED to a size about 2/3 of the complete LED 00394 int pos = width/5 + 1; 00395 int light_width = width; 00396 light_width *= 2; 00397 light_width /= 3; 00398 00399 // Calculate the LED´s "light factor": 00400 int light_quote = (130*2/(light_width?light_width:1))+100; 00401 00402 // Now draw the bright spot on the LED: 00403 while (light_width) { 00404 color = color.light( light_quote ); // make color lighter 00405 pen.setColor( color ); // set color as pen color 00406 paint.setPen( pen ); // select the pen for drawing 00407 paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle) 00408 light_width--; 00409 if (!light_width) 00410 break; 00411 paint.drawEllipse( pos, pos, light_width, light_width ); 00412 light_width--; 00413 if (!light_width) 00414 break; 00415 paint.drawEllipse( pos, pos, light_width, light_width ); 00416 pos++; light_width--; 00417 } 00418 00419 // Drawing of bright spot finished, now draw a thin border 00420 // around the LED which resembles a shadow with light coming 00421 // from the upper left. 00422 00423 pen.setWidth( 2 * scale + 1 ); // ### shouldn't this value be smaller for smaller LEDs? 00424 brush.setStyle( QBrush::NoBrush ); // Switch off the brush 00425 paint.setBrush( brush ); // This avoids filling of the ellipse 00426 00427 // Set the initial color value to colorGroup().light() (bright) and start 00428 // drawing the shadow border at 45° (45*16 = 720). 00429 00430 int angle = -720; 00431 color = colorGroup().light(); 00432 00433 for ( int arc = 120; arc < 2880; arc += 240 ) { 00434 pen.setColor( color ); 00435 paint.setPen( pen ); 00436 int w = width - pen.width()/2 - scale + 1; 00437 paint.drawArc( pen.width()/2, pen.width()/2, w, w, angle + arc, 240 ); 00438 paint.drawArc( pen.width()/2, pen.width()/2, w, w, angle - arc, 240 ); 00439 color = color.dark( 110 ); //FIXME: this should somehow use the contrast value 00440 } // end for ( angle = 720; angle < 6480; angle += 160 ) 00441 00442 paint.end(); 00443 // 00444 // painting done 00445 00446 QPixmap *&dest = led_state ? d->on_map : d->off_map; 00447 QImage i = tmpMap->convertToImage(); 00448 width /= 3; 00449 i = i.smoothScale(width, width); 00450 delete tmpMap; 00451 dest = new QPixmap(i); 00452 paint.begin(this); 00453 paint.drawPixmap(0, 0, *dest); 00454 paint.end(); 00455 00456 } 00457 00458 void 00459 KLed::paintRect() 00460 { 00461 QPainter painter(this); 00462 QBrush lightBrush(led_color); 00463 QBrush darkBrush(d->offcolor); 00464 QPen pen(led_color.dark(300)); 00465 int w=width(); 00466 int h=height(); 00467 // ----- 00468 switch(led_state) 00469 { 00470 case On: 00471 painter.setBrush(lightBrush); 00472 painter.drawRect(0, 0, w, h); 00473 break; 00474 case Off: 00475 painter.setBrush(darkBrush); 00476 painter.drawRect(0, 0, w, h); 00477 painter.setPen(pen); 00478 painter.drawLine(0, 0, w, 0); 00479 painter.drawLine(0, h-1, w, h-1); 00480 // Draw verticals 00481 int i; 00482 for(i=0; i < w; i+= 4 /* dx */) 00483 painter.drawLine(i, 1, i, h-1); 00484 break; 00485 default: break; 00486 } 00487 } 00488 00489 void 00490 KLed::paintRectFrame(bool raised) 00491 { 00492 QPainter painter(this); 00493 QBrush lightBrush(led_color); 00494 QBrush darkBrush(d->offcolor); 00495 int w=width(); 00496 int h=height(); 00497 QColor black=Qt::black; 00498 QColor white=Qt::white; 00499 // ----- 00500 if(raised) 00501 { 00502 painter.setPen(white); 00503 painter.drawLine(0, 0, 0, h-1); 00504 painter.drawLine(1, 0, w-1, 0); 00505 painter.setPen(black); 00506 painter.drawLine(1, h-1, w-1, h-1); 00507 painter.drawLine(w-1, 1, w-1, h-1); 00508 painter.fillRect(1, 1, w-2, h-2, 00509 (led_state==On)? lightBrush : darkBrush); 00510 } else { 00511 painter.setPen(black); 00512 painter.drawRect(0,0,w,h); 00513 painter.drawRect(0,0,w-1,h-1); 00514 painter.setPen(white); 00515 painter.drawRect(1,1,w-1,h-1); 00516 painter.fillRect(2, 2, w-4, h-4, 00517 (led_state==On)? lightBrush : darkBrush); 00518 } 00519 } 00520 00521 KLed::State 00522 KLed::state() const 00523 { 00524 return led_state; 00525 } 00526 00527 KLed::Shape 00528 KLed::shape() const 00529 { 00530 return led_shape; 00531 } 00532 00533 QColor 00534 KLed::color() const 00535 { 00536 return led_color; 00537 } 00538 00539 KLed::Look 00540 KLed::look() const 00541 { 00542 return led_look; 00543 } 00544 00545 void 00546 KLed::setState( State state ) 00547 { 00548 if (led_state != state) 00549 { 00550 led_state = state; 00551 update(); 00552 } 00553 } 00554 00555 void 00556 KLed::toggleState() 00557 { 00558 toggle(); 00559 } 00560 00561 void 00562 KLed::setShape(KLed::Shape s) 00563 { 00564 if(led_shape!=s) 00565 { 00566 led_shape = s; 00567 update(); 00568 } 00569 } 00570 00571 void 00572 KLed::setColor(const QColor& col) 00573 { 00574 if(led_color!=col) { 00575 if(d->on_map) { delete d->on_map; d->on_map = 0; } 00576 if(d->off_map) { delete d->off_map; d->off_map = 0; } 00577 led_color = col; 00578 d->offcolor = col.dark(d->dark_factor); 00579 update(); 00580 } 00581 } 00582 00583 void 00584 KLed::setDarkFactor(int darkfactor) 00585 { 00586 if (d->dark_factor != darkfactor) { 00587 d->dark_factor = darkfactor; 00588 d->offcolor = led_color.dark(darkfactor); 00589 update(); 00590 } 00591 } 00592 00593 int 00594 KLed::darkFactor() const 00595 { 00596 return d->dark_factor; 00597 } 00598 00599 void 00600 KLed::setLook( Look look ) 00601 { 00602 if(led_look!=look) 00603 { 00604 led_look = look; 00605 update(); 00606 } 00607 } 00608 00609 void 00610 KLed::toggle() 00611 { 00612 led_state = (led_state == On) ? Off : On; 00613 // setColor(led_color); 00614 update(); 00615 } 00616 00617 void 00618 KLed::on() 00619 { 00620 setState(On); 00621 } 00622 00623 void 00624 KLed::off() 00625 { 00626 setState(Off); 00627 } 00628 00629 QSize 00630 KLed::sizeHint() const 00631 { 00632 return QSize(16, 16); 00633 } 00634 00635 QSize 00636 KLed::minimumSizeHint() const 00637 { 00638 return QSize(16, 16 ); 00639 } 00640 00641 void KLed::virtual_hook( int, void* ) 00642 { /*BASE::virtual_hook( id, data );*/ } 00643 00644 #include "kled.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:27:30 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003