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