00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_plot_abstract_canvas.h"
00011 #include "qwt_plot.h"
00012 #include "qwt_painter.h"
00013 #include <qpainter.h>
00014 #include <qdrawutil.h>
00015 #include <qstyle.h>
00016 #include <qstyleoption.h>
00017
00018 class QwtStyleSheetRecorder: public QwtNullPaintDevice
00019 {
00020 public:
00021 explicit QwtStyleSheetRecorder( const QSize &size ):
00022 d_size( size )
00023 {
00024 }
00025
00026 virtual void updateState( const QPaintEngineState &state )
00027 {
00028 if ( state.state() & QPaintEngine::DirtyPen )
00029 {
00030 d_pen = state.pen();
00031 }
00032 if ( state.state() & QPaintEngine::DirtyBrush )
00033 {
00034 d_brush = state.brush();
00035 }
00036 if ( state.state() & QPaintEngine::DirtyBrushOrigin )
00037 {
00038 d_origin = state.brushOrigin();
00039 }
00040 }
00041
00042 virtual void drawRects(const QRectF *rects, int count )
00043 {
00044 for ( int i = 0; i < count; i++ )
00045 border.rectList += rects[i];
00046 }
00047
00048 virtual void drawRects(const QRect *rects, int count )
00049 {
00050 for ( int i = 0; i < count; i++ )
00051 border.rectList += rects[i];
00052 }
00053
00054 virtual void drawPath( const QPainterPath &path )
00055 {
00056 const QRectF rect( QPointF( 0.0, 0.0 ), d_size );
00057 if ( path.controlPointRect().contains( rect.center() ) )
00058 {
00059 setCornerRects( path );
00060 alignCornerRects( rect );
00061
00062 background.path = path;
00063 background.brush = d_brush;
00064 background.origin = d_origin;
00065 }
00066 else
00067 {
00068 border.pathList += path;
00069 }
00070 }
00071
00072 void setCornerRects( const QPainterPath &path )
00073 {
00074 QPointF pos( 0.0, 0.0 );
00075
00076 for ( int i = 0; i < path.elementCount(); i++ )
00077 {
00078 QPainterPath::Element el = path.elementAt(i);
00079 switch( el.type )
00080 {
00081 case QPainterPath::MoveToElement:
00082 case QPainterPath::LineToElement:
00083 {
00084 pos.setX( el.x );
00085 pos.setY( el.y );
00086 break;
00087 }
00088 case QPainterPath::CurveToElement:
00089 {
00090 QRectF r( pos, QPointF( el.x, el.y ) );
00091 clipRects += r.normalized();
00092
00093 pos.setX( el.x );
00094 pos.setY( el.y );
00095
00096 break;
00097 }
00098 case QPainterPath::CurveToDataElement:
00099 {
00100 if ( clipRects.size() > 0 )
00101 {
00102 QRectF r = clipRects.last();
00103 r.setCoords(
00104 qMin( r.left(), el.x ),
00105 qMin( r.top(), el.y ),
00106 qMax( r.right(), el.x ),
00107 qMax( r.bottom(), el.y )
00108 );
00109 clipRects.last() = r.normalized();
00110 }
00111 break;
00112 }
00113 }
00114 }
00115 }
00116
00117 protected:
00118 virtual QSize sizeMetrics() const
00119 {
00120 return d_size;
00121 }
00122
00123 private:
00124 void alignCornerRects( const QRectF &rect )
00125 {
00126 for ( int i = 0; i < clipRects.size(); i++ )
00127 {
00128 QRectF &r = clipRects[i];
00129 if ( r.center().x() < rect.center().x() )
00130 r.setLeft( rect.left() );
00131 else
00132 r.setRight( rect.right() );
00133
00134 if ( r.center().y() < rect.center().y() )
00135 r.setTop( rect.top() );
00136 else
00137 r.setBottom( rect.bottom() );
00138 }
00139 }
00140
00141
00142 public:
00143 QVector<QRectF> clipRects;
00144
00145 struct Border
00146 {
00147 QList<QPainterPath> pathList;
00148 QList<QRectF> rectList;
00149 QRegion clipRegion;
00150 } border;
00151
00152 struct Background
00153 {
00154 QPainterPath path;
00155 QBrush brush;
00156 QPointF origin;
00157 } background;
00158
00159 private:
00160 const QSize d_size;
00161
00162 QPen d_pen;
00163 QBrush d_brush;
00164 QPointF d_origin;
00165 };
00166
00167 static void qwtUpdateContentsRect( int fw, QWidget *canvas )
00168 {
00169 canvas->setContentsMargins( fw, fw, fw, fw );
00170 }
00171
00172 static void qwtDrawBackground( QPainter *painter, QWidget *canvas )
00173 {
00174 painter->save();
00175
00176 QPainterPath borderClip;
00177
00178 ( void )QMetaObject::invokeMethod(
00179 canvas, "borderPath", Qt::DirectConnection,
00180 Q_RETURN_ARG( QPainterPath, borderClip ), Q_ARG( QRect, canvas->rect() ) );
00181
00182 if ( !borderClip.isEmpty() )
00183 painter->setClipPath( borderClip, Qt::IntersectClip );
00184
00185 const QBrush &brush =
00186 canvas->palette().brush( canvas->backgroundRole() );
00187
00188 if ( brush.style() == Qt::TexturePattern )
00189 {
00190 QPixmap pm( canvas->size() );
00191 QwtPainter::fillPixmap( canvas, pm );
00192 painter->drawPixmap( 0, 0, pm );
00193 }
00194 else if ( brush.gradient() )
00195 {
00196 QVector<QRect> rects;
00197
00198 if ( brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode )
00199 {
00200 rects += canvas->rect();
00201 }
00202 else
00203 {
00204 rects = painter->clipRegion().rects();
00205 }
00206
00207 #if 1
00208 bool useRaster = false;
00209
00210 if ( painter->paintEngine()->type() == QPaintEngine::X11 )
00211 {
00212
00213
00214
00215
00216
00217
00218 useRaster = true;
00219 }
00220 #endif
00221 if ( useRaster )
00222 {
00223 QImage::Format format = QImage::Format_RGB32;
00224
00225 const QGradientStops stops = brush.gradient()->stops();
00226 for ( int i = 0; i < stops.size(); i++ )
00227 {
00228 if ( stops[i].second.alpha() != 255 )
00229 {
00230
00231
00232
00233
00234 format = QImage::Format_ARGB32;
00235 break;
00236 }
00237 }
00238
00239 QImage image( canvas->size(), format );
00240
00241 QPainter p( &image );
00242 p.setPen( Qt::NoPen );
00243 p.setBrush( brush );
00244
00245 p.drawRects( rects );
00246
00247 p.end();
00248
00249 painter->drawImage( 0, 0, image );
00250 }
00251 else
00252 {
00253 painter->setPen( Qt::NoPen );
00254 painter->setBrush( brush );
00255
00256 painter->drawRects( rects );
00257 }
00258 }
00259 else
00260 {
00261 painter->setPen( Qt::NoPen );
00262 painter->setBrush( brush );
00263
00264 painter->drawRects( painter->clipRegion().rects() );
00265
00266 }
00267
00268 painter->restore();
00269 }
00270
00271 static inline void qwtDrawStyledBackground(
00272 QWidget *w, QPainter *painter )
00273 {
00274 QStyleOption opt;
00275 opt.initFrom(w);
00276 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w);
00277 }
00278
00279 static QWidget *qwtBackgroundWidget( QWidget *w )
00280 {
00281 if ( w->parentWidget() == NULL )
00282 return w;
00283
00284 if ( w->autoFillBackground() )
00285 {
00286 const QBrush brush = w->palette().brush( w->backgroundRole() );
00287 if ( brush.color().alpha() > 0 )
00288 return w;
00289 }
00290
00291 if ( w->testAttribute( Qt::WA_StyledBackground ) )
00292 {
00293 QImage image( 1, 1, QImage::Format_ARGB32 );
00294 image.fill( Qt::transparent );
00295
00296 QPainter painter( &image );
00297 painter.translate( -w->rect().center() );
00298 qwtDrawStyledBackground( w, &painter );
00299 painter.end();
00300
00301 if ( qAlpha( image.pixel( 0, 0 ) ) != 0 )
00302 return w;
00303 }
00304
00305 return qwtBackgroundWidget( w->parentWidget() );
00306 }
00307
00308 static void qwtFillBackground( QPainter *painter,
00309 QWidget *widget, const QVector<QRectF> &fillRects )
00310 {
00311 if ( fillRects.isEmpty() )
00312 return;
00313
00314 QRegion clipRegion;
00315 if ( painter->hasClipping() )
00316 clipRegion = painter->transform().map( painter->clipRegion() );
00317 else
00318 clipRegion = widget->contentsRect();
00319
00320
00321
00322
00323 QWidget *bgWidget = qwtBackgroundWidget( widget->parentWidget() );
00324
00325 for ( int i = 0; i < fillRects.size(); i++ )
00326 {
00327 const QRect rect = fillRects[i].toAlignedRect();
00328 if ( clipRegion.intersects( rect ) )
00329 {
00330 QPixmap pm( rect.size() );
00331 QwtPainter::fillPixmap( bgWidget, pm, widget->mapTo( bgWidget, rect.topLeft() ) );
00332 painter->drawPixmap( rect, pm );
00333 }
00334 }
00335 }
00336
00337 static void qwtFillBackground( QPainter *painter, QWidget *canvas )
00338 {
00339 QVector<QRectF> rects;
00340
00341 if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
00342 {
00343 QwtStyleSheetRecorder recorder( canvas->size() );
00344
00345 QPainter p( &recorder );
00346 qwtDrawStyledBackground( canvas, &p );
00347 p.end();
00348
00349 if ( recorder.background.brush.isOpaque() )
00350 rects = recorder.clipRects;
00351 else
00352 rects += canvas->rect();
00353 }
00354 else
00355 {
00356 const double borderRadius = canvas->property( "borderRadius" ).toDouble();
00357 if ( borderRadius > 0.0 )
00358 {
00359 QSizeF sz( borderRadius, borderRadius );
00360
00361 const QRectF r = canvas->rect();
00362 rects += QRectF( r.topLeft(), sz );
00363 rects += QRectF( r.topRight() - QPointF( borderRadius, 0 ), sz );
00364 rects += QRectF( r.bottomRight() - QPointF( borderRadius, borderRadius ), sz );
00365 rects += QRectF( r.bottomLeft() - QPointF( 0, borderRadius ), sz );
00366 }
00367 }
00368
00369 qwtFillBackground( painter, canvas, rects);
00370 }
00371
00372 static inline void qwtRevertPath( QPainterPath &path )
00373 {
00374 if ( path.elementCount() == 4 )
00375 {
00376 QPainterPath::Element el0 = path.elementAt(0);
00377 QPainterPath::Element el3 = path.elementAt(3);
00378
00379 path.setElementPositionAt( 0, el3.x, el3.y );
00380 path.setElementPositionAt( 3, el0.x, el0.y );
00381 }
00382 }
00383
00384 static QPainterPath qwtCombinePathList( const QRectF &rect,
00385 const QList<QPainterPath> &pathList )
00386 {
00387 if ( pathList.isEmpty() )
00388 return QPainterPath();
00389
00390 QPainterPath ordered[8];
00391
00392 for ( int i = 0; i < pathList.size(); i++ )
00393 {
00394 int index = -1;
00395 QPainterPath subPath = pathList[i];
00396
00397 const QRectF br = pathList[i].controlPointRect();
00398 if ( br.center().x() < rect.center().x() )
00399 {
00400 if ( br.center().y() < rect.center().y() )
00401 {
00402 if ( qAbs( br.top() - rect.top() ) <
00403 qAbs( br.left() - rect.left() ) )
00404 {
00405 index = 1;
00406 }
00407 else
00408 {
00409 index = 0;
00410 }
00411 }
00412 else
00413 {
00414 if ( qAbs( br.bottom() - rect.bottom() ) <
00415 qAbs( br.left() - rect.left() ) )
00416 {
00417 index = 6;
00418 }
00419 else
00420 {
00421 index = 7;
00422 }
00423 }
00424
00425 if ( subPath.currentPosition().y() > br.center().y() )
00426 qwtRevertPath( subPath );
00427 }
00428 else
00429 {
00430 if ( br.center().y() < rect.center().y() )
00431 {
00432 if ( qAbs( br.top() - rect.top() ) <
00433 qAbs( br.right() - rect.right() ) )
00434 {
00435 index = 2;
00436 }
00437 else
00438 {
00439 index = 3;
00440 }
00441 }
00442 else
00443 {
00444 if ( qAbs( br.bottom() - rect.bottom() ) <
00445 qAbs( br.right() - rect.right() ) )
00446 {
00447 index = 5;
00448 }
00449 else
00450 {
00451 index = 4;
00452 }
00453 }
00454 if ( subPath.currentPosition().y() < br.center().y() )
00455 qwtRevertPath( subPath );
00456 }
00457 ordered[index] = subPath;
00458 }
00459
00460 for ( int i = 0; i < 4; i++ )
00461 {
00462 if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() )
00463 {
00464
00465 return QPainterPath();
00466 }
00467 }
00468
00469
00470 const QPolygonF corners( rect );
00471
00472 QPainterPath path;
00473
00474
00475 for ( int i = 0; i < 4; i++ )
00476 {
00477 if ( ordered[2 * i].isEmpty() )
00478 {
00479 path.lineTo( corners[i] );
00480 }
00481 else
00482 {
00483 path.connectPath( ordered[2 * i] );
00484 path.connectPath( ordered[2 * i + 1] );
00485 }
00486 }
00487
00488 path.closeSubpath();
00489
00490 #if 0
00491 return path.simplified();
00492 #else
00493 return path;
00494 #endif
00495 }
00496
00497 static QPainterPath qwtBorderPath( const QWidget *canvas, const QRect &rect )
00498 {
00499 if ( canvas->testAttribute(Qt::WA_StyledBackground ) )
00500 {
00501 QwtStyleSheetRecorder recorder( rect.size() );
00502
00503 QPainter painter( &recorder );
00504
00505 QStyleOption opt;
00506 opt.initFrom( canvas );
00507 opt.rect = rect;
00508 canvas->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, canvas );
00509
00510 painter.end();
00511
00512 if ( !recorder.background.path.isEmpty() )
00513 return recorder.background.path;
00514
00515 if ( !recorder.border.rectList.isEmpty() )
00516 return qwtCombinePathList( rect, recorder.border.pathList );
00517 }
00518 else
00519 {
00520 const double borderRadius = canvas->property( "borderRadius" ).toDouble();
00521
00522 if ( borderRadius > 0.0 )
00523 {
00524 double fw2 = canvas->property( "frameWidth" ).toInt() * 0.5;
00525 QRectF r = QRectF(rect).adjusted( fw2, fw2, -fw2, -fw2 );
00526
00527 QPainterPath path;
00528 path.addRoundedRect( r, borderRadius, borderRadius );
00529 return path;
00530 }
00531 }
00532
00533 return QPainterPath();
00534 }
00535
00536 class QwtPlotAbstractCanvas::PrivateData
00537 {
00538 public:
00539 PrivateData():
00540 focusIndicator( NoFocusIndicator ),
00541 borderRadius( 0 )
00542 {
00543 styleSheet.hasBorder = false;
00544 }
00545
00546 FocusIndicator focusIndicator;
00547 double borderRadius;
00548
00549 struct StyleSheet
00550 {
00551 bool hasBorder;
00552 QPainterPath borderPath;
00553 QVector<QRectF> cornerRects;
00554
00555 struct StyleSheetBackground
00556 {
00557 QBrush brush;
00558 QPointF origin;
00559 } background;
00560
00561 } styleSheet;
00562
00563 QWidget *canvasWidget;
00564 };
00565
00566 QwtPlotAbstractCanvas::QwtPlotAbstractCanvas( QWidget *canvasWidget )
00567 {
00568 d_data = new PrivateData;
00569 d_data->canvasWidget = canvasWidget;
00570
00571 #ifndef QT_NO_CURSOR
00572 canvasWidget->setCursor( Qt::CrossCursor );
00573 #endif
00574
00575 canvasWidget->setAutoFillBackground( true );
00576
00577 canvasWidget->setProperty( "lineWidth", 2 );
00578 canvasWidget->setProperty( "frameShadow", QFrame::Sunken );
00579 canvasWidget->setProperty( "frameShape", QFrame::Panel );
00580 }
00581
00582 QwtPlotAbstractCanvas::~QwtPlotAbstractCanvas()
00583 {
00584 delete d_data;
00585 }
00586
00588 QwtPlot *QwtPlotAbstractCanvas::plot()
00589 {
00590 return qobject_cast<QwtPlot *>( d_data->canvasWidget->parent() );
00591 }
00592
00594 const QwtPlot *QwtPlotAbstractCanvas::plot() const
00595 {
00596 return qobject_cast<const QwtPlot *>( d_data->canvasWidget->parent() );
00597 }
00598
00604 void QwtPlotAbstractCanvas::setFocusIndicator( FocusIndicator focusIndicator )
00605 {
00606 d_data->focusIndicator = focusIndicator;
00607 }
00608
00614 QwtPlotAbstractCanvas::FocusIndicator QwtPlotAbstractCanvas::focusIndicator() const
00615 {
00616 return d_data->focusIndicator;
00617 }
00618
00623 void QwtPlotAbstractCanvas::drawFocusIndicator( QPainter *painter )
00624 {
00625 const int margin = 1;
00626
00627 QRect focusRect = d_data->canvasWidget->contentsRect();
00628 focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
00629 focusRect.width() - 2 * margin, focusRect.height() - 2 * margin );
00630
00631 QwtPainter::drawFocusRect( painter, d_data->canvasWidget, focusRect );
00632 }
00633
00640 void QwtPlotAbstractCanvas::setBorderRadius( double radius )
00641 {
00642 d_data->borderRadius = qMax( 0.0, radius );
00643 }
00644
00649 double QwtPlotAbstractCanvas::borderRadius() const
00650 {
00651 return d_data->borderRadius;
00652 }
00653
00654 QPainterPath QwtPlotAbstractCanvas::borderPath2( const QRect &rect ) const
00655 {
00656 return qwtBorderPath( canvasWidget(), rect );
00657 }
00658
00663 void QwtPlotAbstractCanvas::drawBorder( QPainter *painter )
00664 {
00665 const QWidget *w = canvasWidget();
00666
00667 if ( d_data->borderRadius > 0 )
00668 {
00669 const int frameWidth = w->property( "frameWidth" ).toInt();
00670 if ( frameWidth > 0 )
00671 {
00672 const int frameShape = w->property( "frameShape" ).toInt();
00673 const int frameShadow = w->property( "frameShadow" ).toInt();
00674
00675 const QRectF frameRect = w->property( "frameRect" ).toRect();
00676
00677 QwtPainter::drawRoundedFrame( painter, frameRect,
00678 d_data->borderRadius, d_data->borderRadius,
00679 w->palette(), frameWidth, frameShape | frameShadow );
00680 }
00681 }
00682 else
00683 {
00684 #if QT_VERSION >= 0x040500
00685 const int frameShape = w->property( "frameShape" ).toInt();
00686 const int frameShadow = w->property( "frameShadow" ).toInt();
00687
00688 #if QT_VERSION < 0x050000
00689 QStyleOptionFrameV3 opt;
00690 #else
00691 QStyleOptionFrame opt;
00692 #endif
00693 opt.init( w );
00694
00695 opt.frameShape = QFrame::Shape( int( opt.frameShape ) | frameShape );
00696
00697 switch (frameShape)
00698 {
00699 case QFrame::Box:
00700 case QFrame::HLine:
00701 case QFrame::VLine:
00702 case QFrame::StyledPanel:
00703 case QFrame::Panel:
00704 {
00705 opt.lineWidth = w->property( "lineWidth" ).toInt();
00706 opt.midLineWidth = w->property( "midLineWidth" ).toInt();
00707 break;
00708 }
00709 default:
00710 {
00711 opt.lineWidth = w->property( "frameWidth" ).toInt();
00712 break;
00713 }
00714 }
00715
00716 if ( frameShadow == QFrame::Sunken )
00717 opt.state |= QStyle::State_Sunken;
00718 else if ( frameShadow == QFrame::Raised )
00719 opt.state |= QStyle::State_Raised;
00720
00721 w->style()->drawControl(QStyle::CE_ShapedFrame, &opt, painter, w );
00722 #else
00723
00724 #endif
00725 }
00726 }
00727
00728 void QwtPlotAbstractCanvas::drawBackground( QPainter *painter )
00729 {
00730 qwtDrawBackground( painter, canvasWidget() );
00731 }
00732
00733 void QwtPlotAbstractCanvas::fillBackground( QPainter *painter )
00734 {
00735 qwtFillBackground( painter, canvasWidget() );
00736 }
00737
00738 void QwtPlotAbstractCanvas::drawUnstyled( QPainter *painter )
00739 {
00740 fillBackground( painter );
00741
00742 QWidget *w = canvasWidget();
00743
00744 if ( w->autoFillBackground() )
00745 {
00746 const QRect canvasRect = w->rect();
00747
00748 painter->save();
00749
00750 painter->setPen( Qt::NoPen );
00751 painter->setBrush( w->palette().brush( w->backgroundRole() ) );
00752
00753 const QRect frameRect = w->property( "frameRect" ).toRect();
00754 if ( borderRadius() > 0.0 && ( canvasRect == frameRect ) )
00755 {
00756 const int frameWidth = w->property( "frameWidth" ).toInt();
00757 if ( frameWidth > 0 )
00758 {
00759 painter->setClipPath( borderPath2( canvasRect ) );
00760 painter->drawRect( canvasRect );
00761 }
00762 else
00763 {
00764 painter->setRenderHint( QPainter::Antialiasing, true );
00765 painter->drawPath( borderPath2( canvasRect ) );
00766 }
00767 }
00768 else
00769 {
00770 painter->drawRect( canvasRect );
00771 }
00772
00773 painter->restore();
00774 }
00775
00776 drawCanvas( painter );
00777 }
00778
00779 void QwtPlotAbstractCanvas::drawStyled( QPainter *painter, bool hackStyledBackground )
00780 {
00781 fillBackground( painter );
00782
00783 if ( hackStyledBackground )
00784 {
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 if ( !d_data->styleSheet.hasBorder ||
00798 d_data->styleSheet.borderPath.isEmpty() )
00799 {
00800
00801 hackStyledBackground = false;
00802 }
00803 }
00804
00805 QWidget *w = canvasWidget();
00806
00807 if ( hackStyledBackground )
00808 {
00809 painter->save();
00810
00811
00812 painter->setPen( Qt::NoPen );
00813 painter->setBrush( d_data->styleSheet.background.brush );
00814 painter->setBrushOrigin( d_data->styleSheet.background.origin );
00815 painter->setClipPath( d_data->styleSheet.borderPath );
00816 painter->drawRect( w->contentsRect() );
00817
00818 painter->restore();
00819
00820 drawCanvas( painter );
00821
00822
00823 QStyleOptionFrame opt;
00824 opt.initFrom( w );
00825 w->style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, w);
00826 }
00827 else
00828 {
00829 QStyleOption opt;
00830 opt.initFrom( w );
00831 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w );
00832
00833 drawCanvas( painter );
00834 }
00835 }
00836
00837 void QwtPlotAbstractCanvas::drawCanvas( QPainter *painter )
00838 {
00839 QWidget *w = canvasWidget();
00840
00841 painter->save();
00842
00843 if ( !d_data->styleSheet.borderPath.isEmpty() )
00844 {
00845 painter->setClipPath(
00846 d_data->styleSheet.borderPath, Qt::IntersectClip );
00847 }
00848 else
00849 {
00850 if ( borderRadius() > 0.0 )
00851 {
00852 const QRect frameRect = w->property( "frameRect" ).toRect();
00853 painter->setClipPath( borderPath2( frameRect ), Qt::IntersectClip );
00854 }
00855 else
00856 {
00857 painter->setClipRect( w->contentsRect(), Qt::IntersectClip );
00858 }
00859 }
00860
00861 QwtPlot *plot = qobject_cast< QwtPlot *>( w->parent() );
00862 if ( plot )
00863 plot->drawCanvas( painter );
00864
00865 painter->restore();
00866 }
00867
00869 void QwtPlotAbstractCanvas::updateStyleSheetInfo()
00870 {
00871 QWidget *w = canvasWidget();
00872
00873 if ( !w->testAttribute( Qt::WA_StyledBackground ) )
00874 return;
00875
00876 QwtStyleSheetRecorder recorder( w->size() );
00877
00878 QPainter painter( &recorder );
00879
00880 QStyleOption opt;
00881 opt.initFrom(w);
00882 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, w);
00883
00884 painter.end();
00885
00886 d_data->styleSheet.hasBorder = !recorder.border.rectList.isEmpty();
00887 d_data->styleSheet.cornerRects = recorder.clipRects;
00888
00889 if ( recorder.background.path.isEmpty() )
00890 {
00891 if ( !recorder.border.rectList.isEmpty() )
00892 {
00893 d_data->styleSheet.borderPath =
00894 qwtCombinePathList( w->rect(), recorder.border.pathList );
00895 }
00896 }
00897 else
00898 {
00899 d_data->styleSheet.borderPath = recorder.background.path;
00900 d_data->styleSheet.background.brush = recorder.background.brush;
00901 d_data->styleSheet.background.origin = recorder.background.origin;
00902 }
00903 }
00904
00905 QWidget* QwtPlotAbstractCanvas::canvasWidget()
00906 {
00907 return d_data->canvasWidget;
00908 }
00909
00910 const QWidget* QwtPlotAbstractCanvas::canvasWidget() const
00911 {
00912 return d_data->canvasWidget;
00913 }
00914
00915 class QwtPlotAbstractGLCanvas::PrivateData
00916 {
00917 public:
00918 PrivateData():
00919 frameStyle( QFrame::Panel | QFrame::Sunken),
00920 lineWidth( 2 ),
00921 midLineWidth( 0 )
00922 {
00923 }
00924
00925 ~PrivateData()
00926 {
00927 }
00928
00929 QwtPlotAbstractGLCanvas::PaintAttributes paintAttributes;
00930
00931 int frameStyle;
00932 int lineWidth;
00933 int midLineWidth;
00934 };
00935
00936 QwtPlotAbstractGLCanvas::QwtPlotAbstractGLCanvas( QWidget *canvasWidget ):
00937 QwtPlotAbstractCanvas( canvasWidget )
00938 {
00939 d_data = new PrivateData;
00940
00941 qwtUpdateContentsRect( frameWidth(), canvasWidget );
00942 d_data->paintAttributes = QwtPlotAbstractGLCanvas::BackingStore;
00943 }
00944
00945 QwtPlotAbstractGLCanvas::~QwtPlotAbstractGLCanvas()
00946 {
00947 delete d_data;
00948 }
00949
00958 void QwtPlotAbstractGLCanvas::setPaintAttribute( PaintAttribute attribute, bool on )
00959 {
00960 if ( bool( d_data->paintAttributes & attribute ) == on )
00961 return;
00962
00963 if ( on )
00964 {
00965 d_data->paintAttributes |= attribute;
00966 }
00967 else
00968 {
00969 d_data->paintAttributes &= ~attribute;
00970
00971 if ( attribute == BackingStore )
00972 clearBackingStore();
00973 }
00974 }
00975
00983 bool QwtPlotAbstractGLCanvas::testPaintAttribute( PaintAttribute attribute ) const
00984 {
00985 return d_data->paintAttributes & attribute;
00986 }
00987
00996 void QwtPlotAbstractGLCanvas::setFrameStyle( int style )
00997 {
00998 if ( style != d_data->frameStyle )
00999 {
01000 d_data->frameStyle = style;
01001 qwtUpdateContentsRect( frameWidth(), canvasWidget() );
01002
01003 canvasWidget()->update();
01004 }
01005 }
01006
01011 int QwtPlotAbstractGLCanvas::frameStyle() const
01012 {
01013 return d_data->frameStyle;
01014 }
01015
01022 void QwtPlotAbstractGLCanvas::setFrameShadow( QFrame::Shadow shadow )
01023 {
01024 setFrameStyle(( d_data->frameStyle & QFrame::Shape_Mask ) | shadow );
01025 }
01026
01031 QFrame::Shadow QwtPlotAbstractGLCanvas::frameShadow() const
01032 {
01033 return (QFrame::Shadow) ( d_data->frameStyle & QFrame::Shadow_Mask );
01034 }
01035
01042 void QwtPlotAbstractGLCanvas::setFrameShape( QFrame::Shape shape )
01043 {
01044 setFrameStyle( ( d_data->frameStyle & QFrame::Shadow_Mask ) | shape );
01045 }
01046
01051 QFrame::Shape QwtPlotAbstractGLCanvas::frameShape() const
01052 {
01053 return (QFrame::Shape) ( d_data->frameStyle & QFrame::Shape_Mask );
01054 }
01055
01064 void QwtPlotAbstractGLCanvas::setLineWidth( int width )
01065 {
01066 width = qMax( width, 0 );
01067 if ( width != d_data->lineWidth )
01068 {
01069 d_data->lineWidth = qMax( width, 0 );
01070 qwtUpdateContentsRect( frameWidth(), canvasWidget() );
01071 canvasWidget()->update();
01072 }
01073 }
01074
01079 int QwtPlotAbstractGLCanvas::lineWidth() const
01080 {
01081 return d_data->lineWidth;
01082 }
01083
01092 void QwtPlotAbstractGLCanvas::setMidLineWidth( int width )
01093 {
01094 width = qMax( width, 0 );
01095 if ( width != d_data->midLineWidth )
01096 {
01097 d_data->midLineWidth = width;
01098 qwtUpdateContentsRect( frameWidth(), canvasWidget() );
01099 canvasWidget()->update();
01100 }
01101 }
01102
01107 int QwtPlotAbstractGLCanvas::midLineWidth() const
01108 {
01109 return d_data->midLineWidth;
01110 }
01111
01115 int QwtPlotAbstractGLCanvas::frameWidth() const
01116 {
01117 return ( frameStyle() != QFrame::NoFrame ) ? d_data->lineWidth : 0;
01118 }
01119
01124 void QwtPlotAbstractGLCanvas::replot()
01125 {
01126 invalidateBackingStore();
01127
01128 QWidget *w = canvasWidget();
01129 if ( testPaintAttribute( QwtPlotAbstractGLCanvas::ImmediatePaint ) )
01130 w->repaint( w->contentsRect() );
01131 else
01132 w->update( w->contentsRect() );
01133 }
01134
01136 QRect QwtPlotAbstractGLCanvas::frameRect() const
01137 {
01138 const int fw = frameWidth();
01139 return canvasWidget()->contentsRect().adjusted( -fw, -fw, fw, fw );
01140 }
01141
01142 void QwtPlotAbstractGLCanvas::draw( QPainter *painter )
01143 {
01144 #if FIX_GL_TRANSLATION
01145 if ( painter->paintEngine()->type() == QPaintEngine::OpenGL2 )
01146 {
01147
01148 painter->translate( 1, 1 );
01149 }
01150 #endif
01151
01152 if ( canvasWidget()->testAttribute( Qt::WA_StyledBackground ) )
01153 drawStyled( painter, true );
01154 else
01155 drawUnstyled( painter );
01156
01157 if ( frameWidth() > 0 )
01158 drawBorder( painter );
01159 }