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     setPosition( e->pos().x() - 2, e->pos().y() - 2 );
00119 
00120     emit valueChanged( xPos, yPos );
00121 }
00122 
00123 void KXYSelector::mouseMoveEvent( QMouseEvent *e )
00124 {
00125     setPosition( e->pos().x() - 2, e->pos().y() - 2 );
00126 
00127     emit valueChanged( xPos, yPos );
00128 }
00129 
00130 void KXYSelector::setPosition( int xp, int yp )
00131 {
00132     if ( xp < 2 )
00133         xp = 2;
00134     else if ( xp > width() - 2 )
00135         xp = width() - 2;
00136 
00137     if ( yp < 2 )
00138         yp = 2;
00139     else if ( yp > height() - 2 )
00140         yp = height() - 2;
00141 
00142     QPainter painter;
00143     painter.begin( this );
00144 
00145     bitBlt( this, px - STORE_W, py - STORE_W, &store, 0, 0,
00146             STORE_W2, STORE_W2, CopyROP );
00147     bitBlt( &store, 0, 0, this, xp - STORE_W, yp - STORE_W,
00148             STORE_W2, STORE_W2, CopyROP );
00149     drawCursor( &painter, xp, yp );
00150     px = xp;
00151     py = yp;
00152 
00153     painter.end();
00154 
00155     xPos = ( (maxX-minX) * (xp-2) ) / ( width()-4 );
00156     yPos = maxY - ( ( (maxY-minY) * (yp-2) ) / ( height()-4 ) );
00157     
00158     if ( xPos > maxX )
00159         xPos = maxX;
00160     else if ( xPos < minX )
00161         xPos = minX;
00162     
00163     if ( yPos > maxY )
00164         yPos = maxY;
00165     else if ( yPos < minY )
00166         yPos = minY;
00167 }
00168 
00169 void KXYSelector::drawContents( QPainter * )
00170 {}
00171 
00172 
00173 void KXYSelector::drawCursor( QPainter *p, int xp, int yp )
00174 {
00175     p->setPen( QPen( white ) );
00176 
00177     p->drawLine( xp - 6, yp - 6, xp - 2, yp - 2 );
00178     p->drawLine( xp - 6, yp + 6, xp - 2, yp + 2 );
00179     p->drawLine( xp + 6, yp - 6, xp + 2, yp - 2 );
00180     p->drawLine( xp + 6, yp + 6, xp + 2, yp + 2 );
00181 }
00182 
00183 //-----------------------------------------------------------------------------
00184 /*
00185  * 1D value selector with contents drawn by derived class.
00186  * See KColorDialog for example.
00187  */
00188 
00189 
00190 KSelector::KSelector( QWidget *parent, const char *name )
00191     : QWidget( parent, name ), QRangeControl()
00192 {
00193     _orientation = Horizontal;
00194     _indent = TRUE;
00195 }
00196 
00197 KSelector::KSelector( Orientation o, QWidget *parent, const char *name )
00198     : QWidget( parent, name ), QRangeControl()
00199 {
00200     _orientation = o;
00201     _indent = TRUE;
00202 }
00203 
00204 
00205 KSelector::~KSelector()
00206 {}
00207 
00208 
00209 QRect KSelector::contentsRect() const
00210 {
00211     if ( orientation() == Vertical )
00212         return QRect( 2, 5, width()-9, height()-10 );
00213     else
00214         return QRect( 5, 2, width()-10, height()-9 );
00215 }
00216 
00217 void KSelector::paintEvent( QPaintEvent * )
00218 {
00219     QPainter painter;
00220 
00221     painter.begin( this );
00222 
00223     drawContents( &painter );
00224 
00225     QBrush brush;
00226 
00227     if ( indent() )
00228     {
00229         if ( orientation() == Vertical )
00230             qDrawShadePanel( &painter, 0, 3, width()-5, height()-6,
00231                 colorGroup(), TRUE, 2, &brush );
00232         else
00233             qDrawShadePanel( &painter, 3, 0, width()-6, height()-5,
00234                 colorGroup(), TRUE, 2, &brush );
00235     }
00236 
00237     QPoint pos = calcArrowPos( value() );
00238     drawArrow( &painter, TRUE, pos );   
00239 
00240     painter.end();
00241 }
00242 
00243 void KSelector::mousePressEvent( QMouseEvent *e )
00244 {
00245     moveArrow( e->pos() );
00246 }
00247 
00248 void KSelector::mouseMoveEvent( QMouseEvent *e )
00249 {
00250     moveArrow( e->pos() );
00251 }
00252 
00253 void KSelector::valueChange()
00254 {
00255     QPainter painter;
00256     QPoint pos;
00257 
00258     painter.begin( this );
00259 
00260     pos = calcArrowPos( prevValue() );
00261     drawArrow( &painter, FALSE, pos );   
00262 
00263     pos = calcArrowPos( value() );
00264     drawArrow( &painter, TRUE, pos );   
00265 
00266     painter.end();
00267 }
00268 
00269 void KSelector::moveArrow( const QPoint &pos )
00270 {
00271     int val;
00272 
00273     if ( orientation() == Vertical )
00274         val = ( maxValue() - minValue() ) * (height()-pos.y()-3)
00275                 / (height()-10) + minValue();
00276     else
00277         val = ( maxValue() - minValue() ) * (width()-pos.x()-3)
00278                 / (width()-10) + minValue();
00279 
00280     if ( val > maxValue() )
00281         val = maxValue();
00282     if ( val < minValue() )
00283         val = minValue();
00284 
00285     emit valueChanged( val );
00286     setValue( val );
00287 }
00288 
00289 QPoint KSelector::calcArrowPos( int val )
00290 {
00291     QPoint p;
00292 
00293     if ( orientation() == Vertical )
00294     {
00295         p.setY( height() - ( (height()-10) * val
00296                 / ( maxValue() - minValue() ) + 5 ) );
00297         p.setX( width() - 5 );
00298     }
00299     else
00300     {
00301         p.setX( width() - ( (width()-10) * val
00302                 / ( maxValue() - minValue() ) + 5 ) );
00303         p.setY( height() - 5 );
00304     }
00305 
00306     return p;
00307 }
00308 
00309 void KSelector::drawContents( QPainter * )
00310 {}
00311 
00312 void KSelector::drawArrow( QPainter *painter, bool show, const QPoint &pos )
00313 {
00314   if ( show )
00315   {
00316     QPointArray array(3);
00317 
00318     painter->setPen( QPen() );
00319     painter->setBrush( QBrush( colorGroup().buttonText() ) );
00320     if ( orientation() == Vertical )
00321     {
00322       array.setPoint( 0, pos.x()+0, pos.y()+0 );
00323       array.setPoint( 1, pos.x()+5, pos.y()+5 );
00324       array.setPoint( 2, pos.x()+5, pos.y()-5 );
00325     }
00326     else
00327     {
00328       array.setPoint( 0, pos.x()+0, pos.y()+0 );
00329       array.setPoint( 1, pos.x()+5, pos.y()+5 );
00330       array.setPoint( 2, pos.x()-5, pos.y()+5 );
00331     }
00332 
00333     painter->drawPolygon( array );
00334   } 
00335   else 
00336   {
00337     if ( orientation() == Vertical )
00338     {
00339        repaint(pos.x(), pos.y()-5, 6, 11, true);
00340     }
00341     else
00342     {
00343        repaint(pos.x()-5, pos.y(), 11, 6, true);
00344     }
00345   }
00346 }
00347 
00348 //----------------------------------------------------------------------------
00349 
00350 KGradientSelector::KGradientSelector( QWidget *parent, const char *name )
00351     : KSelector( parent, name )
00352 {
00353     init();
00354 }
00355 
00356 
00357 KGradientSelector::KGradientSelector( Orientation o, QWidget *parent,
00358         const char *name )
00359     : KSelector( o, parent, name )
00360 {
00361     init();
00362 }
00363 
00364 
00365 KGradientSelector::~KGradientSelector()
00366 {}
00367 
00368 
00369 void KGradientSelector::init()
00370 {
00371     color1.setRgb( 0, 0, 0 );
00372     color2.setRgb( 255, 255, 255 );
00373     
00374     text1 = text2 = "";
00375 }
00376 
00377 
00378 void KGradientSelector::drawContents( QPainter *painter )
00379 {
00380     QImage image( contentsRect().width(), contentsRect().height(), 32 );
00381 
00382     QColor col;
00383     float scale;
00384 
00385     int redDiff   = color2.red() - color1.red();
00386     int greenDiff = color2.green() - color1.green();
00387     int blueDiff  = color2.blue() - color1.blue();
00388 
00389     if ( orientation() == Vertical )
00390     {
00391         for ( int y = 0; y < image.height(); y++ )
00392         {
00393             scale = 1.0 * y / image.height();
00394             col.setRgb( color1.red() + int(redDiff*scale),
00395                         color1.green() + int(greenDiff*scale),
00396                         color1.blue() + int(blueDiff*scale) );
00397 
00398             unsigned int *p = (uint *) image.scanLine( y );
00399             for ( int x = 0; x < image.width(); x++ )
00400                 *p++ = col.rgb();
00401         }
00402     }
00403     else
00404     {
00405         unsigned int *p = (uint *) image.scanLine( 0 );
00406 
00407         for ( int x = 0; x < image.width(); x++ )
00408         {
00409             scale = 1.0 * x / image.width();
00410             col.setRgb( color1.red() + int(redDiff*scale),
00411                         color1.green() + int(greenDiff*scale),
00412                         color1.blue() + int(blueDiff*scale) );
00413             *p++ = col.rgb();
00414         }
00415 
00416         for ( int y = 1; y < image.height(); y++ )
00417             memcpy( image.scanLine( y ), image.scanLine( y - 1),
00418                  sizeof( unsigned int ) * image.width() );
00419     }
00420 
00421     QColor ditherPalette[8];
00422 
00423     for ( int s = 0; s < 8; s++ )
00424         ditherPalette[s].setRgb( color1.red() + redDiff * s / 8,
00425                                 color1.green() + greenDiff * s / 8,
00426                                 color1.blue() + blueDiff * s / 8 );
00427 
00428     KImageEffect::dither( image, ditherPalette, 8 );
00429 
00430     QPixmap p;
00431     p.convertFromImage( image );
00432 
00433     painter->drawPixmap( contentsRect().x(), contentsRect().y(), p );
00434 
00435     if ( orientation() == Vertical )
00436     {
00437         int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
00438         int xPos = contentsRect().left() + (contentsRect().width() -
00439              painter->fontMetrics().width( text2 )) / 2;
00440         QPen pen( color2 );
00441         painter->setPen( pen );
00442         painter->drawText( xPos, yPos, text2 );
00443 
00444         yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
00445         xPos = contentsRect().left() + (contentsRect().width() - 
00446             painter->fontMetrics().width( text1 )) / 2;
00447         pen.setColor( color1 );
00448         painter->setPen( pen );
00449         painter->drawText( xPos, yPos, text1 );
00450     }
00451     else
00452     {
00453         int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2;
00454 
00455         QPen pen( color2 );
00456         painter->setPen( pen );
00457         painter->drawText( contentsRect().left() + 2, yPos, text1 );
00458 
00459         pen.setColor( color1 );
00460         painter->setPen( pen );
00461         painter->drawText( contentsRect().right() -
00462              painter->fontMetrics().width( text2 ) - 2, yPos, text2 );
00463     }
00464 }
00465 
00466 //-----------------------------------------------------------------------------
00467 
00468 void KXYSelector::virtual_hook( int, void* )
00469 { /*BASE::virtual_hook( id, data );*/ }
00470 
00471 void KSelector::virtual_hook( int, void* )
00472 { /*BASE::virtual_hook( id, data );*/ }
00473 
00474 void KGradientSelector::virtual_hook( int id, void* data )
00475 { KSelector::virtual_hook( id, data ); }
00476 
00477 #include "kselect.moc"
00478 
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:05 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001