kdeui Library API Documentation

kselect.cpp

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., 59 Temple Place - Suite 330,
00017     Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <qimage.h>
00021 #include <qpainter.h>
00022 #include <qdrawutil.h>
00023 #include <kimageeffect.h>
00024 #include "kselect.h"
00025 
00026 #define STORE_W 8
00027 #define STORE_W2 STORE_W * 2
00028 
00029 //-----------------------------------------------------------------------------
00030 /*
00031  * 2D value selector.
00032  * The contents of the selector are drawn by derived class.
00033  */
00034 
00035 KXYSelector::KXYSelector( QWidget *parent, const char *name )
00036     : QWidget( parent, name )
00037 {
00038     xPos = 0;
00039     yPos = 0;
00040     minX = 0;
00041     minY = 0;
00042     maxX = 100;
00043     maxY = 100;
00044     store.setOptimization( QPixmap::BestOptim );
00045     store.resize( STORE_W2, STORE_W2 );
00046 }
00047 
00048 
00049 KXYSelector::~KXYSelector()
00050 {}
00051 
00052 
00053 void KXYSelector::setRange( int _minX, int _minY, int _maxX, int _maxY )
00054 {
00055     px = 2;
00056     py = 2;
00057     minX = _minX;
00058     minY = _minY;
00059     maxX = _maxX;
00060     maxY = _maxY;
00061 }
00062 
00063 void KXYSelector::setValues( int _xPos, int _yPos )
00064 {
00065     xPos = _xPos;
00066     yPos = _yPos;
00067 
00068     if ( xPos > maxX )
00069         xPos = maxX;
00070     else if ( xPos < minX )
00071         xPos = minX;
00072     
00073     if ( yPos > maxY )
00074         yPos = maxY;
00075     else if ( yPos < minY )
00076         yPos = minY;
00077 
00078     int xp = 2 + (width() - 4) * xPos / (maxX - minX);
00079     int yp = height() - 2 - (height() - 4) * yPos / (maxY - minY);
00080 
00081     setPosition( xp, yp );
00082 }
00083 
00084 QRect KXYSelector::contentsRect() const
00085 {
00086     return QRect( 2, 2, width()-4, height()-4 );
00087 }
00088 
00089 void KXYSelector::paintEvent( QPaintEvent *ev )
00090 {
00091     QRect cursorRect( px - STORE_W, py - STORE_W, STORE_W2, STORE_W2);
00092     QRect paintRect = ev->rect();
00093 
00094     QPainter painter;
00095     painter.begin( this );
00096 
00097     QBrush brush;
00098     qDrawShadePanel( &painter, 0, 0, width(), height(), colorGroup(),
00099             true, 2, &brush );
00100 
00101     drawContents( &painter );
00102     if (paintRect.contains(cursorRect))
00103     {
00104        bitBlt( &store, 0, 0, this, px - STORE_W, py - STORE_W,
00105         STORE_W2, STORE_W2, CopyROP );
00106        drawCursor( &painter, px, py );
00107         }
00108         else if (paintRect.intersects(cursorRect))
00109         {
00110            repaint( cursorRect, false);
00111         }
00112 
00113     painter.end();
00114 }
00115 
00116 void KXYSelector::mousePressEvent( QMouseEvent *e )
00117 {
00118     int xVal, yVal;
00119     valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal );
00120     setValues( xVal, yVal );
00121 
00122     emit valueChanged( xPos, yPos );
00123 }
00124 
00125 void KXYSelector::mouseMoveEvent( QMouseEvent *e )
00126 {
00127     int xVal, yVal;
00128     valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal );
00129     setValues( xVal, yVal );
00130     
00131     emit valueChanged( xPos, yPos );
00132 }
00133 
00134 void KXYSelector::wheelEvent( QWheelEvent *e )
00135 {
00136     if ( e->orientation() == Qt::Horizontal )
00137         setValues( xValue() + e->delta()/120, yValue() );
00138     else    
00139         setValues( xValue(), yValue() + e->delta()/120 );
00140     
00141     emit valueChanged( xPos, yPos );
00142 }
00143 
00144 void KXYSelector::valuesFromPosition( int x, int y, int &xVal, int &yVal ) const
00145 {
00146     xVal = ( (maxX-minX) * (x-2) ) / ( width()-4 );
00147     yVal = maxY - ( ( (maxY-minY) * (y-2) ) / ( height()-4 ) );
00148     
00149     if ( xVal > maxX )
00150         xVal = maxX;
00151     else if ( xVal < minX )
00152         xVal = minX;
00153     
00154     if ( yVal > maxY )
00155         yVal = maxY;
00156     else if ( yVal < minY )
00157         yVal = minY;
00158 }
00159 
00160 void KXYSelector::setPosition( int xp, int yp )
00161 {
00162     if ( xp < 2 )
00163         xp = 2;
00164     else if ( xp > width() - 2 )
00165         xp = width() - 2;
00166 
00167     if ( yp < 2 )
00168         yp = 2;
00169     else if ( yp > height() - 2 )
00170         yp = height() - 2;
00171 
00172     QPainter painter;
00173     painter.begin( this );
00174 
00175     bitBlt( this, px - STORE_W, py - STORE_W, &store, 0, 0,
00176             STORE_W2, STORE_W2, CopyROP );
00177     bitBlt( &store, 0, 0, this, xp - STORE_W, yp - STORE_W,
00178             STORE_W2, STORE_W2, CopyROP );
00179     drawCursor( &painter, xp, yp );
00180     px = xp;
00181     py = yp;
00182 
00183     painter.end();
00184 }
00185 
00186 void KXYSelector::drawContents( QPainter * )
00187 {}
00188 
00189 
00190 void KXYSelector::drawCursor( QPainter *p, int xp, int yp )
00191 {
00192     p->setPen( QPen( white ) );
00193 
00194     p->drawLine( xp - 6, yp - 6, xp - 2, yp - 2 );
00195     p->drawLine( xp - 6, yp + 6, xp - 2, yp + 2 );
00196     p->drawLine( xp + 6, yp - 6, xp + 2, yp - 2 );
00197     p->drawLine( xp + 6, yp + 6, xp + 2, yp + 2 );
00198 }
00199 
00200 //-----------------------------------------------------------------------------
00201 /*
00202  * 1D value selector with contents drawn by derived class.
00203  * See KColorDialog for example.
00204  */
00205 
00206 
00207 KSelector::KSelector( QWidget *parent, const char *name )
00208     : QWidget( parent, name ), QRangeControl()
00209 {
00210     _orientation = Horizontal;
00211     _indent = true;
00212 }
00213 
00214 KSelector::KSelector( Orientation o, QWidget *parent, const char *name )
00215     : QWidget( parent, name ), QRangeControl()
00216 {
00217     _orientation = o;
00218     _indent = true;
00219 }
00220 
00221 
00222 KSelector::~KSelector()
00223 {}
00224 
00225 
00226 QRect KSelector::contentsRect() const
00227 {
00228     if ( orientation() == Vertical )
00229         return QRect( 2, 5, width()-9, height()-10 );
00230     else
00231         return QRect( 5, 2, width()-10, height()-9 );
00232 }
00233 
00234 void KSelector::paintEvent( QPaintEvent * )
00235 {
00236     QPainter painter;
00237 
00238     painter.begin( this );
00239 
00240     drawContents( &painter );
00241 
00242     QBrush brush;
00243 
00244     if ( indent() )
00245     {
00246         if ( orientation() == Vertical )
00247             qDrawShadePanel( &painter, 0, 3, width()-5, height()-6,
00248                 colorGroup(), true, 2, &brush );
00249         else
00250             qDrawShadePanel( &painter, 3, 0, width()-6, height()-5,
00251                 colorGroup(), true, 2, &brush );
00252     }
00253 
00254     QPoint pos = calcArrowPos( value() );
00255     drawArrow( &painter, true, pos );   
00256 
00257     painter.end();
00258 }
00259 
00260 void KSelector::mousePressEvent( QMouseEvent *e )
00261 {
00262     moveArrow( e->pos() );
00263 }
00264 
00265 void KSelector::mouseMoveEvent( QMouseEvent *e )
00266 {
00267     moveArrow( e->pos() );
00268 }
00269 
00270 void KSelector::wheelEvent( QWheelEvent *e )
00271 {
00272     int val = value() + e->delta()/120;
00273     setValue( val );
00274 }
00275 
00276 void KSelector::valueChange()
00277 {
00278     QPainter painter;
00279     QPoint pos;
00280 
00281     painter.begin( this );
00282 
00283     pos = calcArrowPos( prevValue() );
00284     drawArrow( &painter, false, pos );   
00285 
00286     pos = calcArrowPos( value() );
00287     drawArrow( &painter, true, pos );   
00288 
00289     painter.end();
00290 
00291     emit valueChanged( value() );
00292 }
00293 
00294 void KSelector::moveArrow( const QPoint &pos )
00295 {
00296     int val;
00297 
00298     if ( orientation() == Vertical )
00299         val = ( maxValue() - minValue() ) * (height()-pos.y()-3)
00300                 / (height()-10) + minValue();
00301     else
00302         val = ( maxValue() - minValue() ) * (width()-pos.x()-3)
00303                 / (width()-10) + minValue();
00304 
00305     setValue( val );
00306 }
00307 
00308 QPoint KSelector::calcArrowPos( int val )
00309 {
00310     QPoint p;
00311 
00312     if ( orientation() == Vertical )
00313     {
00314         p.setY( height() - ( (height()-10) * val
00315                 / ( maxValue() - minValue() ) + 5 ) );
00316         p.setX( width() - 5 );
00317     }
00318     else
00319     {
00320         p.setX( width() - ( (width()-10) * val
00321                 / ( maxValue() - minValue() ) + 5 ) );
00322         p.setY( height() - 5 );
00323     }
00324 
00325     return p;
00326 }
00327 
00328 void KSelector::drawContents( QPainter * )
00329 {}
00330 
00331 void KSelector::drawArrow( QPainter *painter, bool show, const QPoint &pos )
00332 {
00333   if ( show )
00334   {
00335     QPointArray array(3);
00336 
00337     painter->setPen( QPen() );
00338     painter->setBrush( QBrush( colorGroup().buttonText() ) );
00339     if ( orientation() == Vertical )
00340     {
00341       array.setPoint( 0, pos.x()+0, pos.y()+0 );
00342       array.setPoint( 1, pos.x()+5, pos.y()+5 );
00343       array.setPoint( 2, pos.x()+5, pos.y()-5 );
00344     }
00345     else
00346     {
00347       array.setPoint( 0, pos.x()+0, pos.y()+0 );
00348       array.setPoint( 1, pos.x()+5, pos.y()+5 );
00349       array.setPoint( 2, pos.x()-5, pos.y()+5 );
00350     }
00351 
00352     painter->drawPolygon( array );
00353   } 
00354   else 
00355   {
00356     if ( orientation() == Vertical )
00357     {
00358        repaint(pos.x(), pos.y()-5, 6, 11, true);
00359     }
00360     else
00361     {
00362        repaint(pos.x()-5, pos.y(), 11, 6, true);
00363     }
00364   }
00365 }
00366 
00367 //----------------------------------------------------------------------------
00368 
00369 KGradientSelector::KGradientSelector( QWidget *parent, const char *name )
00370     : KSelector( parent, name )
00371 {
00372     init();
00373 }
00374 
00375 
00376 KGradientSelector::KGradientSelector( Orientation o, QWidget *parent,
00377         const char *name )
00378     : KSelector( o, parent, name )
00379 {
00380     init();
00381 }
00382 
00383 
00384 KGradientSelector::~KGradientSelector()
00385 {}
00386 
00387 
00388 void KGradientSelector::init()
00389 {
00390     color1.setRgb( 0, 0, 0 );
00391     color2.setRgb( 255, 255, 255 );
00392     
00393     text1 = text2 = "";
00394 }
00395 
00396 
00397 void KGradientSelector::drawContents( QPainter *painter )
00398 {
00399     QImage image( contentsRect().width(), contentsRect().height(), 32 );
00400 
00401     QColor col;
00402     float scale;
00403 
00404     int redDiff   = color2.red() - color1.red();
00405     int greenDiff = color2.green() - color1.green();
00406     int blueDiff  = color2.blue() - color1.blue();
00407 
00408     if ( orientation() == Vertical )
00409     {
00410         for ( int y = 0; y < image.height(); y++ )
00411         {
00412             scale = 1.0 * y / image.height();
00413             col.setRgb( color1.red() + int(redDiff*scale),
00414                         color1.green() + int(greenDiff*scale),
00415                         color1.blue() + int(blueDiff*scale) );
00416 
00417             unsigned int *p = (uint *) image.scanLine( y );
00418             for ( int x = 0; x < image.width(); x++ )
00419                 *p++ = col.rgb();
00420         }
00421     }
00422     else
00423     {
00424         unsigned int *p = (uint *) image.scanLine( 0 );
00425 
00426         for ( int x = 0; x < image.width(); x++ )
00427         {
00428             scale = 1.0 * x / image.width();
00429             col.setRgb( color1.red() + int(redDiff*scale),
00430                         color1.green() + int(greenDiff*scale),
00431                         color1.blue() + int(blueDiff*scale) );
00432             *p++ = col.rgb();
00433         }
00434 
00435         for ( int y = 1; y < image.height(); y++ )
00436             memcpy( image.scanLine( y ), image.scanLine( y - 1),
00437                  sizeof( unsigned int ) * image.width() );
00438     }
00439 
00440     QColor ditherPalette[8];
00441 
00442     for ( int s = 0; s < 8; s++ )
00443         ditherPalette[s].setRgb( color1.red() + redDiff * s / 8,
00444                                 color1.green() + greenDiff * s / 8,
00445                                 color1.blue() + blueDiff * s / 8 );
00446 
00447     KImageEffect::dither( image, ditherPalette, 8 );
00448 
00449     QPixmap p;
00450     p.convertFromImage( image );
00451 
00452     painter->drawPixmap( contentsRect().x(), contentsRect().y(), p );
00453 
00454     if ( orientation() == Vertical )
00455     {
00456         int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
00457         int xPos = contentsRect().left() + (contentsRect().width() -
00458              painter->fontMetrics().width( text2 )) / 2;
00459         QPen pen( color2 );
00460         painter->setPen( pen );
00461         painter->drawText( xPos, yPos, text2 );
00462 
00463         yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
00464         xPos = contentsRect().left() + (contentsRect().width() - 
00465             painter->fontMetrics().width( text1 )) / 2;
00466         pen.setColor( color1 );
00467         painter->setPen( pen );
00468         painter->drawText( xPos, yPos, text1 );
00469     }
00470     else
00471     {
00472         int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2;
00473 
00474         QPen pen( color2 );
00475         painter->setPen( pen );
00476         painter->drawText( contentsRect().left() + 2, yPos, text1 );
00477 
00478         pen.setColor( color1 );
00479         painter->setPen( pen );
00480         painter->drawText( contentsRect().right() -
00481              painter->fontMetrics().width( text2 ) - 2, yPos, text2 );
00482     }
00483 }
00484 
00485 //-----------------------------------------------------------------------------
00486 
00487 void KXYSelector::virtual_hook( int, void* )
00488 { /*BASE::virtual_hook( id, data );*/ }
00489 
00490 void KSelector::virtual_hook( int, void* )
00491 { /*BASE::virtual_hook( id, data );*/ }
00492 
00493 void KGradientSelector::virtual_hook( int id, void* data )
00494 { KSelector::virtual_hook( id, data ); }
00495 
00496 #include "kselect.moc"
00497 
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 12 09:04:44 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003