• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kled.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
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   // Initialize coordinates, width, and height of the LED
00152   int width = this->width();
00153 
00154   // Make sure the LED is round!
00155   if ( width > this->height() )
00156     width = this->height();
00157 
00158   // leave one pixel border
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 // paint a ROUND FLAT led lamp
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   // start painting widget
00208   paint.begin( tmpMap );
00209   paint.setRenderHint(QPainter::Antialiasing);
00210 
00211   // Set the color of the LED according to given parameters
00212   color = ( d->state ) ? d->color : d->offColor;
00213 
00214   // Set the brush to SolidPattern, this fills the entire area
00215   // of the ellipse which is drawn with a thin gray "border" (pen)
00216   brush.setStyle( Qt::SolidPattern );
00217   brush.setColor( color );
00218 
00219   pen.setWidth( scale );
00220   color = palette().color( QPalette::Dark );
00221   pen.setColor( color ); // Set the pen accordingly
00222 
00223   paint.setPen( pen ); // Select pen for drawing
00224   paint.setBrush( brush ); // Assign the brush to the painter
00225 
00226   // Draws a "flat" LED with the given color:
00227   paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 );
00228 
00229   paint.end();
00230 
00231   // painting done
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 // paint a ROUND RAISED led lamp
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   // Initialize coordinates, width, and height of the LED
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   // Set the color of the LED according to given parameters
00269   color = ( d->state == On ? d->color : d->offColor );
00270 
00271   // Set the brush to SolidPattern, this fills the entire area
00272   // of the ellipse which is drawn first
00273   brush.setStyle( Qt::SolidPattern );
00274   brush.setColor( color );
00275   paint.setBrush( brush ); // Assign the brush to the painter
00276 
00277   // Draws a "flat" LED with the given color:
00278   paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 );
00279 
00280   // Draw the bright light spot of the LED now, using modified "old"
00281   // painter routine taken from KDEUI's KLed widget:
00282 
00283   // Setting the new width of the pen is essential to avoid "pixelized"
00284   // shadow like it can be observed with the old LED code
00285   pen.setWidth( 2 * scale );
00286 
00287   // shrink the light on the LED to a size about 2/3 of the complete LED
00288   int pos = width / 5 + 1;
00289   int light_width = width;
00290   light_width *= 2;
00291   light_width /= 3;
00292 
00293   // Calculate the LED's "light factor":
00294   int light_quote = ( 130 * 2 / ( light_width ? light_width : 1 ) ) + 100;
00295 
00296   // Now draw the bright spot on the LED:
00297   while ( light_width ) {
00298     color = color.light( light_quote );  // make color lighter
00299     pen.setColor( color );  // set color as pen color
00300     paint.setPen( pen );  // select the pen for drawing
00301     paint.drawEllipse( pos, pos, light_width, light_width );  // draw the ellipse (circle)
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   // Drawing of bright spot finished, now draw a thin gray border
00319   // around the LED; it looks nicer that way. We do this here to
00320   // avoid that the border can be erased by the bright spot of the LED
00321 
00322   pen.setWidth( 2 * scale + 1 );
00323   color = palette().color( QPalette::Dark );
00324   pen.setColor( color );  // Set the pen accordingly
00325   paint.setPen( pen );  // Select pen for drawing
00326   brush.setStyle( Qt::NoBrush );  // Switch off the brush
00327   paint.setBrush( brush );  // This avoids filling of the ellipse
00328 
00329   paint.drawEllipse( 2, 2, width, width );
00330 
00331   paint.end();
00332 
00333   // painting done
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 // paint a ROUND SUNKEN led lamp
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   // First of all we want to know what area should be updated
00358   // Initialize coordinates, width, and height of the LED
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   // Set the color of the LED according to given parameters
00372   color = ( d->state == On ) ? d->color : d->offColor;
00373 
00374   // Set the brush to SolidPattern, this fills the entire area
00375   // of the ellipse which is drawn first
00376   brush.setStyle( Qt::SolidPattern );
00377   brush.setColor( color );
00378   paint.setBrush( brush );  // Assign the brush to the painter
00379 
00380   // Draws a "flat" LED with the given color:
00381   paint.drawEllipse( scale, scale, width - scale * 2, width - scale * 2 );
00382 
00383   // Draw the bright light spot of the LED now, using modified "old"
00384   // painter routine taken from KDEUI's KLed widget:
00385 
00386   // Setting the new width of the pen is essential to avoid "pixelized"
00387   // shadow like it can be observed with the old LED code
00388   pen.setWidth( 2 * scale );
00389 
00390   // shrink the light on the LED to a size about 2/3 of the complete LED
00391   int pos = width / 5 + 1;
00392   int light_width = width;
00393   light_width *= 2;
00394   light_width /= 3;
00395 
00396   // Calculate the LED's "light factor":
00397   int light_quote = ( 130 * 2 / ( light_width ? light_width : 1 ) ) + 100;
00398 
00399   // Now draw the bright spot on the LED:
00400   while ( light_width ) {
00401     color = color.light( light_quote );                      // make color lighter
00402     pen.setColor( color );                                   // set color as pen color
00403     paint.setPen( pen );                                     // select the pen for drawing
00404     paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle)
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   // Drawing of bright spot finished, now draw a thin border
00422   // around the LED which resembles a shadow with light coming
00423   // from the upper left.
00424 
00425   pen.setWidth( 2 * scale + 1 ); // ### shouldn't this value be smaller for smaller LEDs?
00426   brush.setStyle( Qt::NoBrush );              // Switch off the brush
00427   paint.setBrush( brush );                        // This avoids filling of the ellipse
00428 
00429   // Set the initial color value to QColorGroup(palette()).light() (bright) and start
00430   // drawing the shadow border at 45° (45*16 = 720).
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 ); //FIXME: this should somehow use the contrast value
00442   }  // end for ( angle = 720; angle < 6480; angle += 160 )
00443 
00444   paint.end();
00445 
00446   // painting done
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       // Draw verticals
00486       int i;
00487       for ( i = 0; i < w; i += 4 /* dx */)
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"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal