17 #include <qpainterpath.h> 19 #include <qstyleoption.h> 26 explicit QwtStyleSheetRecorder(
const QSize &size ):
33 if (
state.state() & QPaintEngine::DirtyPen )
37 if (
state.state() & QPaintEngine::DirtyBrush )
39 d_brush =
state.brush();
41 if (
state.state() & QPaintEngine::DirtyBrushOrigin )
43 d_origin =
state.brushOrigin();
49 for (
int i = 0; i <
count; i++ )
50 border.rectList += rects[i];
55 for (
int i = 0; i <
count; i++ )
56 border.rectList += rects[i];
61 const QRectF rect( QPointF( 0.0, 0.0 ), d_size );
62 if ( path.controlPointRect().contains( rect.center() ) )
64 setCornerRects( path );
65 alignCornerRects( rect );
67 background.path = path;
68 background.brush = d_brush;
69 background.origin = d_origin;
73 border.pathList += path;
77 void setCornerRects(
const QPainterPath &path )
79 QPointF pos( 0.0, 0.0 );
81 for (
int i = 0; i < path.elementCount(); i++ )
83 QPainterPath::Element el = path.elementAt(i);
86 case QPainterPath::MoveToElement:
87 case QPainterPath::LineToElement:
93 case QPainterPath::CurveToElement:
95 QRectF r( pos, QPointF( el.x, el.y ) );
96 clipRects += r.normalized();
103 case QPainterPath::CurveToDataElement:
105 if ( clipRects.size() > 0 )
107 QRectF r = clipRects.last();
114 clipRects.last() = r.normalized();
129 void alignCornerRects(
const QRectF &rect )
131 for (
int i = 0; i < clipRects.size(); i++ )
133 QRectF &r = clipRects[i];
134 if ( r.center().x() < rect.center().x() )
135 r.setLeft( rect.left() );
137 r.setRight( rect.right() );
139 if ( r.center().y() < rect.center().y() )
140 r.setTop( rect.top() );
142 r.setBottom( rect.bottom() );
175 canvas->setContentsMargins( fw, fw, fw, fw );
180 #if QT_VERSION >= 0x050800 181 for ( QRegion::const_iterator it = region.cbegin();
182 it != region.cend(); ++it )
184 painter->drawRect( *it );
187 painter->drawRects( region.rects() );
195 QPainterPath borderClip;
197 (
void )QMetaObject::invokeMethod(
198 canvas,
"borderPath", Qt::DirectConnection,
199 Q_RETURN_ARG( QPainterPath, borderClip ), Q_ARG( QRect, canvas->rect() ) );
201 if ( !borderClip.isEmpty() )
202 painter->setClipPath( borderClip, Qt::IntersectClip );
204 const QBrush &brush = canvas->palette().brush( canvas->backgroundRole() );
206 if ( brush.style() == Qt::TexturePattern )
208 QPixmap pm( canvas->size() );
210 painter->drawPixmap( 0, 0, pm );
212 else if ( brush.gradient() )
214 const bool fillClipRegion =
215 brush.gradient()->coordinateMode() != QGradient::ObjectBoundingMode;
217 painter->setPen( Qt::NoPen );
218 painter->setBrush( brush );
220 if ( fillClipRegion )
223 painter->drawRect( canvas->rect() );
227 painter->setPen( Qt::NoPen );
228 painter->setBrush( brush );
236 QWidget *w, QPainter *painter )
240 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w);
245 if ( w->parentWidget() == NULL )
248 if ( w->autoFillBackground() )
250 const QBrush brush = w->palette().brush( w->backgroundRole() );
251 if ( brush.color().alpha() > 0 )
255 if ( w->testAttribute( Qt::WA_StyledBackground ) )
257 QImage image( 1, 1, QImage::Format_ARGB32 );
258 image.fill( Qt::transparent );
260 QPainter painter( &image );
261 painter.translate( -w->rect().center() );
265 if ( qAlpha( image.pixel( 0, 0 ) ) != 0 )
275 if ( fillRects.isEmpty() )
279 if ( painter->hasClipping() )
280 clipRegion = painter->transform().map( painter->clipRegion() );
282 clipRegion = widget->contentsRect();
289 for (
int i = 0; i < fillRects.size(); i++ )
291 const QRect rect = fillRects[i].toAlignedRect();
292 if ( clipRegion.intersects( rect ) )
294 QPixmap pm( rect.size() );
296 painter->drawPixmap( rect, pm );
305 if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
307 QwtStyleSheetRecorder recorder( canvas->size() );
309 QPainter p( &recorder );
313 if ( recorder.background.brush.isOpaque() )
314 rects = recorder.clipRects;
316 rects += canvas->rect();
320 const double borderRadius = canvas->property(
"borderRadius" ).toDouble();
321 if ( borderRadius > 0.0 )
323 QSizeF sz( borderRadius, borderRadius );
325 const QRectF r = canvas->rect();
326 rects += QRectF( r.topLeft(), sz );
327 rects += QRectF( r.topRight() - QPointF( borderRadius, 0 ), sz );
328 rects += QRectF( r.bottomRight() - QPointF( borderRadius, borderRadius ), sz );
329 rects += QRectF( r.bottomLeft() - QPointF( 0, borderRadius ), sz );
338 if ( path.elementCount() == 4 )
340 QPainterPath::Element el0 = path.elementAt(0);
341 QPainterPath::Element el3 = path.elementAt(3);
343 path.setElementPositionAt( 0, el3.x, el3.y );
344 path.setElementPositionAt( 3, el0.x, el0.y );
351 if ( pathList.isEmpty() )
352 return QPainterPath();
354 QPainterPath ordered[8];
356 for (
int i = 0; i < pathList.size(); i++ )
359 QPainterPath subPath = pathList[i];
361 const QRectF br = pathList[i].controlPointRect();
362 if ( br.center().x() < rect.center().x() )
364 if ( br.center().y() < rect.center().y() )
366 if ( qAbs( br.top() - rect.top() ) <
367 qAbs( br.left() - rect.left() ) )
378 if ( qAbs( br.bottom() - rect.bottom() ) <
379 qAbs( br.left() - rect.left() ) )
389 if ( subPath.currentPosition().y() > br.center().y() )
394 if ( br.center().y() < rect.center().y() )
396 if ( qAbs( br.top() - rect.top() ) <
397 qAbs( br.right() - rect.right() ) )
408 if ( qAbs( br.bottom() - rect.bottom() ) <
409 qAbs( br.right() - rect.right() ) )
418 if ( subPath.currentPosition().y() < br.center().y() )
421 ordered[index] = subPath;
424 for (
int i = 0; i < 4; i++ )
426 if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() )
429 return QPainterPath();
434 const QPolygonF corners( rect );
439 for (
int i = 0; i < 4; i++ )
441 if ( ordered[2 * i].isEmpty() )
443 path.lineTo( corners[i] );
447 path.connectPath( ordered[2 * i] );
448 path.connectPath( ordered[2 * i + 1] );
455 return path.simplified();
461 static QPainterPath
qwtBorderPath(
const QWidget *canvas,
const QRect &rect )
463 if ( canvas->testAttribute(Qt::WA_StyledBackground ) )
465 QwtStyleSheetRecorder recorder( rect.size() );
467 QPainter painter( &recorder );
470 opt.initFrom( canvas );
472 canvas->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, canvas );
476 if ( !recorder.background.path.isEmpty() )
477 return recorder.background.path;
479 if ( !recorder.border.rectList.isEmpty() )
484 const double borderRadius = canvas->property(
"borderRadius" ).toDouble();
486 if ( borderRadius > 0.0 )
488 double fw2 = canvas->property(
"frameWidth" ).toInt() * 0.5;
489 QRectF r = QRectF(rect).adjusted( fw2, fw2, -fw2, -fw2 );
492 path.addRoundedRect( r, borderRadius, borderRadius );
497 return QPainterPath();
504 focusIndicator( NoFocusIndicator ),
507 styleSheet.hasBorder =
false;
536 canvasWidget->setCursor( Qt::CrossCursor );
539 canvasWidget->setAutoFillBackground(
true );
541 canvasWidget->setProperty(
"lineWidth", 2 );
542 canvasWidget->setProperty(
"frameShadow", QFrame::Sunken );
543 canvasWidget->setProperty(
"frameShape", QFrame::Panel );
554 return qobject_cast<
QwtPlot *>( d_data->canvasWidget->parent() );
560 return qobject_cast<
const QwtPlot *>( d_data->canvasWidget->parent() );
570 d_data->focusIndicator = focusIndicator;
580 return d_data->focusIndicator;
589 const int margin = 1;
591 QRect focusRect = d_data->canvasWidget->contentsRect();
592 focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
593 focusRect.width() - 2 * margin, focusRect.height() - 2 * margin );
606 d_data->borderRadius =
qwtMaxF( 0.0, radius );
615 return d_data->borderRadius;
629 const QWidget *w = canvasWidget();
631 if ( d_data->borderRadius > 0 )
633 const int frameWidth = w->property(
"frameWidth" ).toInt();
634 if ( frameWidth > 0 )
636 const int frameShape = w->property(
"frameShape" ).toInt();
637 const int frameShadow = w->property(
"frameShadow" ).toInt();
639 const QRectF frameRect = w->property(
"frameRect" ).toRect();
642 d_data->borderRadius, d_data->borderRadius,
643 w->palette(), frameWidth, frameShape | frameShadow );
648 const int frameShape = w->property(
"frameShape" ).toInt();
649 const int frameShadow = w->property(
"frameShadow" ).toInt();
651 #if QT_VERSION < 0x050000 652 QStyleOptionFrameV3 opt;
654 QStyleOptionFrame opt;
658 opt.frameShape = QFrame::Shape(
int( opt.frameShape ) | frameShape );
665 case QFrame::StyledPanel:
668 opt.lineWidth = w->property(
"lineWidth" ).toInt();
669 opt.midLineWidth = w->property(
"midLineWidth" ).toInt();
674 opt.lineWidth = w->property(
"frameWidth" ).toInt();
679 if ( frameShadow == QFrame::Sunken )
680 opt.state |= QStyle::State_Sunken;
681 else if ( frameShadow == QFrame::Raised )
682 opt.state |= QStyle::State_Raised;
684 w->style()->drawControl(QStyle::CE_ShapedFrame, &opt, painter, w );
700 fillBackground( painter );
702 QWidget *w = canvasWidget();
704 if ( w->autoFillBackground() )
706 const QRect canvasRect = w->rect();
710 painter->setPen( Qt::NoPen );
711 painter->setBrush( w->palette().brush( w->backgroundRole() ) );
713 const QRect frameRect = w->property(
"frameRect" ).toRect();
714 if ( borderRadius() > 0.0 && ( canvasRect == frameRect ) )
716 const int frameWidth = w->property(
"frameWidth" ).toInt();
717 if ( frameWidth > 0 )
719 painter->setClipPath( borderPath2( canvasRect ) );
720 painter->drawRect( canvasRect );
724 painter->setRenderHint( QPainter::Antialiasing,
true );
725 painter->drawPath( borderPath2( canvasRect ) );
730 painter->drawRect( canvasRect );
736 drawCanvas( painter );
741 fillBackground( painter );
743 if ( hackStyledBackground )
757 if ( !d_data->styleSheet.hasBorder ||
758 d_data->styleSheet.borderPath.isEmpty() )
761 hackStyledBackground =
false;
765 QWidget *w = canvasWidget();
767 if ( hackStyledBackground )
772 painter->setPen( Qt::NoPen );
773 painter->setBrush( d_data->styleSheet.background.brush );
774 painter->setBrushOrigin( d_data->styleSheet.background.origin );
775 painter->setClipPath( d_data->styleSheet.borderPath );
776 painter->drawRect( w->contentsRect() );
780 drawCanvas( painter );
783 QStyleOptionFrame opt;
785 w->style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, w);
791 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w );
793 drawCanvas( painter );
799 QWidget *w = canvasWidget();
803 if ( !d_data->styleSheet.borderPath.isEmpty() )
805 painter->setClipPath(
806 d_data->styleSheet.borderPath, Qt::IntersectClip );
810 if ( borderRadius() > 0.0 )
812 const QRect frameRect = w->property(
"frameRect" ).toRect();
813 painter->setClipPath( borderPath2( frameRect ), Qt::IntersectClip );
817 painter->setClipRect( w->contentsRect(), Qt::IntersectClip );
831 QWidget *w = canvasWidget();
833 if ( !w->testAttribute( Qt::WA_StyledBackground ) )
836 QwtStyleSheetRecorder recorder( w->size() );
838 QPainter painter( &recorder );
842 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, w);
846 d_data->styleSheet.hasBorder = !recorder.border.rectList.isEmpty();
847 d_data->styleSheet.cornerRects = recorder.clipRects;
849 if ( recorder.background.path.isEmpty() )
851 if ( !recorder.border.rectList.isEmpty() )
853 d_data->styleSheet.borderPath =
859 d_data->styleSheet.borderPath = recorder.background.path;
860 d_data->styleSheet.background.brush = recorder.background.brush;
861 d_data->styleSheet.background.origin = recorder.background.origin;
867 return d_data->canvasWidget;
872 return d_data->canvasWidget;
879 frameStyle( QFrame::Panel | QFrame::Sunken),
1026 width = qMax( width, 0 );
1054 width = qMax( width, 0 );
1090 w->repaint( w->contentsRect() );
1092 w->update( w->contentsRect() );
1099 return canvasWidget()->contentsRect().adjusted( -fw, -fw, fw, fw );
1104 #if FIX_GL_TRANSLATION 1105 if ( painter->paintEngine()->type() == QPaintEngine::OpenGL2 )
1108 painter->translate( 1, 1 );
1112 if (
canvasWidget()->testAttribute( Qt::WA_StyledBackground ) )
virtual void clearBackingStore()=0
Paint double buffered reusing the content of the pixmap buffer when possible.
virtual void drawBackground(QPainter *)
static void fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())
QVector< QRectF > cornerRects
virtual void drawRects(const QRect *, int)
See QPaintEngine::drawRects()
static void qwtRevertPath(QPainterPath &path)
void setPaintAttribute(PaintAttribute, bool on=true)
Changing the paint attributes.
static void drawFocusRect(QPainter *, const QWidget *)
Draw a focus rectangle on a widget using its style.
bool testPaintAttribute(PaintAttribute) const
void setBorderRadius(double)
QWT_CONSTEXPR float qwtMaxF(float a, float b)
void drawCanvas(QPainter *)
double borderRadius() const
QwtPlotAbstractGLCanvas::PaintAttributes paintAttributes
void drawUnstyled(QPainter *)
A null paint device doing nothing.
void setFrameStyle(int style)
FocusIndicator focusIndicator() const
static void qwtUpdateContentsRect(int fw, QWidget *canvas)
static void qwtDrawBackground(QPainter *painter, QWidget *canvas)
virtual void updateState(const QPaintEngineState &)
See QPaintEngine::updateState()
QWT_CONSTEXPR float qwtMinF(float a, float b)
void drawStyled(QPainter *, bool)
virtual ~QwtPlotAbstractGLCanvas()
static void drawRoundedFrame(QPainter *, const QRectF &, qreal xRadius, qreal yRadius, const QPalette &, int lineWidth, int frameStyle)
FocusIndicator focusIndicator
void setMidLineWidth(int)
virtual void drawPath(const QPainterPath &)
See QPaintEngine::drawPath()
virtual void drawCanvas(QPainter *)
QFrame::Shape frameShape() const
static QPainterPath qwtBorderPath(const QWidget *canvas, const QRect &rect)
static QPainterPath qwtCombinePathList(const QRectF &rect, const QList< QPainterPath > &pathList)
QFrame::Shadow frameShadow() const
static void qwtDrawStyledBackground(QWidget *w, QPainter *painter)
QwtPlotAbstractGLCanvas(QWidget *canvasWidget)
void setFrameShape(QFrame::Shape)
void setFocusIndicator(FocusIndicator)
virtual QSize sizeMetrics() const =0
virtual ~QwtPlotAbstractCanvas()
QPainterPath borderPath2(const QRect &rect) const
virtual void drawBorder(QPainter *)
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
FocusIndicator
Focus indicator The default setting is NoFocusIndicator.
QwtPlot * plot()
Return parent plot widget.
static QWidget * qwtBackgroundWidget(QWidget *w)
QwtPlotAbstractCanvas(QWidget *canvasWidget)
void setFrameShadow(QFrame::Shadow)
virtual void drawFocusIndicator(QPainter *)
static void qwtFillRegion(QPainter *painter, const QRegion ®ion)
void fillBackground(QPainter *)
void updateStyleSheetInfo()
Update the cached information about the current style sheet.
static void qwtFillBackground(QPainter *painter, QWidget *widget, const QVector< QRectF > &fillRects)
virtual void invalidateBackingStore()=0
PaintAttribute
Paint attributes.