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

KDEUI

kselector.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1997 Martin Jones (mjones@kde.org)
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 "kselector.h"
00021 
00022 #include <QImage>
00023 #include <QPainter>
00024 #include <QPaintEvent>
00025 #include <QPixmap>
00026 #include <QStyle>
00027 #include <QStyleOption>
00028 
00029 #include <stdio.h>
00030 
00031 //-----------------------------------------------------------------------------
00032 /*
00033  * 1D value selector with contents drawn by derived class.
00034  * See KColorDialog for example.
00035  */
00036 
00037 #define ARROWSIZE 5
00038 
00039 class KSelector::Private
00040 {
00041 public:
00042     Private()
00043     {
00044         arrowPE = QStyle::PE_IndicatorArrowLeft;
00045         m_indent = true;
00046     }
00047 
00048     bool m_indent;
00049     QStyle::PrimitiveElement arrowPE;
00050 };
00051 
00052 class KGradientSelector::KGradientSelectorPrivate
00053 {
00054 public:
00055   KGradientSelectorPrivate(KGradientSelector *q): q(q) {}
00056 
00057   void init();
00058 
00059   KGradientSelector *q;
00060   QColor color1;
00061   QColor color2;
00062   QString text1;
00063   QString text2;
00064 };
00065 
00066 KSelector::KSelector( QWidget *parent )
00067   : QAbstractSlider( parent )
00068  , d(new Private)
00069 {
00070     setOrientation(Qt::Horizontal);
00071 }
00072 
00073 KSelector::KSelector( Qt::Orientation o, QWidget *parent )
00074   : QAbstractSlider( parent )
00075  , d(new Private)
00076 {
00077     setOrientation(o);
00078     if(o == Qt::Horizontal)
00079         setArrowDirection(Qt::UpArrow);
00080 }
00081 
00082 KSelector::~KSelector()
00083 {
00084     delete d;
00085 }
00086 
00087 void KSelector::setIndent( bool i )
00088 {
00089     d->m_indent = i;
00090 }
00091 
00092 bool KSelector::indent() const
00093 {
00094     return d->m_indent;
00095 }
00096 
00097 QRect KSelector::contentsRect() const
00098 {
00099     int w = indent() ? style()->pixelMetric( QStyle::PM_DefaultFrameWidth ) : 0;
00100     //TODO: is the height:width ratio of an indicator arrow always 2:1? hm.
00101     int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
00102 
00103     if ( orientation() == Qt::Vertical ) {
00104         if ( arrowDirection() == Qt::RightArrow ) {
00105             return QRect( w + ARROWSIZE, iw,
00106                           width() - w*2 - ARROWSIZE,
00107                           height() - iw*2 );
00108         } else {
00109             return QRect( w, iw,
00110                           width() - w*2 - ARROWSIZE,
00111                           height() - iw*2 );
00112         }
00113     } else { // Qt::Horizontal
00114         if ( arrowDirection() == Qt::UpArrow ) {
00115             return QRect( iw, w,
00116                           width() - 2*iw,
00117                           height() - w*2 - ARROWSIZE );
00118         } else {
00119             return QRect( iw, w + ARROWSIZE,
00120                           width() - 2*iw,
00121                           height() - w*2 - ARROWSIZE );
00122         }
00123     }
00124 }
00125 
00126 void KSelector::paintEvent( QPaintEvent * )
00127 {
00128   QPainter painter;
00129   int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
00130   int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
00131 
00132   painter.begin( this );
00133 
00134   drawContents( &painter );
00135 
00136   QBrush brush;
00137 
00138   QPoint pos = calcArrowPos( value() );
00139   drawArrow( &painter, pos );
00140 
00141   if ( indent() )
00142   {
00143     QStyleOptionFrame opt;
00144     opt.initFrom( this );
00145     opt.state = QStyle::State_Sunken;
00146     if ( orientation() == Qt::Vertical )
00147       opt.rect.adjust( 0, iw - w, -5, w - iw );
00148     else
00149       opt.rect.adjust(iw - w, 0, w - iw, -5);
00150     style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, this );
00151   }
00152 
00153 
00154   painter.end();
00155 }
00156 
00157 void KSelector::mousePressEvent( QMouseEvent *e )
00158 {
00159     setSliderDown(true);
00160     moveArrow( e->pos() );
00161 }
00162 
00163 void KSelector::mouseMoveEvent( QMouseEvent *e )
00164 {
00165   moveArrow( e->pos() );
00166 }
00167 
00168 void KSelector::mouseReleaseEvent( QMouseEvent *e )
00169 {
00170     moveArrow( e->pos() );
00171     setSliderDown(false);
00172 }
00173 
00174 void KSelector::wheelEvent( QWheelEvent *e )
00175 {
00176     int val = value() + e->delta()/120;
00177     setSliderDown(true);
00178     setValue( val );
00179     setSliderDown(false);
00180 }
00181 
00182 void KSelector::moveArrow( const QPoint &pos )
00183 {
00184     int val;
00185     int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00186     int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
00187 
00188     if ( orientation() == Qt::Vertical )
00189         val = ( maximum() - minimum() ) * (height() - pos.y() - iw)
00190             / (height() - iw * 2) + minimum();
00191     else
00192         val = ( maximum() - minimum() ) * ( pos.x() - iw)
00193             / (width() - iw * 2) + minimum();
00194 
00195     setValue( val );
00196     update();
00197 }
00198 
00199 QPoint KSelector::calcArrowPos( int val )
00200 {
00201     QPoint p;
00202     int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
00203     int iw = ( w < ARROWSIZE ) ? ARROWSIZE : w;
00204 
00205     if ( orientation() == Qt::Vertical )
00206     {
00207         p.setY( height() - iw - 1 - (height() - 2 * iw - 1) * val  / ( maximum() - minimum() ) );
00208 
00209         if ( d->arrowPE == QStyle::PE_IndicatorArrowRight ) {
00210             p.setX( 0 );
00211         } else {
00212             p.setX( width() - 5 );
00213         }
00214     }
00215     else
00216     {
00217         p.setX( iw + (width() - 2 * iw - 1) * val  / ( maximum() - minimum() ) );
00218 
00219         if ( d->arrowPE == QStyle::PE_IndicatorArrowDown ) {
00220             p.setY( 0 );
00221         } else {
00222             p.setY( height() - 5 );
00223         }
00224     }
00225 
00226     return p;
00227 }
00228 
00229 void KSelector::setArrowDirection( Qt::ArrowType direction )
00230 {
00231     switch ( direction ) {
00232         case Qt::UpArrow:
00233             if ( orientation() == Qt::Horizontal ) {
00234                 d->arrowPE = QStyle::PE_IndicatorArrowUp;
00235             } else {
00236                 d->arrowPE = QStyle::PE_IndicatorArrowLeft;
00237             }
00238             break;
00239         case Qt::DownArrow:
00240             if ( orientation() == Qt::Horizontal ) {
00241                 d->arrowPE = QStyle::PE_IndicatorArrowDown;
00242             } else {
00243                 d->arrowPE = QStyle::PE_IndicatorArrowRight;
00244             }
00245             break;
00246         case Qt::LeftArrow:
00247             if ( orientation() == Qt::Vertical ) {
00248                 d->arrowPE = QStyle::PE_IndicatorArrowLeft;
00249             } else {
00250                 d->arrowPE = QStyle::PE_IndicatorArrowDown;
00251             }
00252             break;
00253         case Qt::RightArrow:
00254             if ( orientation() == Qt::Vertical ) {
00255                 d->arrowPE = QStyle::PE_IndicatorArrowRight;
00256             } else {
00257                 d->arrowPE = QStyle::PE_IndicatorArrowUp;
00258             }
00259             break;
00260 
00261         case Qt::NoArrow:
00262             break;
00263     }
00264 }
00265 
00266 Qt::ArrowType KSelector::arrowDirection() const
00267 {
00268     switch ( d->arrowPE ) {
00269         case QStyle::PE_IndicatorArrowUp:
00270             return Qt::UpArrow;
00271             break;
00272         case QStyle::PE_IndicatorArrowDown:
00273             return Qt::DownArrow;
00274             break;
00275         case QStyle::PE_IndicatorArrowRight:
00276             return Qt::RightArrow;
00277             break;
00278         case QStyle::PE_IndicatorArrowLeft:
00279         default:
00280             return Qt::LeftArrow;
00281             break;
00282     }
00283 }
00284 
00285 void KSelector::drawContents( QPainter * )
00286 {}
00287 
00288 void KSelector::drawArrow( QPainter *painter, const QPoint &pos )
00289 {
00290     painter->setPen( QPen() );
00291     painter->setBrush( QBrush( palette().color(QPalette::ButtonText) ) );
00292 
00293     QStyleOption o;
00294 
00295     if ( orientation() == Qt::Vertical ) {
00296         o.rect = QRect( pos.x(), pos.y() - ARROWSIZE / 2,
00297                         ARROWSIZE, ARROWSIZE );
00298     } else {
00299         o.rect = QRect( pos.x() - ARROWSIZE / 2, pos.y(),
00300                         ARROWSIZE, ARROWSIZE );
00301 
00302     }
00303     style()->drawPrimitive( d->arrowPE, &o, painter, this );
00304 }
00305 
00306 //----------------------------------------------------------------------------
00307 
00308 KGradientSelector::KGradientSelector( QWidget *parent )
00309     : KSelector( parent ), d(new KGradientSelectorPrivate(this))
00310 {
00311     d->init();
00312 }
00313 
00314 
00315 KGradientSelector::KGradientSelector( Qt::Orientation o, QWidget *parent )
00316     : KSelector( o, parent ), d(new KGradientSelectorPrivate(this))
00317 {
00318     d->init();
00319 }
00320 
00321 
00322 KGradientSelector::~KGradientSelector()
00323 {
00324     delete d;
00325 }
00326 
00327 
00328 void KGradientSelector::KGradientSelectorPrivate::init()
00329 {
00330     color1.setRgb( 0, 0, 0 );
00331     color2.setRgb( 255, 255, 255 );
00332 
00333     text1 = text2 = "";
00334 }
00335 
00336 
00337 void KGradientSelector::drawContents( QPainter *painter )
00338 {
00339   QImage image( contentsRect().width(), contentsRect().height(), QImage::Format_RGB32 );
00340 
00341   QColor col;
00342   float scale;
00343 
00344   int redDiff   = d->color2.red() - d->color1.red();
00345   int greenDiff = d->color2.green() - d->color1.green();
00346   int blueDiff  = d->color2.blue() - d->color1.blue();
00347 
00348   if ( orientation() == Qt::Vertical )
00349   {
00350     for ( int y = 0; y < image.height(); y++ )
00351     {
00352       scale = 1.0 * y / image.height();
00353       col.setRgb( d->color1.red() + int(redDiff*scale),
00354             d->color1.green() + int(greenDiff*scale),
00355             d->color1.blue() + int(blueDiff*scale) );
00356 
00357       unsigned int *p = (uint *) image.scanLine( y );
00358       for ( int x = 0; x < image.width(); x++ )
00359         *p++ = col.rgb();
00360     }
00361   }
00362   else
00363   {
00364     unsigned int *p = (uint *) image.scanLine( 0 );
00365 
00366     for ( int x = 0; x < image.width(); x++ )
00367     {
00368       scale = 1.0 * x / image.width();
00369       col.setRgb( d->color1.red() + int(redDiff*scale),
00370             d->color1.green() + int(greenDiff*scale),
00371             d->color1.blue() + int(blueDiff*scale) );
00372       *p++ = col.rgb();
00373     }
00374 
00375     for ( int y = 1; y < image.height(); y++ )
00376       memcpy( image.scanLine( y ), image.scanLine( y - 1),
00377          sizeof( unsigned int ) * image.width() );
00378   }
00379 
00380   /*
00381   QColor ditherPalette[8];
00382 
00383   for ( int s = 0; s < 8; s++ )
00384     ditherPalette[s].setRgb( d->color1.red() + redDiff * s / 8,
00385                 d->color1.green() + greenDiff * s / 8,
00386                 d->color1.blue() + blueDiff * s / 8 );
00387 
00388   KImageEffect::dither( image, ditherPalette, 8 );
00389   */
00390 
00391   QPixmap p = QPixmap::fromImage(image);
00392 
00393   painter->drawPixmap( contentsRect().x(), contentsRect().y(), p );
00394 
00395   if ( orientation() == Qt::Vertical )
00396   {
00397     int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
00398     int xPos = contentsRect().left() + (contentsRect().width() -
00399        painter->fontMetrics().width( d->text2 )) / 2;
00400     QPen pen( d->color2 );
00401     painter->setPen( pen );
00402     painter->drawText( xPos, yPos, d->text2 );
00403 
00404     yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
00405     xPos = contentsRect().left() + (contentsRect().width() -
00406       painter->fontMetrics().width( d->text1 )) / 2;
00407     pen.setColor( d->color1 );
00408     painter->setPen( pen );
00409     painter->drawText( xPos, yPos, d->text1 );
00410   }
00411   else
00412   {
00413     int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2;
00414 
00415     QPen pen( d->color2 );
00416     painter->setPen( pen );
00417     painter->drawText( contentsRect().left() + 2, yPos, d->text1 );
00418 
00419     pen.setColor( d->color1 );
00420     painter->setPen( pen );
00421     painter->drawText( contentsRect().right() -
00422        painter->fontMetrics().width( d->text2 ) - 2, yPos, d->text2 );
00423   }
00424 }
00425 
00426 QSize KGradientSelector::minimumSize() const
00427 {
00428     return sizeHint();
00429 }
00430 
00431 void KGradientSelector::setColors( const QColor &col1, const QColor &col2 )
00432 {
00433   d->color1 = col1;
00434   d->color2 = col2;
00435   update();
00436 }
00437 
00438 void KGradientSelector::setText( const QString &t1, const QString &t2 )
00439 {
00440   d->text1 = t1;
00441   d->text2 = t2;
00442   update();
00443 }
00444 
00445 void KGradientSelector::setFirstColor( const QColor &col )
00446 {
00447   d->color1 = col;
00448   update();
00449 }
00450 
00451 void KGradientSelector::setSecondColor( const QColor &col )
00452 {
00453   d->color2 = col;
00454   update();
00455 }
00456 
00457 void KGradientSelector::setFirstText( const QString &t )
00458 {
00459   d->text1 = t;
00460   update();
00461 }
00462 
00463 void KGradientSelector::setSecondText( const QString &t )
00464 {
00465   d->text2 = t;
00466   update();
00467 }
00468 
00469 QColor KGradientSelector::firstColor() const
00470 {
00471   return d->color1;
00472 }
00473 
00474 QColor KGradientSelector::secondColor() const
00475 {
00476   return d->color2;
00477 }
00478 
00479 QString KGradientSelector::firstText() const
00480 {
00481   return d->text1;
00482 }
00483 
00484 QString KGradientSelector::secondText() const
00485 {
00486   return d->text2;
00487 }
00488 
00489 #include "kselector.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
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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