• Skip to content
  • Skip to link menu
KDE 4.2 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     QBrush oldBrush = painter.brush();
00151     painter.setBrush( Qt::NoBrush );
00152     style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, this );
00153     painter.setBrush( oldBrush );
00154   }
00155 
00156 
00157   painter.end();
00158 }
00159 
00160 void KSelector::mousePressEvent( QMouseEvent *e )
00161 {
00162     setSliderDown(true);
00163     moveArrow( e->pos() );
00164 }
00165 
00166 void KSelector::mouseMoveEvent( QMouseEvent *e )
00167 {
00168   moveArrow( e->pos() );
00169 }
00170 
00171 void KSelector::mouseReleaseEvent( QMouseEvent *e )
00172 {
00173     moveArrow( e->pos() );
00174     setSliderDown(false);
00175 }
00176 
00177 void KSelector::wheelEvent( QWheelEvent *e )
00178 {
00179     int val = value() + e->delta()/120;
00180     setSliderDown(true);
00181     setValue( val );
00182     setSliderDown(false);
00183 }
00184 
00185 void KSelector::moveArrow( const QPoint &pos )
00186 {
00187     int val;
00188     int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00189     int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
00190 
00191     if ( orientation() == Qt::Vertical )
00192         val = ( maximum() - minimum() ) * (height() - pos.y() - iw)
00193             / (height() - iw * 2) + minimum();
00194     else
00195         val = ( maximum() - minimum() ) * ( pos.x() - iw)
00196             / (width() - iw * 2) + minimum();
00197 
00198     setValue( val );
00199     update();
00200 }
00201 
00202 QPoint KSelector::calcArrowPos( int val )
00203 {
00204     QPoint p;
00205     int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
00206     int iw = ( w < ARROWSIZE ) ? ARROWSIZE : w;
00207 
00208     if ( orientation() == Qt::Vertical )
00209     {
00210         p.setY( height() - iw - 1 - (height() - 2 * iw - 1) * val  / ( maximum() - minimum() ) );
00211 
00212         if ( d->arrowPE == QStyle::PE_IndicatorArrowRight ) {
00213             p.setX( 0 );
00214         } else {
00215             p.setX( width() - 5 );
00216         }
00217     }
00218     else
00219     {
00220         p.setX( iw + (width() - 2 * iw - 1) * val  / ( maximum() - minimum() ) );
00221 
00222         if ( d->arrowPE == QStyle::PE_IndicatorArrowDown ) {
00223             p.setY( 0 );
00224         } else {
00225             p.setY( height() - 5 );
00226         }
00227     }
00228 
00229     return p;
00230 }
00231 
00232 void KSelector::setArrowDirection( Qt::ArrowType direction )
00233 {
00234     switch ( direction ) {
00235         case Qt::UpArrow:
00236             if ( orientation() == Qt::Horizontal ) {
00237                 d->arrowPE = QStyle::PE_IndicatorArrowUp;
00238             } else {
00239                 d->arrowPE = QStyle::PE_IndicatorArrowLeft;
00240             }
00241             break;
00242         case Qt::DownArrow:
00243             if ( orientation() == Qt::Horizontal ) {
00244                 d->arrowPE = QStyle::PE_IndicatorArrowDown;
00245             } else {
00246                 d->arrowPE = QStyle::PE_IndicatorArrowRight;
00247             }
00248             break;
00249         case Qt::LeftArrow:
00250             if ( orientation() == Qt::Vertical ) {
00251                 d->arrowPE = QStyle::PE_IndicatorArrowLeft;
00252             } else {
00253                 d->arrowPE = QStyle::PE_IndicatorArrowDown;
00254             }
00255             break;
00256         case Qt::RightArrow:
00257             if ( orientation() == Qt::Vertical ) {
00258                 d->arrowPE = QStyle::PE_IndicatorArrowRight;
00259             } else {
00260                 d->arrowPE = QStyle::PE_IndicatorArrowUp;
00261             }
00262             break;
00263 
00264         case Qt::NoArrow:
00265             break;
00266     }
00267 }
00268 
00269 Qt::ArrowType KSelector::arrowDirection() const
00270 {
00271     switch ( d->arrowPE ) {
00272         case QStyle::PE_IndicatorArrowUp:
00273             return Qt::UpArrow;
00274             break;
00275         case QStyle::PE_IndicatorArrowDown:
00276             return Qt::DownArrow;
00277             break;
00278         case QStyle::PE_IndicatorArrowRight:
00279             return Qt::RightArrow;
00280             break;
00281         case QStyle::PE_IndicatorArrowLeft:
00282         default:
00283             return Qt::LeftArrow;
00284             break;
00285     }
00286 }
00287 
00288 void KSelector::drawContents( QPainter * )
00289 {}
00290 
00291 void KSelector::drawArrow( QPainter *painter, const QPoint &pos )
00292 {
00293     painter->setPen( QPen() );
00294     painter->setBrush( QBrush( palette().color(QPalette::ButtonText) ) );
00295 
00296     QStyleOption o;
00297 
00298     if ( orientation() == Qt::Vertical ) {
00299         o.rect = QRect( pos.x(), pos.y() - ARROWSIZE / 2,
00300                         ARROWSIZE, ARROWSIZE );
00301     } else {
00302         o.rect = QRect( pos.x() - ARROWSIZE / 2, pos.y(),
00303                         ARROWSIZE, ARROWSIZE );
00304 
00305     }
00306     style()->drawPrimitive( d->arrowPE, &o, painter, this );
00307 }
00308 
00309 //----------------------------------------------------------------------------
00310 
00311 KGradientSelector::KGradientSelector( QWidget *parent )
00312     : KSelector( parent ), d(new KGradientSelectorPrivate(this))
00313 {
00314     d->init();
00315 }
00316 
00317 
00318 KGradientSelector::KGradientSelector( Qt::Orientation o, QWidget *parent )
00319     : KSelector( o, parent ), d(new KGradientSelectorPrivate(this))
00320 {
00321     d->init();
00322 }
00323 
00324 
00325 KGradientSelector::~KGradientSelector()
00326 {
00327     delete d;
00328 }
00329 
00330 
00331 void KGradientSelector::KGradientSelectorPrivate::init()
00332 {
00333     color1.setRgb( 0, 0, 0 );
00334     color2.setRgb( 255, 255, 255 );
00335 
00336     text1 = text2 = "";
00337 }
00338 
00339 
00340 void KGradientSelector::drawContents( QPainter *painter )
00341 {
00342   QImage image( contentsRect().width(), contentsRect().height(), QImage::Format_RGB32 );
00343 
00344   QColor col;
00345   float scale;
00346 
00347   int redDiff   = d->color2.red() - d->color1.red();
00348   int greenDiff = d->color2.green() - d->color1.green();
00349   int blueDiff  = d->color2.blue() - d->color1.blue();
00350 
00351   if ( orientation() == Qt::Vertical )
00352   {
00353     for ( int y = 0; y < image.height(); y++ )
00354     {
00355       scale = 1.0 * y / image.height();
00356       col.setRgb( d->color1.red() + int(redDiff*scale),
00357             d->color1.green() + int(greenDiff*scale),
00358             d->color1.blue() + int(blueDiff*scale) );
00359 
00360       unsigned int *p = (uint *) image.scanLine( y );
00361       for ( int x = 0; x < image.width(); x++ )
00362         *p++ = col.rgb();
00363     }
00364   }
00365   else
00366   {
00367     unsigned int *p = (uint *) image.scanLine( 0 );
00368 
00369     for ( int x = 0; x < image.width(); x++ )
00370     {
00371       scale = 1.0 * x / image.width();
00372       col.setRgb( d->color1.red() + int(redDiff*scale),
00373             d->color1.green() + int(greenDiff*scale),
00374             d->color1.blue() + int(blueDiff*scale) );
00375       *p++ = col.rgb();
00376     }
00377 
00378     for ( int y = 1; y < image.height(); y++ )
00379       memcpy( image.scanLine( y ), image.scanLine( y - 1),
00380          sizeof( unsigned int ) * image.width() );
00381   }
00382 
00383   /*
00384   QColor ditherPalette[8];
00385 
00386   for ( int s = 0; s < 8; s++ )
00387     ditherPalette[s].setRgb( d->color1.red() + redDiff * s / 8,
00388                 d->color1.green() + greenDiff * s / 8,
00389                 d->color1.blue() + blueDiff * s / 8 );
00390 
00391   KImageEffect::dither( image, ditherPalette, 8 );
00392   */
00393 
00394   QPixmap p = QPixmap::fromImage(image);
00395 
00396   painter->drawPixmap( contentsRect().x(), contentsRect().y(), p );
00397 
00398   if ( orientation() == Qt::Vertical )
00399   {
00400     int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
00401     int xPos = contentsRect().left() + (contentsRect().width() -
00402        painter->fontMetrics().width( d->text2 )) / 2;
00403     QPen pen( d->color2 );
00404     painter->setPen( pen );
00405     painter->drawText( xPos, yPos, d->text2 );
00406 
00407     yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
00408     xPos = contentsRect().left() + (contentsRect().width() -
00409       painter->fontMetrics().width( d->text1 )) / 2;
00410     pen.setColor( d->color1 );
00411     painter->setPen( pen );
00412     painter->drawText( xPos, yPos, d->text1 );
00413   }
00414   else
00415   {
00416     int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2;
00417 
00418     QPen pen( d->color2 );
00419     painter->setPen( pen );
00420     painter->drawText( contentsRect().left() + 2, yPos, d->text1 );
00421 
00422     pen.setColor( d->color1 );
00423     painter->setPen( pen );
00424     painter->drawText( contentsRect().right() -
00425        painter->fontMetrics().width( d->text2 ) - 2, yPos, d->text2 );
00426   }
00427 }
00428 
00429 QSize KGradientSelector::minimumSize() const
00430 {
00431     return sizeHint();
00432 }
00433 
00434 void KGradientSelector::setColors( const QColor &col1, const QColor &col2 )
00435 {
00436   d->color1 = col1;
00437   d->color2 = col2;
00438   update();
00439 }
00440 
00441 void KGradientSelector::setText( const QString &t1, const QString &t2 )
00442 {
00443   d->text1 = t1;
00444   d->text2 = t2;
00445   update();
00446 }
00447 
00448 void KGradientSelector::setFirstColor( const QColor &col )
00449 {
00450   d->color1 = col;
00451   update();
00452 }
00453 
00454 void KGradientSelector::setSecondColor( const QColor &col )
00455 {
00456   d->color2 = col;
00457   update();
00458 }
00459 
00460 void KGradientSelector::setFirstText( const QString &t )
00461 {
00462   d->text1 = t;
00463   update();
00464 }
00465 
00466 void KGradientSelector::setSecondText( const QString &t )
00467 {
00468   d->text2 = t;
00469   update();
00470 }
00471 
00472 QColor KGradientSelector::firstColor() const
00473 {
00474   return d->color1;
00475 }
00476 
00477 QColor KGradientSelector::secondColor() const
00478 {
00479   return d->color2;
00480 }
00481 
00482 QString KGradientSelector::firstText() const
00483 {
00484   return d->text1;
00485 }
00486 
00487 QString KGradientSelector::secondText() const
00488 {
00489   return d->text2;
00490 }
00491 
00492 #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
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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