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  * $Id: kled.cpp,v 1.23 2002/03/04 00:51:49 lunakl Exp $
00022  *
00023  * $Log: kled.cpp,v $
00024  * Revision 1.23  2002/03/04 00:51:49  lunakl
00025  * Keep BC changes (the patch is almost 100KiB of boring stuff
00026  * ... anybody willing to review? ;) ).
00027  *
00028  * Revision 1.22  2002/02/27 23:15:45  pfeiffer
00029  * kapp--
00030  *
00031  * Revision 1.21  2002/01/22 10:23:55  hausmann
00032  * - minor API fix (don't return a const QColor object)
00033  *
00034  * Revision 1.20  2001/10/10 17:40:39  mueller
00035  * CVS_SILENT: fixincludes
00036  *
00037  * Revision 1.19  2001/08/08 14:35:12  hausmann
00038  * - removed empty KActionCollection::childEvent
00039  * - added sizeHint() and minimumSizeHint() methods to KLed, as advised by
00040  *   Rik in the comment in kled.h
00041  * - removed unused mousePressEvent, mouseMoveEvent and mouseReleaseEvent
00042  *   handlers from KPassDlg
00043  * - merged KToolBar::insertSeparator() and KToolBar::insertLineSeparator()
00044  *   with their overloaded variants
00045  *
00046  * Revision 1.18  2001/04/16 22:08:43  pfeiffer
00047  * don't assume that the first item of an enum is 0
00048  *
00049  * Revision 1.17  2000/09/12 19:15:53  pfeiffer
00050  * Stefan Hellwig in cooperation with Joerg Habenicht:
00051  * Draw nicer LEDs, especially sunken ones.
00052  *
00053  * Revision 1.16  2000/08/24 12:44:48  porten
00054  * "friend class" patches from Thomas Kunert <kunert@physik.tu-dresden.de>
00055  *
00056  * Revision 1.15  2000/08/17 16:44:44  reggie
00057  * Don't crash
00058  *
00059  * Revision 1.14  2000/06/03 01:04:42  gehrmab
00060  * * Made drawing routines available for overriding
00061  * * Added a parent/name constructor
00062  * * Propertyfication
00063  *
00064  * Revision 1.13  2000/05/08 19:38:49  sschiman
00065  * Calling setColor before setting up the private data is a bad idea ;-)
00066  *
00067  * Revision 1.12  2000/05/07 09:49:57  habenich
00068  * provided method to set the factor to dark the LED
00069  * precalculated the dark color, is just retrieved at paint events
00070  *
00071  * Revision 1.11  2000/04/09 16:08:33  habenich
00072  * fixed nasty bug #70 disappearing led
00073  * reenabled flat and raised led painting
00074  *
00075  * Revision 1.10  1999/12/25 17:12:18  mirko
00076  * Modified Look "round" to "raised", as the others are flat and
00077  * sunken. All enums start with uppercase letters now to fit the overall
00078  * KDE style.
00079  * Implemented raised rectangluar look.
00080  * --Mirko.
00081  *
00082  * Revision 1.9  1999/11/12 21:17:09  antlarr
00083  * Fixed some bugs.
00084  * Added the possibility to draw a sunk rectangle as the "old" KLedLamp did.
00085  *
00086  * Revision 1.9  1999/11/11 16:08:15  antlarr
00087  * Fixed some bugs.
00088  * Added the possibility to draw a sunk rectangle as the "old" KLedLamp did.
00089  *
00090  * Revision 1.8  1999/11/01 22:03:15  dmuell
00091  * fixing all kinds of compile warnings
00092  * (unused var, unused argument etc)
00093  *
00094  * Revision 1.7  1999/10/10 13:34:14  mirko
00095  * First merge with KLedLamp that shows a rectangular LED.
00096  * It does not yet work reliably.
00097  *
00098  * Revision 1.6  1999/03/01 23:34:49  kulow
00099  * CVS_SILENT ported to Qt 2.0
00100  *
00101  * Revision 1.5  1999/02/19 08:52:42  habenich
00102  * ID und LOG tags included
00103  *
00104  *
00105  *************************************************************************/
00106 
00107 #define PAINT_BENCH
00108 #undef PAINT_BENCH
00109 
00110 #ifdef PAINT_BENCH
00111 #include <qdatetime.h>
00112 #include <stdio.h>
00113 #endif
00114 
00115 
00116 #include <qpainter.h>
00117 #include <qcolor.h>
00118 #include <kapplication.h>
00119 #include <kpixmapeffect.h>
00120 #include "kled.h"
00121 
00122 
00123 
00124 class KLed::KLedPrivate
00125 {
00126   friend class KLed;
00127 
00128   int dark_factor;
00129   QColor offcolor;
00130 };
00131 
00132 
00133 
00134 KLed::KLed(QWidget *parent, const char *name)
00135   : QWidget( parent, name),
00136     led_state(On),
00137     led_look(Raised),
00138     led_shape(Circular)
00139 {
00140   QColor col(green);
00141   d = new KLed::KLedPrivate;
00142   d->dark_factor = 300;
00143   d->offcolor = col.dark(300);
00144 
00145   setColor(col);
00146 }
00147 
00148 
00149 KLed::KLed(const QColor& col, QWidget *parent, const char *name)
00150   : QWidget( parent, name),
00151     led_state(On),
00152     led_look(Raised),
00153     led_shape(Circular)
00154 {
00155   d = new KLed::KLedPrivate;
00156   d->dark_factor = 300;
00157   d->offcolor = col.dark(300);
00158 
00159   setColor(col);
00160   //setShape(Circular);
00161 }
00162 
00163 KLed::KLed(const QColor& col, KLed::State state,
00164        KLed::Look look, KLed::Shape shape, QWidget *parent, const char *name )
00165   : QWidget(parent, name),
00166     led_state(state),
00167     led_look(look),
00168     led_shape(shape)
00169 {
00170   d = new KLed::KLedPrivate;
00171   d->dark_factor = 300;
00172   d->offcolor = col.dark(300);
00173 
00174   //setShape(shape);
00175   setColor(col);
00176 }
00177 
00178 
00179 KLed::~KLed()
00180 {
00181   delete d;
00182 }
00183 
00184 void
00185 KLed::paintEvent(QPaintEvent *)
00186 {
00187 #ifdef PAINT_BENCH
00188   const int rounds = 1000;
00189   QTime t;
00190   t.start();
00191   for (int i=0; i<rounds; i++) {
00192 #endif
00193   switch(led_shape)
00194     {
00195     case Rectangular:
00196       switch (led_look)
00197     {
00198     case Sunken :
00199       paintRectFrame(false);
00200       break;
00201     case Raised :
00202       paintRectFrame(true);
00203       break;
00204     case Flat   :
00205       paintRect();
00206       break;
00207     default  :
00208       qWarning("%s: in class KLed: no KLed::Look set",qApp->argv()[0]);
00209     }
00210       break;
00211     case Circular:
00212       switch (led_look)
00213     {
00214     case Flat   :
00215       paintFlat();
00216       break;
00217     case Raised :
00218       paintRound();
00219       break;
00220     case Sunken :
00221       paintSunken();
00222       break;
00223     default:
00224       qWarning("%s: in class KLed: no KLed::Look set",qApp->argv()[0]);
00225     }
00226       break;
00227     default:
00228       qWarning("%s: in class KLed: no KLed::Shape set",qApp->argv()[0]);
00229       break;
00230     }
00231 #ifdef PAINT_BENCH
00232   }
00233   int ready = t.elapsed();
00234   qWarning("elapsed: %d msec. for %d rounds", ready, rounds);
00235 #endif
00236 }
00237 
00238 void
00239 KLed::paintFlat() // paint a ROUND FLAT led lamp
00240 {
00241     QPainter paint;
00242     QColor color;
00243     QBrush brush;
00244     QPen pen;
00245 
00246     // Initialize coordinates, width, and height of the LED
00247     //
00248     int width = this->width();
00249     // Make sure the LED is round!
00250     if (width > this->height())
00251         width = this->height();
00252     width -= 2; // leave one pixel border
00253     if (width < 0)
00254       width = 0;
00255 
00256 
00257     // start painting widget
00258     //
00259     paint.begin( this );
00260 
00261     // Set the color of the LED according to given parameters
00262     color = ( led_state ) ? led_color : d->offcolor;
00263 
00264     // Set the brush to SolidPattern, this fills the entire area
00265     // of the ellipse which is drawn with a thin grey "border" (pen)
00266     brush.setStyle( QBrush::SolidPattern );
00267     brush.setColor( color );
00268 
00269     pen.setWidth( 1 );
00270     color.setRgb( 170, 170, 170 );      // This is a grey color value
00271     pen.setColor( color );          // Set the pen accordingly
00272 
00273     paint.setPen( pen );            // Select pen for drawing
00274     paint.setBrush( brush );        // Assign the brush to the painter
00275 
00276     // Draws a "flat" LED with the given color:
00277     paint.drawEllipse( 1, 1, width, width );
00278 
00279     paint.end();
00280     //
00281     // painting done
00282 }
00283 
00284 void
00285 KLed::paintRound() // paint a ROUND RAISED led lamp
00286 {
00287     QPainter paint;
00288     QColor color;
00289     QBrush brush;
00290     QPen pen;
00291 
00292     // Initialize coordinates, width, and height of the LED
00293     int width = this->width();
00294 
00295     // Make sure the LED is round!
00296     if (width > this->height())
00297       width = this->height();
00298     width -= 2; // leave one pixel border
00299     if (width < 0) 
00300       width = 0;
00301 
00302     // start painting widget
00303     //
00304     paint.begin( this );
00305 
00306     // Set the color of the LED according to given parameters
00307     color = ( led_state ) ? led_color : d->offcolor;
00308 
00309     // Set the brush to SolidPattern, this fills the entire area
00310     // of the ellipse which is drawn first
00311     brush.setStyle( QBrush::SolidPattern );
00312     brush.setColor( color );
00313     paint.setBrush( brush );        // Assign the brush to the painter
00314 
00315     // Draws a "flat" LED with the given color:
00316     paint.drawEllipse( 1, 1, width, width );
00317 
00318     // Draw the bright light spot of the LED now, using modified "old"
00319     // painter routine taken from KDEUI´s KLed widget:
00320 
00321     // Setting the new width of the pen is essential to avoid "pixelized"
00322     // shadow like it can be observed with the old LED code
00323     pen.setWidth( 2 );
00324 
00325     // shrink the light on the LED to a size about 2/3 of the complete LED
00326     int pos = width/5 + 1;
00327     int light_width = width;
00328     light_width *= 2;
00329     light_width /= 3;
00330 
00331     // Calculate the LED´s "light factor":
00332     int light_quote = (130*2/(light_width?light_width:1))+100;
00333 
00334     // Now draw the bright spot on the LED:
00335     while (light_width) {
00336         color = color.light( light_quote );         // make color lighter
00337     pen.setColor( color );              // set color as pen color
00338     paint.setPen( pen );                // select the pen for drawing
00339     paint.drawEllipse( pos, pos, light_width, light_width );    // draw the ellipse (circle)
00340     light_width--;
00341     if (!light_width)
00342              break;
00343     paint.drawEllipse( pos, pos, light_width, light_width );
00344     light_width--;
00345     if (!light_width)
00346         break;
00347     paint.drawEllipse( pos, pos, light_width, light_width );
00348     pos++; light_width--;
00349     }
00350 
00351     // Drawing of bright spot finished, now draw a thin grey border
00352     // around the LED; it looks nicer that way. We do this here to
00353     // avoid that the border can be erased by the bright spot of the LED
00354 
00355     pen.setWidth( 1 );
00356     color.setRgb( 170, 170, 170 );      // This is a grey color value
00357     pen.setColor( color );          // Set the pen accordingly
00358     paint.setPen( pen );            // Select pen for drawing
00359     brush.setStyle( QBrush::NoBrush );      // Switch off the brush
00360     paint.setBrush( brush );            // This avoids filling of the ellipse
00361 
00362     paint.drawEllipse( 1, 1, width, width );
00363 
00364     paint.end();
00365     //
00366     // painting done
00367 }
00368 
00369 void
00370 KLed::paintSunken() // paint a ROUND SUNKEN led lamp
00371 {
00372     QPainter paint;
00373     QColor color;
00374     QBrush brush;
00375     QPen pen;
00376                 
00377     // First of all we want to know what area should be updated
00378     // Initialize coordinates, width, and height of the LED
00379     int width = this->width();
00380 
00381     // Make sure the LED is round!
00382     if (width > this->height())
00383       width = this->height();
00384     width -= 2; // leave one pixel border
00385     if (width < 0) 
00386       width = 0;
00387 
00388     // maybe we could stop HERE, if width <=0 ?
00389 
00390     // start painting widget
00391     //
00392     paint.begin( this );
00393 
00394     // Set the color of the LED according to given parameters
00395     color = ( led_state ) ? led_color : d->offcolor;
00396 
00397     // Set the brush to SolidPattern, this fills the entire area
00398     // of the ellipse which is drawn first
00399     brush.setStyle( QBrush::SolidPattern );
00400     brush.setColor( color );
00401     paint.setBrush( brush );                // Assign the brush to the painter
00402 
00403     // Draws a "flat" LED with the given color:
00404     paint.drawEllipse( 1, 1, width, width );
00405 
00406     // Draw the bright light spot of the LED now, using modified "old"
00407     // painter routine taken from KDEUI´s KLed widget:
00408 
00409     // Setting the new width of the pen is essential to avoid "pixelized"
00410     // shadow like it can be observed with the old LED code
00411     pen.setWidth( 2 );
00412 
00413     // shrink the light on the LED to a size about 2/3 of the complete LED
00414     int pos = width/5 + 1;
00415     int light_width = width;
00416     light_width *= 2;
00417     light_width /= 3;
00418     
00419     // Calculate the LED´s "light factor":
00420     int light_quote = (130*2/(light_width?light_width:1))+100;
00421 
00422     // Now draw the bright spot on the LED:
00423     while (light_width) {
00424     color = color.light( light_quote );                      // make color lighter
00425     pen.setColor( color );                                   // set color as pen color
00426     paint.setPen( pen );                                     // select the pen for drawing
00427     paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle)
00428     light_width--;
00429     if (!light_width)
00430         break;
00431     paint.drawEllipse( pos, pos, light_width, light_width );
00432     light_width--;
00433     if (!light_width)
00434         break;
00435     paint.drawEllipse( pos, pos, light_width, light_width );
00436     pos++; light_width--;
00437     }
00438 
00439     // Drawing of bright spot finished, now draw a thin border
00440     // around the LED which resembles a shadow with light coming
00441     // from the upper left.
00442 
00443     pen.setWidth( 3 );
00444     brush.setStyle( QBrush::NoBrush );              // Switch off the brush
00445     paint.setBrush( brush );                        // This avoids filling of the ellipse
00446 
00447     // Set the initial color value to 200 (bright) and start
00448     // drawing the shadow border at 45° (45*16 = 720).
00449 
00450     int shadow_color = 200, angle;
00451     
00452     for ( angle = 720; angle < 6480; angle += 240 ) {
00453       color.setRgb( shadow_color, shadow_color, shadow_color );
00454       pen.setColor( color );
00455       paint.setPen( pen );
00456       paint.drawArc( 1, 1, width, width, angle, 240 );
00457       if ( angle < 2320 ) {
00458     shadow_color -= 25;         // set color to a darker value
00459     if ( shadow_color < 100 ) shadow_color = 100;
00460       }
00461       else if ( ( angle > 2320 ) && ( angle < 5760 ) ) {
00462     shadow_color += 25;         // set color to a brighter value
00463     if ( shadow_color > 255 ) shadow_color = 255;
00464       }
00465       else {
00466     shadow_color -= 25;         // set color to a darker value again
00467     if ( shadow_color < 100 ) shadow_color = 100;
00468       } // end if ( angle < 2320 )
00469     }   // end for ( angle = 720; angle < 6480; angle += 160 )
00470 
00471     paint.end();
00472     //
00473     // painting done
00474 }
00475 
00476 void
00477 KLed::paintRect()
00478 {
00479   QPainter painter(this);
00480   QBrush lightBrush(led_color);
00481   QBrush darkBrush(d->offcolor);
00482   QPen pen(led_color.dark(300));
00483   int w=width();
00484   int h=height();
00485   // -----
00486   switch(led_state)
00487   {
00488   case On:
00489     painter.setBrush(lightBrush);
00490     painter.drawRect(0, 0, w, h);
00491     break;
00492   case Off:
00493     painter.setBrush(darkBrush);
00494     painter.drawRect(0, 0, w, h);
00495     painter.setPen(pen);
00496     painter.drawLine(0, 0, w, 0);
00497     painter.drawLine(0, h-1, w, h-1);
00498     // Draw verticals
00499     int i;
00500     for(i=0; i < w; i+= 4 /* dx */)
00501       painter.drawLine(i, 1, i, h-1);
00502     break;
00503   default: break;
00504   }
00505 }
00506 
00507 void
00508 KLed::paintRectFrame(bool raised)
00509 {
00510   QPainter painter(this);
00511   QBrush lightBrush(led_color);
00512   QBrush darkBrush(d->offcolor);
00513   int w=width();
00514   int h=height();
00515   QColor black=Qt::black;
00516   QColor white=Qt::white;
00517   // -----
00518   if(raised)
00519     {
00520       painter.setPen(white);
00521       painter.drawLine(0, 0, 0, h-1);
00522       painter.drawLine(1, 0, w-1, 0);
00523       painter.setPen(black);
00524       painter.drawLine(1, h-1, w-1, h-1);
00525       painter.drawLine(w-1, 1, w-1, h-1);
00526       painter.fillRect(1, 1, w-2, h-2,
00527                    (led_state==On)? lightBrush : darkBrush);
00528     } else {
00529       painter.setPen(black);
00530       painter.drawRect(0,0,w,h);
00531       painter.drawRect(0,0,w-1,h-1);
00532       painter.setPen(white);
00533       painter.drawRect(1,1,w-1,h-1);
00534       painter.fillRect(2, 2, w-4, h-4,
00535                (led_state==On)? lightBrush : darkBrush);
00536     }
00537 }
00538 
00539 KLed::State
00540 KLed::state() const
00541 {
00542   return led_state;
00543 }
00544 
00545 KLed::Shape
00546 KLed::shape() const
00547 {
00548   return led_shape;
00549 }
00550 
00551 QColor
00552 KLed::color() const
00553 {
00554   return led_color;
00555 }
00556 
00557 KLed::Look
00558 KLed::look() const
00559 {
00560   return led_look;
00561 }
00562 
00563 void
00564 KLed::setState( State state )
00565 {
00566   if (led_state != state)
00567     {
00568       led_state = state;
00569       update();
00570     }
00571 }
00572 
00573 void
00574 KLed::toggleState()
00575 {
00576   led_state = (led_state == On) ? Off : On;
00577   // setColor(led_color);
00578   update();
00579 }
00580 
00581 void
00582 KLed::setShape(KLed::Shape s)
00583 {
00584   if(led_shape!=s)
00585     {
00586       led_shape = s;
00587       update();
00588     }
00589 }
00590 
00591 void
00592 KLed::setColor(const QColor& col)
00593 {
00594   if(led_color!=col) {
00595     led_color = col;
00596     d->offcolor = col.dark(d->dark_factor);
00597     update();
00598   }
00599 }
00600 
00601 void
00602 KLed::setDarkFactor(int darkfactor)
00603 {
00604   if (d->dark_factor != darkfactor) {
00605     d->dark_factor = darkfactor;
00606     d->offcolor = led_color.dark(darkfactor);
00607     update();
00608   }
00609 }
00610 
00611 int
00612 KLed::darkFactor() const
00613 {
00614   return d->dark_factor;
00615 }
00616 
00617 void
00618 KLed::setLook( Look look )
00619 {
00620   if(led_look!=look)
00621     {
00622       led_look = look;
00623       update();
00624     }
00625 }
00626 
00627 void
00628 KLed::toggle()
00629 {
00630   toggleState();
00631 }
00632 
00633 void
00634 KLed::on()
00635 {
00636   setState(On);
00637 }
00638 
00639 void
00640 KLed::off()
00641 {
00642   setState(Off);
00643 }
00644 
00645 QSize
00646 KLed::sizeHint() const
00647 {
00648   return QSize(16, 16);
00649 }
00650 
00651 QSize
00652 KLed::minimumSizeHint() const
00653 {
00654   return QSize(16, 16 );
00655 }
00656 
00657 void KLed::virtual_hook( int, void* )
00658 { /*BASE::virtual_hook( id, data );*/ }
00659 
00660 #include "kled.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:15:03 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001