00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kled.h"
00021
00022 #define PAINT_BENCH
00023 #undef PAINT_BENCH
00024
00025 #ifdef PAINT_BENCH
00026 #include <qdatetime.h>
00027 #include <stdio.h>
00028 #endif
00029
00030
00031 #include <QtGui/QPainter>
00032 #include <QtGui/QImage>
00033 #include <QtGui/QColor>
00034 #include <QtGui/QApplication>
00035
00036 class KLed::Private
00037 {
00038 public:
00039 Private()
00040 : darkFactor( 300 ), color( Qt::green ),
00041 state( On ), look( Raised ), shape( Circular ),
00042 offMap( 0 ), onMap( 0 )
00043 {
00044 offColor = color.dark( darkFactor );
00045 }
00046
00047 ~Private()
00048 {
00049 delete offMap;
00050 delete onMap;
00051 }
00052
00053 int darkFactor;
00054 QColor color;
00055 State state;
00056 Look look;
00057 Shape shape;
00058
00059 QColor offColor;
00060 QPixmap *offMap;
00061 QPixmap *onMap;
00062 };
00063
00064
00065
00066 KLed::KLed( QWidget *parent )
00067 : QWidget( parent ),
00068 d( new Private )
00069 {
00070 setColor( QColor( Qt::green ) );
00071 }
00072
00073
00074 KLed::KLed( const QColor& color, QWidget *parent )
00075 : QWidget( parent ),
00076 d( new Private )
00077 {
00078 setColor( color );
00079 }
00080
00081 KLed::KLed( const QColor& color, State state, Look look, Shape shape,
00082 QWidget *parent )
00083 : QWidget( parent ),
00084 d( new Private )
00085 {
00086 d->state = state;
00087 d->look = look;
00088 d->shape = shape;
00089
00090 setColor( color );
00091 }
00092
00093 KLed::~KLed()
00094 {
00095 delete d;
00096 }
00097
00098 void KLed::paintEvent( QPaintEvent* )
00099 {
00100 #ifdef PAINT_BENCH
00101 const int rounds = 1000;
00102 QTime t;
00103 t.start();
00104 for ( int i = 0; i < rounds; i++ ) {
00105 #endif
00106 switch( d->shape ) {
00107 case Rectangular:
00108 switch ( d->look ) {
00109 case Sunken:
00110 paintRectFrame( false );
00111 break;
00112 case Raised:
00113 paintRectFrame( true );
00114 break;
00115 case Flat:
00116 paintRect();
00117 break;
00118 default:
00119 qWarning( "%s: in class KLed: no KLed::Look set", qApp->argv()[0] );
00120 }
00121 break;
00122 case Circular:
00123 switch ( d->look ) {
00124 case Flat:
00125 paintFlat();
00126 break;
00127 case Raised:
00128 paintRaised();
00129 break;
00130 case Sunken:
00131 paintSunken();
00132 break;
00133 default:
00134 qWarning( "%s: in class KLed: no KLed::Look set", qApp->argv()[0] );
00135 }
00136 break;
00137 default:
00138 qWarning( "%s: in class KLed: no KLed::Shape set", qApp->argv()[0] );
00139 break;
00140 }
00141 #ifdef PAINT_BENCH
00142 }
00143
00144 int ready = t.elapsed();
00145 qWarning( "elapsed: %d msec. for %d rounds", ready, rounds );
00146 #endif
00147 }
00148
00149 int KLed::ledWidth() const
00150 {
00151
00152 int width = this->width();
00153
00154
00155 if ( width > this->height() )
00156 width = this->height();
00157
00158
00159 width -= 2;
00160
00161 if ( width < 0 )
00162 width = 0;
00163
00164 return width;
00165 }
00166
00167 bool KLed::paintCachedPixmap()
00168 {
00169 if ( d->state == On ) {
00170 if ( d->onMap ) {
00171 QPainter paint( this );
00172 paint.drawPixmap( 0, 0, *d->onMap );
00173 return true;
00174 }
00175 } else {
00176 if ( d->offMap ) {
00177 QPainter paint( this );
00178 paint.drawPixmap( 0, 0, *d->offMap );
00179 return true;
00180 }
00181 }
00182
00183 return false;
00184 }
00185
00186
00187 void KLed::paintFlat()
00188 {
00189 if ( paintCachedPixmap() )
00190 return;
00191
00192 QPainter paint;
00193 QColor color;
00194 QBrush brush;
00195 QPen pen;
00196
00197 int width = ledWidth();
00198
00199 int scale = 3;
00200 QPixmap *tmpMap = 0;
00201
00202 width *= scale;
00203
00204 tmpMap = new QPixmap( width + 6, width + 6 );
00205 tmpMap->fill( palette().color( backgroundRole() ) );
00206
00207
00208 paint.begin( tmpMap );
00209 paint.setRenderHint(QPainter::Antialiasing);
00210
00211
00212 color = ( d->state ) ? d->color : d->offColor;
00213
00214
00215
00216 brush.setStyle( Qt::SolidPattern );
00217 brush.setColor( color );
00218
00219 pen.setWidth( scale );
00220 color = palette().color( QPalette::Dark );
00221 pen.setColor( color );
00222
00223 paint.setPen( pen );
00224 paint.setBrush( brush );
00225
00226
00227 paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 );
00228
00229 paint.end();
00230
00231
00232 QPixmap *&dest = ( d->state == On ? d->onMap : d->offMap );
00233 QImage i = tmpMap->toImage();
00234 width /= 3;
00235 i = i.scaled( width, width, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
00236 delete tmpMap;
00237
00238 dest = new QPixmap( QPixmap::fromImage( i ) );
00239 paint.begin( this );
00240 paint.drawPixmap( 0, 0, *dest );
00241 paint.end();
00242 }
00243
00244
00245 void KLed::paintRaised()
00246 {
00247 if ( paintCachedPixmap() )
00248 return;
00249
00250 QPainter paint;
00251 QColor color;
00252 QBrush brush;
00253 QPen pen;
00254
00255
00256 int width = ledWidth();
00257
00258 int scale = 3;
00259 QPixmap *tmpMap = 0;
00260
00261 width *= scale;
00262
00263 tmpMap = new QPixmap( width + 6, width + 6 );
00264 tmpMap->fill( palette().color( backgroundRole() ) );
00265 paint.begin( tmpMap );
00266 paint.setRenderHint(QPainter::Antialiasing);
00267
00268
00269 color = ( d->state == On ? d->color : d->offColor );
00270
00271
00272
00273 brush.setStyle( Qt::SolidPattern );
00274 brush.setColor( color );
00275 paint.setBrush( brush );
00276
00277
00278 paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 );
00279
00280
00281
00282
00283
00284
00285 pen.setWidth( 2 * scale );
00286
00287
00288 int pos = width / 5 + 1;
00289 int light_width = width;
00290 light_width *= 2;
00291 light_width /= 3;
00292
00293
00294 int light_quote = ( 130 * 2 / ( light_width ? light_width : 1 ) ) + 100;
00295
00296
00297 while ( light_width ) {
00298 color = color.light( light_quote );
00299 pen.setColor( color );
00300 paint.setPen( pen );
00301 paint.drawEllipse( pos, pos, light_width, light_width );
00302 light_width--;
00303
00304 if ( !light_width )
00305 break;
00306
00307 paint.drawEllipse( pos, pos, light_width, light_width );
00308 light_width--;
00309
00310 if ( !light_width )
00311 break;
00312
00313 paint.drawEllipse( pos, pos, light_width, light_width );
00314 pos++;
00315 light_width--;
00316 }
00317
00318
00319
00320
00321
00322 pen.setWidth( 2 * scale + 1 );
00323 color = palette().color( QPalette::Dark );
00324 pen.setColor( color );
00325 paint.setPen( pen );
00326 brush.setStyle( Qt::NoBrush );
00327 paint.setBrush( brush );
00328
00329 paint.drawEllipse( 2, 2, width, width );
00330
00331 paint.end();
00332
00333
00334 QPixmap *&dest = ( d->state == On ? d->onMap : d->offMap );
00335 QImage i = tmpMap->toImage();
00336 width /= 3;
00337 i = i.scaled( width, width, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
00338 delete tmpMap;
00339
00340 dest = new QPixmap( QPixmap::fromImage( i ) );
00341 paint.begin( this );
00342 paint.drawPixmap( 0, 0, *dest );
00343 paint.end();
00344 }
00345
00346
00347 void KLed::paintSunken()
00348 {
00349 if ( paintCachedPixmap() )
00350 return;
00351
00352 QPainter paint;
00353 QColor color;
00354 QBrush brush;
00355 QPen pen;
00356
00357
00358
00359 int width = ledWidth();
00360
00361 int scale = 3;
00362 QPixmap *tmpMap = 0;
00363
00364 width *= scale;
00365
00366 tmpMap = new QPixmap( width, width );
00367 tmpMap->fill( palette().color( backgroundRole() ) );
00368 paint.begin( tmpMap );
00369 paint.setRenderHint(QPainter::Antialiasing);
00370
00371
00372 color = ( d->state == On ) ? d->color : d->offColor;
00373
00374
00375
00376 brush.setStyle( Qt::SolidPattern );
00377 brush.setColor( color );
00378 paint.setBrush( brush );
00379
00380
00381 paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 );
00382
00383
00384
00385
00386
00387
00388 pen.setWidth( 2 * scale );
00389
00390
00391 int pos = width / 5 + 1;
00392 int light_width = width;
00393 light_width *= 2;
00394 light_width /= 3;
00395
00396
00397 int light_quote = ( 130 * 2 / ( light_width ? light_width : 1 ) ) + 100;
00398
00399
00400 while ( light_width ) {
00401 color = color.light( light_quote );
00402 pen.setColor( color );
00403 paint.setPen( pen );
00404 paint.drawEllipse( pos, pos, light_width, light_width );
00405 light_width--;
00406
00407 if ( !light_width )
00408 break;
00409
00410 paint.drawEllipse( pos, pos, light_width, light_width );
00411 light_width--;
00412
00413 if ( !light_width )
00414 break;
00415
00416 paint.drawEllipse( pos, pos, light_width, light_width );
00417 pos++;
00418 light_width--;
00419 }
00420
00421
00422
00423
00424
00425 pen.setWidth( 2 * scale + 1 );
00426 brush.setStyle( Qt::NoBrush );
00427 paint.setBrush( brush );
00428
00429
00430
00431
00432 int angle = -720;
00433 color = palette().color( QPalette::Light );
00434
00435 for ( int arc = 120; arc < 2880; arc += 240 ) {
00436 pen.setColor( color );
00437 paint.setPen( pen );
00438 int w = width - pen.width() / 2 - scale + 1;
00439 paint.drawArc( pen.width() / 2, pen.width() / 2, w, w, angle + arc, 240 );
00440 paint.drawArc( pen.width() / 2, pen.width() / 2, w, w, angle - arc, 240 );
00441 color = color.dark( 110 );
00442 }
00443
00444 paint.end();
00445
00446
00447
00448 QPixmap *&dest = ( d->state == On ? d->onMap : d->offMap );
00449 QImage i = tmpMap->toImage();
00450 width /= 3;
00451 i = i.scaled( width, width, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
00452 delete tmpMap;
00453
00454 dest = new QPixmap( QPixmap::fromImage( i ) );
00455 paint.begin( this );
00456 paint.setCompositionMode(QPainter::CompositionMode_Source);
00457 paint.drawPixmap( 0, 0, *dest );
00458 paint.end();
00459 }
00460
00461 void KLed::paintRect()
00462 {
00463 QPainter painter( this );
00464 painter.setRenderHint(QPainter::Antialiasing);
00465 QBrush lightBrush( d->color );
00466 QBrush darkBrush( d->offColor );
00467
00468 QPen pen( d->color.dark( 300 ) );
00469 int w = width();
00470 int h = height();
00471
00472
00473 switch ( d->state ) {
00474 case On:
00475 painter.setBrush( lightBrush );
00476 painter.drawRect( 0, 0, w, h );
00477 break;
00478 case Off:
00479 painter.setBrush( darkBrush );
00480 painter.drawRect( 0, 0, w, h );
00481 painter.setPen( pen );
00482 painter.drawLine( 0, 0, w, 0 );
00483 painter.drawLine( 0, h - 1, w, h - 1 );
00484
00485
00486 int i;
00487 for ( i = 0; i < w; i += 4 )
00488 painter.drawLine( i, 1, i, h - 1 );
00489 break;
00490 default:
00491 break;
00492 }
00493 }
00494
00495 void KLed::paintRectFrame( bool raised )
00496 {
00497 QPainter painter( this );
00498 painter.setRenderHint(QPainter::Antialiasing);
00499 QBrush lightBrush( d->color );
00500 QBrush darkBrush( d->offColor );
00501 int w = width();
00502 int h = height();
00503
00504 if ( raised ) {
00505 painter.setPen( Qt::white );
00506 painter.drawLine( 0, 0, 0, h - 1 );
00507 painter.drawLine( 1, 0, w - 1, 0 );
00508 painter.setPen( Qt::black );
00509 painter.drawLine( 1, h - 1, w - 1, h - 1 );
00510 painter.drawLine( w - 1, 1, w - 1, h - 1 );
00511 painter.fillRect( 1, 1, w - 2, h - 2, ( d->state == On ? lightBrush : darkBrush ) );
00512 } else {
00513 painter.setPen( Qt::black );
00514 painter.drawRect( 0, 0, w, h );
00515 painter.drawRect( 0, 0, w - 1, h - 1 );
00516 painter.setPen( Qt::white );
00517 painter.drawRect( 1, 1, w - 1, h - 1 );
00518 painter.fillRect( 2, 2, w - 4, h - 4, ( d->state == On ? lightBrush : darkBrush ) );
00519 }
00520 }
00521
00522 KLed::State KLed::state() const
00523 {
00524 return d->state;
00525 }
00526
00527 KLed::Shape KLed::shape() const
00528 {
00529 return d->shape;
00530 }
00531
00532 QColor KLed::color() const
00533 {
00534 return d->color;
00535 }
00536
00537 KLed::Look KLed::look() const
00538 {
00539 return d->look;
00540 }
00541
00542 void KLed::setState( State state )
00543 {
00544 if ( d->state == state)
00545 return;
00546
00547 d->state = state;
00548 update();
00549 }
00550
00551 void KLed::setShape( Shape shape )
00552 {
00553 if ( d->shape == shape )
00554 return;
00555
00556 d->shape = shape;
00557 update();
00558 }
00559
00560 void KLed::setColor( const QColor &color )
00561 {
00562 if ( d->color == color )
00563 return;
00564
00565 if ( d->onMap ) {
00566 delete d->onMap;
00567 d->onMap = 0;
00568 }
00569
00570 if ( d->offMap ) {
00571 delete d->offMap;
00572 d->offMap = 0;
00573 }
00574
00575 d->color = color;
00576 d->offColor = color.dark( d->darkFactor );
00577
00578 update();
00579 }
00580
00581 void KLed::setDarkFactor( int darkFactor )
00582 {
00583 if ( d->darkFactor == darkFactor )
00584 return;
00585
00586 d->darkFactor = darkFactor;
00587 d->offColor = d->color.dark( darkFactor );
00588 update();
00589 }
00590
00591 int KLed::darkFactor() const
00592 {
00593 return d->darkFactor;
00594 }
00595
00596 void KLed::setLook( Look look )
00597 {
00598 if ( d->look == look)
00599 return;
00600
00601 d->look = look;
00602 update();
00603 }
00604
00605 void KLed::toggle()
00606 {
00607 d->state = (d->state == On ? Off : On);
00608 update();
00609 }
00610
00611 void KLed::on()
00612 {
00613 setState( On );
00614 }
00615
00616 void KLed::off()
00617 {
00618 setState( Off );
00619 }
00620
00621 QSize KLed::sizeHint() const
00622 {
00623 return QSize( 16, 16 );
00624 }
00625
00626 QSize KLed::minimumSizeHint() const
00627 {
00628 return QSize( 16, 16 );
00629 }
00630
00631 #include "kled.moc"