00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qlabel.h>
00022 #include <qframe.h>
00023 #include <qbitmap.h>
00024
00025 #include <kcolorbutton.h>
00026 #include <kcombobox.h>
00027 #include <klocale.h>
00028 #include <qpainter.h>
00029 #include <kiconloader.h>
00030
00031 #include "vgradientwidget.h"
00032 #include "vcolordlg.h"
00033 #include "vfill.h"
00034 #include "vkopainter.h"
00035 #include "vcursor.h"
00036
00037 #define midPoint_width 7
00038 #define midPoint_height 10
00039 static unsigned char midPoint_bits[] = {
00040 0x08, 0x08, 0x1c, 0x1c, 0x2a, 0x2a, 0x08, 0x08, 0x08, 0x08
00041 };
00042
00043 #define colorStopBorder_width 11
00044 #define colorStopBorder_height 11
00045 static unsigned char colorStopBorder_bits[] = {
00046 0x20, 0x00, 0x50, 0x00, 0x50, 0x00, 0x88, 0x00, 0x88, 0x00, 0x04, 0x01,
00047 0x04, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x04, 0xff, 0x07
00048 };
00049
00050 #define colorStop_width 9
00051 #define colorStop_height 10
00052 static unsigned char colorStop_bits[] = {
00053 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00,
00054 0x7c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xff, 0x01
00055 };
00056
00057 VGradientWidget::VGradientWidget( VGradient& gradient, QWidget* parent, const char* name )
00058 : QWidget( parent, name ), m_gradient( &gradient )
00059 {
00060 setBackgroundMode( Qt::NoBackground );
00061 setMinimumSize( 105, 35 );
00062 }
00063
00064 VGradientWidget::~VGradientWidget()
00065 {
00066 }
00067
00068 void VGradientWidget::paintColorStop( QPainter& p, int x, VColor& color )
00069 {
00070 QBitmap bitmap;
00071
00072 bitmap = QBitmap( colorStop_width, colorStop_height, colorStop_bits, true );
00073 bitmap.setMask( bitmap );
00074 p.setPen( color );
00075 p.drawPixmap( x - 4, 1, bitmap );
00076
00077 bitmap = QBitmap( colorStopBorder_width, colorStopBorder_height, colorStopBorder_bits, true );
00078 bitmap.setMask( bitmap );
00079 p.setPen( Qt::black );
00080 p.drawPixmap( x - 5, 1, bitmap );
00081 }
00082
00083 void VGradientWidget::paintMidPoint( QPainter& p, int x )
00084 {
00085 QBitmap bitmap( midPoint_width, midPoint_height, midPoint_bits, true );
00086 bitmap.setMask( bitmap );
00087 p.setPen( Qt::black );
00088 p.drawPixmap( x - 3, 1, bitmap );
00089 }
00090
00091 void VGradientWidget::paintEvent( QPaintEvent* )
00092 {
00093 int w = width() - 4;
00094 int h = height() - 7;
00095 int ph = colorStopBorder_height + 2;
00096 int gh = h - ph;
00097
00098 QPixmap pixmap( width(), height() );
00099 VKoPainter gp( &pixmap, width(), height() );
00100 gp.setRasterOp( Qt::XorROP );
00101 VGradient gradient( *m_gradient );
00102 gradient.setType( VGradient::linear );
00103 gradient.setOrigin( KoPoint( 2, 2 ) );
00104 gradient.setFocalPoint( KoPoint( 2, 2 ) );
00105 gradient.setVector( KoPoint( 2 + w, 2 ) );
00106 VFill fill;
00107 KIconLoader il;
00108 fill.pattern() = VPattern( il.iconPath( "karbon.png", KIcon::Small ) );
00109 fill.setType( VFill::patt );
00110 gp.setBrush( fill );
00111 gp.drawRect( KoRect( 2, 2, w, gh ) );
00112 fill.gradient() = gradient;
00113 fill.setType( VFill::grad );
00114 gp.setBrush( fill );
00115 gp.drawRect( KoRect( 2, 2, w, gh ) );
00116 gp.end();
00117
00118 QPainter p( &pixmap );
00119
00120 p.setPen( colorGroup().light() );
00121
00122 p.moveTo( 1, height() - 1 );
00123 p.lineTo( 1, 1 );
00124 p.lineTo( width() - 1, 1 );
00125 p.lineTo( width() - 1, height() - 1 );
00126 p.lineTo( 1, height() - 1 );
00127
00128
00129 p.moveTo( 1, 3 + gh );
00130 p.lineTo( width() - 1, 3 + gh );
00131
00132 p.setPen( colorGroup().dark() );
00133
00134 p.moveTo( 0, height() - 1 );
00135 p.lineTo( 0, 0 );
00136 p.lineTo( width() - 1, 0 );
00137
00138
00139 p.moveTo( width() - 2, 2 );
00140 p.lineTo( width() - 2, 2 + gh );
00141 p.lineTo( 2, 2 + gh );
00142
00143
00144 p.moveTo( 1, height() - 3 - ph );
00145 p.lineTo( width() - 1, height() - 3 - ph );
00146
00147
00148 p.moveTo( width() - 2, height() - ph - 1 );
00149 p.lineTo( width() - 2, height() - 2 );
00150 p.lineTo( 2, height() - 2 );
00151
00152 m_pntArea.setRect( 2, height() - ph - 2, w, ph );
00153
00154 p.fillRect( m_pntArea.x(), m_pntArea.y(), m_pntArea.width(), m_pntArea.height(), colorGroup().background() );
00155
00156 p.setClipRect( m_pntArea.x(), m_pntArea.y(), m_pntArea.width(), m_pntArea.height() );
00157 p.translate( m_pntArea.x(), m_pntArea.y() );
00158
00159 QPtrList<VColorStop>& colorStops = m_gradient->m_colorStops;
00160 if( colorStops.count() > 1 )
00161 {
00162 VColorStop* stop, *nextstop;
00163 for( stop = colorStops.first(), nextstop = colorStops.next();
00164 nextstop; stop = nextstop, nextstop = colorStops.next() )
00165 {
00166 paintColorStop( p, (int)( stop->rampPoint * m_pntArea.width() ), stop->color );
00167 paintMidPoint( p, (int)(( stop->rampPoint + ( nextstop->rampPoint - stop->rampPoint ) * stop->midPoint ) * m_pntArea.width() ) );
00168 }
00169 paintColorStop( p, int( stop->rampPoint * w ), stop->color );
00170 }
00171 p.end();
00172 bitBlt( this, 0, 0, &pixmap, 0, 0, width(), height() );
00173 }
00174
00175 void VGradientWidget::mousePressEvent( QMouseEvent* e )
00176 {
00177 if( ! m_pntArea.contains( e->x(), e->y() ) )
00178 return;
00179
00180 QPtrList<VColorStop>& colorStops = m_gradient->m_colorStops;
00181
00182 currentPoint = 0;
00183
00184 int x = e->x() - m_pntArea.left();
00185
00186 int i = colorStops.count() - 1;
00187 VColorStop *stop, *nextstop = 0;
00188 for( stop = colorStops.last(); i >= 0; i--, stop = colorStops.prev() )
00189 {
00190 int r = int( stop->rampPoint * m_pntArea.width() );
00191 if( nextstop )
00192 {
00193 int m = int( ( stop->rampPoint + ( nextstop->rampPoint - stop->rampPoint ) * stop->midPoint ) * m_pntArea.width() );
00194 if( ( x > m - 5 ) && ( x < m + 5 ) )
00195 {
00196
00197 currentPoint = 2 * i + 2;
00198 if( e->button() == Qt::LeftButton )
00199 setCursor( VCursor::horzMove() );
00200 return;
00201 }
00202 }
00203 if( ( x > r - 5 ) && ( x < r + 5 ) )
00204 {
00205
00206 currentPoint = 2 * i + 1;
00207 if( e->button() == Qt::LeftButton )
00208 setCursor( VCursor::horzMove() );
00209 return;
00210 }
00211
00212 nextstop = stop;
00213 }
00214 }
00215
00216 void VGradientWidget::mouseReleaseEvent( QMouseEvent* e )
00217 {
00218 if( e->button() == Qt::RightButton && currentPoint )
00219 {
00220 if( m_pntArea.contains( e->x(), e->y() ) && ( currentPoint % 2 == 1 ) )
00221 {
00222 int x = e->x() - m_pntArea.left();
00223
00224 int r = int( m_gradient->m_colorStops.at( int(0.5 * currentPoint) )->rampPoint * m_pntArea.width() );
00225 if( ( x > r - 5 ) && ( x < r + 5 ) )
00226 {
00227 m_gradient->m_colorStops.remove( int(0.5 * currentPoint) );
00228 update();
00229 emit changed();
00230 }
00231 }
00232 }
00233 setCursor( QCursor( Qt::ArrowCursor ) );
00234 }
00235
00236 void VGradientWidget::mouseDoubleClickEvent( QMouseEvent* e )
00237 {
00238 if( ! m_pntArea.contains( e->x(), e->y() ) )
00239 return;
00240
00241 if( e->button() != Qt::LeftButton )
00242 return;
00243
00244 if( currentPoint % 2 == 1 )
00245 {
00246
00247 VColorDlg* d = new VColorDlg( m_gradient->m_colorStops.at( currentPoint / 2 )->color, this->topLevelWidget() );
00248 if( d->exec() == QDialog::Accepted )
00249 {
00250 m_gradient->m_colorStops.at( currentPoint / 2 )->color = d->Color();
00251 update();
00252 emit changed();
00253 }
00254 delete d;
00255 }
00256 else if( currentPoint == 0 )
00257 {
00258
00259 VColorDlg* d = new VColorDlg( m_gradient->m_colorStops.at( 0 )->color, this->topLevelWidget() );
00260 if( d->exec() == QDialog::Accepted )
00261 {
00262 m_gradient->addStop( d->Color(), (float)( e->x() - 2 ) / ( m_pntArea.width() ), 0.5 );
00263 update();
00264 emit changed();
00265 }
00266 delete d;
00267 }
00268 }
00269
00270 void VGradientWidget::mouseMoveEvent( QMouseEvent* e )
00271 {
00272 if( e->state() & Qt::RightButton )
00273 return;
00274
00275 QPtrList<VColorStop>& colorStops = m_gradient->m_colorStops;
00276
00277 if( currentPoint >= colorStops.count() * 2 )
00278 return;
00279
00280 int x = e->x() - m_pntArea.left();
00281
00282 if( currentPoint % 2 == 1 )
00283 {
00284
00285 int actRP = int( 0.5 * ( currentPoint - 1 ) );
00286 int prevRP = actRP - 1;
00287 int nextRP = int( 0.5 * ( currentPoint + 1 ) );
00288
00289 x = kMin( x, ( actRP < int( colorStops.count() - 1 ) ) ? int( colorStops.at( nextRP )->rampPoint * m_pntArea.width() ) : m_pntArea.width() );
00290 x = kMax( x, ( actRP > 0 ) ? int( colorStops.at( prevRP )->rampPoint * m_pntArea.width() ) : 0 );
00291 colorStops.at( actRP )->rampPoint = (float)( x ) / m_pntArea.width();
00292 update();
00293 emit changed();
00294 }
00295 else if( currentPoint > 0 )
00296 {
00297
00298 int prevRP = int( 0.5 * ( currentPoint - 1 ) );
00299 int nextRP = int( 0.5 * ( currentPoint + 1 ) );
00300
00301 x = kMin( x, int( colorStops.at( nextRP )->rampPoint * m_pntArea.width() ) );
00302 x = kMax( x, int( colorStops.at( prevRP )->rampPoint * m_pntArea.width() ) );
00303 colorStops.at( prevRP )->midPoint = ( (float)( x ) / m_pntArea.width() - ( colorStops.at( prevRP )->rampPoint ) ) / ( colorStops.at( nextRP )->rampPoint - colorStops.at( prevRP )->rampPoint );
00304 update();
00305 emit changed();
00306 }
00307 }
00308
00309 #include "vgradientwidget.moc"