00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qimage.h>
00023 #include <qdrawutil.h>
00024
00025
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
00036
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
00213
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 }