Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

oselector.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., 59 Temple Place - Suite 330,
00017     Boston, MA 02111-1307, USA.
00018 */
00019 
00020 /* QT */
00021 
00022 #include <qimage.h>
00023 #include <qdrawutil.h>
00024 
00025 /* OPIE */
00026 
00027 #include <opie2/oimageeffect.h>
00028 #include <opie2/oselector.h>
00029 
00030 #define STORE_W 8
00031 #define STORE_W2 STORE_W * 2
00032 
00033 //-----------------------------------------------------------------------------
00034 /*
00035  * 2D value selector.
00036  * The contents of the selector are drawn by derived class.
00037  */
00038 
00039 using namespace Opie::Ui;
00040 
00041 OXYSelector::OXYSelector( QWidget *parent, const char *name )
00042         : QWidget( parent, name )
00043 {
00044         xPos = 0;
00045         yPos = 0;
00046         minX = 0;
00047         minY = 0;
00048         maxX = 100;
00049         maxY = 100;
00050         store.setOptimization( QPixmap::BestOptim );
00051         store.resize( STORE_W2, STORE_W2 );
00052 }
00053 
00054 
00055 OXYSelector::~OXYSelector()
00056 {}
00057 
00058 
00059 void OXYSelector::setRange( int _minX, int _minY, int _maxX, int _maxY )
00060 {
00061         px = 2;
00062         py = 2;
00063         minX = _minX;
00064         minY = _minY;
00065         maxX = _maxX;
00066         maxY = _maxY;
00067 }
00068 
00069 void OXYSelector::setValues( int _xPos, int _yPos )
00070 {
00071         xPos = _xPos;
00072         yPos = _yPos;
00073 
00074         if ( xPos > maxX )
00075                 xPos = maxX;
00076         else if ( xPos < minX )
00077                 xPos = minX;
00078 
00079         if ( yPos > maxY )
00080                 yPos = maxY;
00081         else if ( yPos < minY )
00082                 yPos = minY;
00083 
00084         int xp = 2 + (width() - 4) * xPos / (maxX - minX);
00085         int yp = height() - 2 - (height() - 4) * yPos / (maxY - minY);
00086 
00087         setPosition( xp, yp );
00088 }
00089 
00090 QRect OXYSelector::contentsRect() const
00091 {
00092         return QRect( 2, 2, width()-4, height()-4 );
00093 }
00094 
00095 void OXYSelector::paintEvent( QPaintEvent *ev )
00096 {
00097         QRect cursorRect( px - STORE_W, py - STORE_W, STORE_W2, STORE_W2);
00098         QRect paintRect = ev->rect();
00099 
00100         QPainter painter;
00101         painter.begin( this );
00102 
00103         QBrush brush;
00104         qDrawShadePanel( &painter, 0, 0, width(), height(), colorGroup(),
00105                         TRUE, 2, &brush );
00106 
00107         drawContents( &painter );
00108         if (paintRect.contains(cursorRect))
00109         {
00110            bitBlt( &store, 0, 0, this, px - STORE_W, py - STORE_W,
00111                 STORE_W2, STORE_W2, CopyROP );
00112            drawCursor( &painter, px, py );
00113         }
00114         else if (paintRect.intersects(cursorRect))
00115         {
00116            repaint( cursorRect, false);
00117         }
00118 
00119         painter.end();
00120 }
00121 
00122 void OXYSelector::mousePressEvent( QMouseEvent *e )
00123 {
00124     int xVal, yVal;
00125     valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal );
00126     setValues( xVal, yVal );
00127 
00128     emit valueChanged( xPos, yPos );
00129 }
00130 
00131 void OXYSelector::mouseMoveEvent( QMouseEvent *e )
00132 {
00133     int xVal, yVal;
00134     valuesFromPosition( e->pos().x() - 2, e->pos().y() - 2, xVal, yVal );
00135     setValues( xVal, yVal );
00136 
00137     emit valueChanged( xPos, yPos );
00138 }
00139 
00140 void OXYSelector::wheelEvent( QWheelEvent *e )
00141 {
00142     #if QT_VERSION >= 0x030000
00143     if ( e->orientation() == Qt::Horizontal )
00144         setValues( xValue() + e->delta()/120, yValue() );
00145     else
00146         setValues( xValue(), yValue() + e->delta()/120 );
00147 
00148     emit valueChanged( xPos, yPos );
00149     #else
00150     Q_UNUSED( e )
00151     #endif
00152 }
00153 
00154 void OXYSelector::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 OXYSelector::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 OXYSelector::drawContents( QPainter * )
00197 {}
00198 
00199 
00200 void OXYSelector::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 OColorDialog for example.
00214  */
00215 
00216 
00217 OSelector::OSelector( QWidget *parent, const char *name )
00218         : QWidget( parent, name ), QRangeControl()
00219 {
00220         _orientation = Horizontal;
00221         _indent = TRUE;
00222 }
00223 
00224 OSelector::OSelector( Orientation o, QWidget *parent, const char *name )
00225         : QWidget( parent, name ), QRangeControl()
00226 {
00227         _orientation = o;
00228         _indent = TRUE;
00229 }
00230 
00231 
00232 OSelector::~OSelector()
00233 {}
00234 
00235 
00236 QRect OSelector::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 OSelector::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 OSelector::mousePressEvent( QMouseEvent *e )
00271 {
00272         moveArrow( e->pos() );
00273 }
00274 
00275 void OSelector::mouseMoveEvent( QMouseEvent *e )
00276 {
00277         moveArrow( e->pos() );
00278 }
00279 
00280 void OSelector::wheelEvent( QWheelEvent *e )
00281 {
00282         int val = value() + e->delta()/120;
00283         emit valueChanged( val );
00284         setValue( val );
00285 }
00286 
00287 void OSelector::valueChange()
00288 {
00289         QPainter painter;
00290         QPoint pos;
00291 
00292         painter.begin( this );
00293 
00294         pos = calcArrowPos( prevValue() );
00295         drawArrow( &painter, FALSE, pos );
00296 
00297         pos = calcArrowPos( value() );
00298         drawArrow( &painter, TRUE, pos );
00299 
00300         painter.end();
00301 }
00302 
00303 void OSelector::moveArrow( const QPoint &pos )
00304 {
00305         int val;
00306 
00307         if ( orientation() == Vertical )
00308                 val = ( maxValue() - minValue() ) * (height()-pos.y()-3)
00309                                 / (height()-10) + minValue();
00310         else
00311                 val = ( maxValue() - minValue() ) * (width()-pos.x()-3)
00312                                 / (width()-10) + minValue();
00313 
00314         if ( val > maxValue() )
00315                 val = maxValue();
00316         if ( val < minValue() )
00317                 val = minValue();
00318 
00319         emit valueChanged( val );
00320         setValue( val );
00321 }
00322 
00323 QPoint OSelector::calcArrowPos( int val )
00324 {
00325         QPoint p;
00326 
00327         if ( orientation() == Vertical )
00328         {
00329                 p.setY( height() - ( (height()-10) * val
00330                                 / ( maxValue() - minValue() ) + 5 ) );
00331                 p.setX( width() - 5 );
00332         }
00333         else
00334         {
00335                 p.setX( width() - ( (width()-10) * val
00336                                 / ( maxValue() - minValue() ) + 5 ) );
00337                 p.setY( height() - 5 );
00338         }
00339 
00340         return p;
00341 }
00342 
00343 void OSelector::drawContents( QPainter * )
00344 {}
00345 
00346 void OSelector::drawArrow( QPainter *painter, bool show, const QPoint &pos )
00347 {
00348   if ( show )
00349   {
00350     QPointArray array(3);
00351 
00352     painter->setPen( QPen() );
00353     painter->setBrush( QBrush( colorGroup().buttonText() ) );
00354     if ( orientation() == Vertical )
00355     {
00356       array.setPoint( 0, pos.x()+0, pos.y()+0 );
00357       array.setPoint( 1, pos.x()+5, pos.y()+5 );
00358       array.setPoint( 2, pos.x()+5, pos.y()-5 );
00359     }
00360     else
00361     {
00362       array.setPoint( 0, pos.x()+0, pos.y()+0 );
00363       array.setPoint( 1, pos.x()+5, pos.y()+5 );
00364       array.setPoint( 2, pos.x()-5, pos.y()+5 );
00365     }
00366 
00367     painter->drawPolygon( array );
00368   }
00369   else
00370   {
00371     if ( orientation() == Vertical )
00372     {
00373        repaint(pos.x(), pos.y()-5, 6, 11, true);
00374     }
00375     else
00376     {
00377        repaint(pos.x()-5, pos.y(), 11, 6, true);
00378     }
00379   }
00380 }
00381 
00382 //----------------------------------------------------------------------------
00383 
00384 OGradientSelector::OGradientSelector( QWidget *parent, const char *name )
00385     : OSelector( parent, name )
00386 {
00387     init();
00388 }
00389 
00390 
00391 OGradientSelector::OGradientSelector( Orientation o, QWidget *parent,
00392                 const char *name )
00393         : OSelector( o, parent, name )
00394 {
00395     init();
00396 }
00397 
00398 
00399 OGradientSelector::~OGradientSelector()
00400 {}
00401 
00402 
00403 void OGradientSelector::init()
00404 {
00405     color1.setRgb( 0, 0, 0 );
00406     color2.setRgb( 255, 255, 255 );
00407 
00408     text1 = text2 = "";
00409 }
00410 
00411 
00412 void OGradientSelector::drawContents( QPainter *painter )
00413 {
00414         QImage image( contentsRect().width(), contentsRect().height(), 32 );
00415 
00416         QColor col;
00417         float scale;
00418 
00419         int redDiff   = color2.red() - color1.red();
00420         int greenDiff = color2.green() - color1.green();
00421         int blueDiff  = color2.blue() - color1.blue();
00422 
00423         if ( orientation() == Vertical )
00424         {
00425                 for ( int y = 0; y < image.height(); y++ )
00426                 {
00427                         scale = 1.0 * y / image.height();
00428                         col.setRgb( color1.red() + int(redDiff*scale),
00429                                                 color1.green() + int(greenDiff*scale),
00430                                                 color1.blue() + int(blueDiff*scale) );
00431 
00432                         unsigned int *p = (uint *) image.scanLine( y );
00433                         for ( int x = 0; x < image.width(); x++ )
00434                                 *p++ = col.rgb();
00435                 }
00436         }
00437         else
00438         {
00439                 unsigned int *p = (uint *) image.scanLine( 0 );
00440 
00441                 for ( int x = 0; x < image.width(); x++ )
00442                 {
00443                         scale = 1.0 * x / image.width();
00444                         col.setRgb( color1.red() + int(redDiff*scale),
00445                                                 color1.green() + int(greenDiff*scale),
00446                                                 color1.blue() + int(blueDiff*scale) );
00447                         *p++ = col.rgb();
00448                 }
00449 
00450                 for ( int y = 1; y < image.height(); y++ )
00451                         memcpy( image.scanLine( y ), image.scanLine( y - 1),
00452                                  sizeof( unsigned int ) * image.width() );
00453         }
00454 
00455         QColor ditherPalette[8];
00456 
00457         for ( int s = 0; s < 8; s++ )
00458                 ditherPalette[s].setRgb( color1.red() + redDiff * s / 8,
00459                                                                 color1.green() + greenDiff * s / 8,
00460                                                                 color1.blue() + blueDiff * s / 8 );
00461 
00462         OImageEffect::dither( image, ditherPalette, 8 );
00463 
00464         QPixmap p;
00465         p.convertFromImage( image );
00466 
00467         painter->drawPixmap( contentsRect().x(), contentsRect().y(), p );
00468 
00469         if ( orientation() == Vertical )
00470         {
00471                 int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
00472                 int xPos = contentsRect().left() + (contentsRect().width() -
00473                          painter->fontMetrics().width( text2 )) / 2;
00474                 QPen pen( color2 );
00475                 painter->setPen( pen );
00476                 painter->drawText( xPos, yPos, text2 );
00477 
00478                 yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
00479                 xPos = contentsRect().left() + (contentsRect().width() -
00480                         painter->fontMetrics().width( text1 )) / 2;
00481                 pen.setColor( color1 );
00482                 painter->setPen( pen );
00483                 painter->drawText( xPos, yPos, text1 );
00484         }
00485         else
00486         {
00487                 int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2;
00488 
00489                 QPen pen( color2 );
00490                 painter->setPen( pen );
00491                 painter->drawText( contentsRect().left() + 2, yPos, text1 );
00492 
00493                 pen.setColor( color1 );
00494                 painter->setPen( pen );
00495                 painter->drawText( contentsRect().right() -
00496                          painter->fontMetrics().width( text2 ) - 2, yPos, text2 );
00497         }
00498 }
00499 
00500 //-----------------------------------------------------------------------------
00501 
00502 static QColor *standardPalette = 0;
00503 
00504 #define STANDARD_PAL_SIZE 17
00505 
00506 OColor::OColor()
00507 : QColor()
00508 {
00509   r = 0; g = 0; b = 0; h = 0; s = 0; v = 0;
00510 };
00511 
00512 OColor::OColor( const OColor &col)
00513 : QColor( col )
00514 {
00515   h = col.h; s = col.s; v = col.v;
00516   r = col.r; g = col.g; b = col.b;
00517 };
00518 
00519 OColor::OColor( const QColor &col)
00520 : QColor( col )
00521 {
00522   QColor::rgb(&r, &g, &b);
00523   QColor::hsv(&h, &s, &v);
00524 };
00525 
00526 bool OColor::operator==(const OColor& col) const
00527 {
00528   return (h == col.h) && (s == col.s) && (v == col.v) &&
00529          (r == col.r) && (g == col.g) && (b == col.b);
00530 }
00531 
00532 OColor& OColor::operator=(const OColor& col)
00533 {
00534   *(QColor *)this = col;
00535   h = col.h; s = col.s; v = col.v;
00536   r = col.r; g = col.g; b = col.b;
00537   return *this;
00538 }
00539 
00540 void
00541 OColor::setHsv(int _h, int _s, int _v)
00542 {
00543   h = _h; s = _s; v = _v;
00544   QColor::setHsv(h, s, v);
00545   QColor::rgb(&r, &g, &b);
00546 };
00547 
00548 void
00549 OColor::setRgb(int _r, int _g, int _b)
00550 {
00551   r = _r; g = _g; b = _b;
00552   QColor::setRgb(r, g, b);
00553   QColor::hsv(&h, &s, &v);
00554 }
00555 
00556 void
00557 OColor::rgb(int *_r, int *_g, int *_b) const
00558 {
00559   *_r = r; *_g = g; *_b = b;
00560 }
00561 
00562 void
00563 OColor::hsv(int *_h, int *_s, int *_v) const
00564 {
00565   *_h = h; *_s = s; *_v = v;
00566 }
00567 
00568 static void createStandardPalette()
00569 {
00570     if ( standardPalette )
00571         return;
00572 
00573     standardPalette = new QColor[STANDARD_PAL_SIZE];
00574 
00575     int i = 0;
00576 
00577     standardPalette[i++] = Qt::red;
00578     standardPalette[i++] = Qt::green;
00579     standardPalette[i++] = Qt::blue;
00580     standardPalette[i++] = Qt::cyan;
00581     standardPalette[i++] = Qt::magenta;
00582     standardPalette[i++] = Qt::yellow;
00583     standardPalette[i++] = Qt::darkRed;
00584     standardPalette[i++] = Qt::darkGreen;
00585     standardPalette[i++] = Qt::darkBlue;
00586     standardPalette[i++] = Qt::darkCyan;
00587     standardPalette[i++] = Qt::darkMagenta;
00588     standardPalette[i++] = Qt::darkYellow;
00589     standardPalette[i++] = Qt::white;
00590     standardPalette[i++] = Qt::lightGray;
00591     standardPalette[i++] = Qt::gray;
00592     standardPalette[i++] = Qt::darkGray;
00593     standardPalette[i++] = Qt::black;
00594 }
00595 
00596 
00597 OHSSelector::OHSSelector( QWidget *parent, const char *name )
00598         : OXYSelector( parent, name )
00599 {
00600         setRange( 0, 0, 359, 255 );
00601 }
00602 
00603 void OHSSelector::updateContents()
00604 {
00605         drawPalette(&pixmap);
00606 }
00607 
00608 void OHSSelector::resizeEvent( QResizeEvent * )
00609 {
00610         updateContents();
00611 }
00612 
00613 void OHSSelector::drawContents( QPainter *painter )
00614 {
00615         painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap );
00616 }
00617 
00618 void OHSSelector::drawPalette( QPixmap *pixmap )
00619 {
00620         int xSize = contentsRect().width(), ySize = contentsRect().height();
00621         QImage image( xSize, ySize, 32 );
00622         QColor col;
00623         int h, s;
00624         uint *p;
00625 
00626         for ( s = ySize-1; s >= 0; s-- )
00627         {
00628                 p = (uint *) image.scanLine( ySize - s - 1 );
00629                 for( h = 0; h < xSize; h++ )
00630                 {
00631                         col.setHsv( 359*h/(xSize-1), 255*s/(ySize-1), 192 );
00632                         *p = col.rgb();
00633                         p++;
00634                 }
00635         }
00636 
00637         if ( QColor::numBitPlanes() <= 8 )
00638         {
00639                 createStandardPalette();
00640                 OImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE );
00641         }
00642         pixmap->convertFromImage( image );
00643 }
00644 
00645 
00646 //-----------------------------------------------------------------------------
00647 
00648 OValueSelector::OValueSelector( QWidget *parent, const char *name )
00649         : OSelector( OSelector::Vertical, parent, name ), _hue(0), _sat(0)
00650 {
00651         setRange( 0, 255 );
00652         pixmap.setOptimization( QPixmap::BestOptim );
00653 }
00654 
00655 OValueSelector::OValueSelector(Orientation o, QWidget *parent, const char *name
00656  )
00657         : OSelector( o, parent, name), _hue(0), _sat(0)
00658 {
00659         setRange( 0, 255 );
00660         pixmap.setOptimization( QPixmap::BestOptim );
00661 }
00662 
00663 void OValueSelector::updateContents()
00664 {
00665         drawPalette(&pixmap);
00666 }
00667 
00668 void OValueSelector::resizeEvent( QResizeEvent * )
00669 {
00670         updateContents();
00671 }
00672 
00673 void OValueSelector::drawContents( QPainter *painter )
00674 {
00675         painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap );
00676 }
00677 
00678 void OValueSelector::drawPalette( QPixmap *pixmap )
00679 {
00680         int xSize = contentsRect().width(), ySize = contentsRect().height();
00681         QImage image( xSize, ySize, 32 );
00682         QColor col;
00683         uint *p;
00684         QRgb rgb;
00685 
00686         if ( orientation() == OSelector::Horizontal )
00687         {
00688                 for ( int v = 0; v < ySize; v++ )
00689                 {
00690                         p = (uint *) image.scanLine( ySize - v - 1 );
00691 
00692                         for( int x = 0; x < xSize; x++ )
00693                         {
00694                                 col.setHsv( _hue, _sat, 255*x/(xSize-1) );
00695                                 rgb = col.rgb();
00696                                 *p++ = rgb;
00697                         }
00698                 }
00699         }
00700 
00701         if( orientation() == OSelector::Vertical )
00702         {
00703                 for ( int v = 0; v < ySize; v++ )
00704                 {
00705                         p = (uint *) image.scanLine( ySize - v - 1 );
00706                         col.setHsv( _hue, _sat, 255*v/(ySize-1) );
00707                         rgb = col.rgb();
00708                         for ( int i = 0; i < xSize; i++ )
00709                                 *p++ = rgb;
00710                 }
00711         }
00712 
00713         if ( QColor::numBitPlanes() <= 8 )
00714         {
00715                 createStandardPalette();
00716                 OImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE );
00717         }
00718         pixmap->convertFromImage( image );
00719 }

Generated on Sat Nov 5 16:16:27 2005 for OPIE by  doxygen 1.4.2