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