Qwt User's Guide 6.2.0

qwt_plot_abstract_canvas.cpp
1 /******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10 #include "qwt_plot_abstract_canvas.h"
11 #include "qwt_plot.h"
12 #include "qwt_painter.h"
13 #include "qwt_null_paintdevice.h"
14 #include "qwt_math.h"
15
16 #include <qpainter.h>
17 #include <qpainterpath.h>
18 #include <qstyle.h>
19 #include <qstyleoption.h>
20
21 namespace
22 {
23 class QwtStyleSheetRecorder QWT_FINAL : public QwtNullPaintDevice
24 {
25 public:
26 explicit QwtStyleSheetRecorder( const QSize& size )
27 : m_size( size )
28 {
29 }
30
31 virtual void updateState( const QPaintEngineState& state ) QWT_OVERRIDE
32 {
33 if ( state.state() & QPaintEngine::DirtyPen )
34 {
35 m_pen = state.pen();
36 }
37 if ( state.state() & QPaintEngine::DirtyBrush )
38 {
39 m_brush = state.brush();
40 }
41 if ( state.state() & QPaintEngine::DirtyBrushOrigin )
42 {
43 m_origin = state.brushOrigin();
44 }
45 }
46
47 virtual void drawRects(const QRectF* rects, int count ) QWT_OVERRIDE
48 {
49 for ( int i = 0; i < count; i++ )
50 border.rectList += rects[i];
51 }
52
53 virtual void drawRects(const QRect* rects, int count ) QWT_OVERRIDE
54 {
55 for ( int i = 0; i < count; i++ )
56 border.rectList += rects[i];
57 }
58
59 virtual void drawPath( const QPainterPath& path ) QWT_OVERRIDE
60 {
61 const QRectF rect( QPointF( 0.0, 0.0 ), m_size );
62 if ( path.controlPointRect().contains( rect.center() ) )
63 {
64 setCornerRects( path );
65 alignCornerRects( rect );
66
67 background.path = path;
68 background.brush = m_brush;
69 background.origin = m_origin;
70 }
71 else
72 {
73 border.pathList += path;
74 }
75 }
76
77 void setCornerRects( const QPainterPath& path )
78 {
79 QPointF pos( 0.0, 0.0 );
80
81 for ( int i = 0; i < path.elementCount(); i++ )
82 {
83 QPainterPath::Element el = path.elementAt(i);
84 switch( el.type )
85 {
86 case QPainterPath::MoveToElement:
87 case QPainterPath::LineToElement:
88 {
89 pos.setX( el.x );
90 pos.setY( el.y );
91 break;
92 }
93 case QPainterPath::CurveToElement:
94 {
95 QRectF r( pos, QPointF( el.x, el.y ) );
96 clipRects += r.normalized();
97
98 pos.setX( el.x );
99 pos.setY( el.y );
100
101 break;
102 }
103 case QPainterPath::CurveToDataElement:
104 {
105 if ( clipRects.size() > 0 )
106 {
107 QRectF r = clipRects.last();
108 r.setCoords(
109 qwtMinF( r.left(), el.x ),
110 qwtMinF( r.top(), el.y ),
111 qwtMaxF( r.right(), el.x ),
112 qwtMaxF( r.bottom(), el.y )
113 );
114 clipRects.last() = r.normalized();
115 }
116 break;
117 }
118 }
119 }
120 }
121
122 protected:
123 virtual QSize sizeMetrics() const QWT_OVERRIDE
124 {
125 return m_size;
126 }
127
128 private:
129 void alignCornerRects( const QRectF& rect )
130 {
131 for ( int i = 0; i < clipRects.size(); i++ )
132 {
133 QRectF& r = clipRects[i];
134 if ( r.center().x() < rect.center().x() )
135 r.setLeft( rect.left() );
136 else
137 r.setRight( rect.right() );
138
139 if ( r.center().y() < rect.center().y() )
140 r.setTop( rect.top() );
141 else
142 r.setBottom( rect.bottom() );
143 }
144 }
145
146
147 public:
148 QVector< QRectF > clipRects;
149
150 struct Border
151 {
152 QList< QPainterPath > pathList;
153 QList< QRectF > rectList;
154 QRegion clipRegion;
155 } border;
156
157 struct Background
158 {
159 QPainterPath path;
160 QBrush brush;
161 QPointF origin;
162 } background;
163
164 private:
165 const QSize m_size;
166
167 QPen m_pen;
168 QBrush m_brush;
169 QPointF m_origin;
170 };
171 }
172
173 static void qwtUpdateContentsRect( int fw, QWidget* canvas )
174 {
175 canvas->setContentsMargins( fw, fw, fw, fw );
176 }
177
178 static void qwtFillRegion( QPainter* painter, const QRegion& region )
179 {
180 #if QT_VERSION >= 0x050800
181 for ( QRegion::const_iterator it = region.cbegin();
182 it != region.cend(); ++it )
183 {
184 painter->drawRect( *it );
185 }
186 #else
187 painter->drawRects( region.rects() );
188 #endif
189 }
190
191 static void qwtDrawBackground( QPainter* painter, QWidget* canvas )
192 {
193 painter->save();
194
195 QPainterPath borderClip;
196
197 ( void )QMetaObject::invokeMethod(
198 canvas, "borderPath", Qt::DirectConnection,
199 Q_RETURN_ARG( QPainterPath, borderClip ), Q_ARG( QRect, canvas->rect() ) );
200
201 if ( !borderClip.isEmpty() )
202 painter->setClipPath( borderClip, Qt::IntersectClip );
203
204 const QBrush& brush = canvas->palette().brush( canvas->backgroundRole() );
205
206 if ( brush.style() == Qt::TexturePattern )
207 {
208 QPixmap pm( canvas->size() );
209 QwtPainter::fillPixmap( canvas, pm );
210 painter->drawPixmap( 0, 0, pm );
211 }
212 else if ( brush.gradient() )
213 {
214 const bool fillClipRegion =
215 brush.gradient()->coordinateMode() != QGradient::ObjectBoundingMode;
216
217 painter->setPen( Qt::NoPen );
218 painter->setBrush( brush );
219
220 if ( fillClipRegion )
221 qwtFillRegion( painter, painter->clipRegion() );
222 else
223 painter->drawRect( canvas->rect() );
224 }
225 else
226 {
227 painter->setPen( Qt::NoPen );
228 painter->setBrush( brush );
229 qwtFillRegion( painter, painter->clipRegion() );
230 }
231
232 painter->restore();
233 }
234
235 static inline void qwtDrawStyledBackground(
236 QWidget* w, QPainter* painter )
237 {
238 QStyleOption opt;
239 opt.initFrom(w);
240 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w);
241 }
242
243 static QWidget* qwtBackgroundWidget( QWidget* w )
244 {
245 if ( w->parentWidget() == NULL )
246 return w;
247
248 if ( w->autoFillBackground() )
249 {
250 const QBrush brush = w->palette().brush( w->backgroundRole() );
251 if ( brush.color().alpha() > 0 )
252 return w;
253 }
254
255 if ( w->testAttribute( Qt::WA_StyledBackground ) )
256 {
257 QImage image( 1, 1, QImage::Format_ARGB32 );
258 image.fill( Qt::transparent );
259
260 QPainter painter( &image );
261 painter.translate( -w->rect().center() );
262 qwtDrawStyledBackground( w, &painter );
263 painter.end();
264
265 if ( qAlpha( image.pixel( 0, 0 ) ) != 0 )
266 return w;
267 }
268
269 return qwtBackgroundWidget( w->parentWidget() );
270 }
271
272 static void qwtFillBackground( QPainter* painter,
273 QWidget* widget, const QVector< QRectF >& fillRects )
274 {
275 if ( fillRects.isEmpty() )
276 return;
277
278 QRegion clipRegion;
279 if ( painter->hasClipping() )
280 clipRegion = painter->transform().map( painter->clipRegion() );
281 else
282 clipRegion = widget->contentsRect();
283
284 // Try to find out which widget fills
285 // the unfilled areas of the styled background
286
287 QWidget* bgWidget = qwtBackgroundWidget( widget->parentWidget() );
288
289 for ( int i = 0; i < fillRects.size(); i++ )
290 {
291 const QRect rect = fillRects[i].toAlignedRect();
292 if ( clipRegion.intersects( rect ) )
293 {
294 QPixmap pm( rect.size() );
295 QwtPainter::fillPixmap( bgWidget, pm, widget->mapTo( bgWidget, rect.topLeft() ) );
296 painter->drawPixmap( rect, pm );
297 }
298 }
299 }
300
301 static void qwtFillBackground( QPainter* painter, QWidget* canvas )
302 {
303 QVector< QRectF > rects;
304
305 if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
306 {
307 QwtStyleSheetRecorder recorder( canvas->size() );
308
309 QPainter p( &recorder );
310 qwtDrawStyledBackground( canvas, &p );
311 p.end();
312
313 if ( recorder.background.brush.isOpaque() )
314 rects = recorder.clipRects;
315 else
316 rects += canvas->rect();
317 }
318 else
319 {
320 const double borderRadius = canvas->property( "borderRadius" ).toDouble();
321 if ( borderRadius > 0.0 )
322 {
323 QSizeF sz( borderRadius, borderRadius );
324
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 );
330 }
331 }
332
333 qwtFillBackground( painter, canvas, rects);
334 }
335
336 static inline void qwtRevertPath( QPainterPath& path )
337 {
338 if ( path.elementCount() == 4 )
339 {
340 QPainterPath::Element el0 = path.elementAt(0);
341 QPainterPath::Element el3 = path.elementAt(3);
342
343 path.setElementPositionAt( 0, el3.x, el3.y );
344 path.setElementPositionAt( 3, el0.x, el0.y );
345 }
346 }
347
348 static QPainterPath qwtCombinePathList( const QRectF& rect,
349 const QList< QPainterPath >& pathList )
350 {
351 if ( pathList.isEmpty() )
352 return QPainterPath();
353
354 QPainterPath ordered[8]; // starting top left
355
356 for ( int i = 0; i < pathList.size(); i++ )
357 {
358 int index = -1;
359 QPainterPath subPath = pathList[i];
360
361 const QRectF br = pathList[i].controlPointRect();
362 if ( br.center().x() < rect.center().x() )
363 {
364 if ( br.center().y() < rect.center().y() )
365 {
366 if ( qAbs( br.top() - rect.top() ) <
367 qAbs( br.left() - rect.left() ) )
368 {
369 index = 1;
370 }
371 else
372 {
373 index = 0;
374 }
375 }
376 else
377 {
378 if ( qAbs( br.bottom() - rect.bottom() ) <
379 qAbs( br.left() - rect.left() ) )
380 {
381 index = 6;
382 }
383 else
384 {
385 index = 7;
386 }
387 }
388
389 if ( subPath.currentPosition().y() > br.center().y() )
390 qwtRevertPath( subPath );
391 }
392 else
393 {
394 if ( br.center().y() < rect.center().y() )
395 {
396 if ( qAbs( br.top() - rect.top() ) <
397 qAbs( br.right() - rect.right() ) )
398 {
399 index = 2;
400 }
401 else
402 {
403 index = 3;
404 }
405 }
406 else
407 {
408 if ( qAbs( br.bottom() - rect.bottom() ) <
409 qAbs( br.right() - rect.right() ) )
410 {
411 index = 5;
412 }
413 else
414 {
415 index = 4;
416 }
417 }
418 if ( subPath.currentPosition().y() < br.center().y() )
419 qwtRevertPath( subPath );
420 }
421 ordered[index] = subPath;
422 }
423
424 for ( int i = 0; i < 4; i++ )
425 {
426 if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() )
427 {
428 // we don't accept incomplete rounded borders
429 return QPainterPath();
430 }
431 }
432
433
434 const QPolygonF corners( rect );
435
436 QPainterPath path;
437 //path.moveTo( rect.topLeft() );
438
439 for ( int i = 0; i < 4; i++ )
440 {
441 if ( ordered[2 * i].isEmpty() )
442 {
443 path.lineTo( corners[i] );
444 }
445 else
446 {
447 path.connectPath( ordered[2 * i] );
448 path.connectPath( ordered[2 * i + 1] );
449 }
450 }
451
452 path.closeSubpath();
453
454 #if 0
455 return path.simplified();
456 #else
457 return path;
458 #endif
459 }
460
461 static QPainterPath qwtBorderPath( const QWidget* canvas, const QRect& rect )
462 {
463 if ( canvas->testAttribute(Qt::WA_StyledBackground ) )
464 {
465 QwtStyleSheetRecorder recorder( rect.size() );
466
467 QPainter painter( &recorder );
468
469 QStyleOption opt;
470 opt.initFrom( canvas );
471 opt.rect = rect;
472 canvas->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, canvas );
473
474 painter.end();
475
476 if ( !recorder.background.path.isEmpty() )
477 return recorder.background.path;
478
479 if ( !recorder.border.rectList.isEmpty() )
480 return qwtCombinePathList( rect, recorder.border.pathList );
481 }
482 else
483 {
484 const double borderRadius = canvas->property( "borderRadius" ).toDouble();
485
486 if ( borderRadius > 0.0 )
487 {
488 double fw2 = canvas->property( "frameWidth" ).toInt() * 0.5;
489 QRectF r = QRectF(rect).adjusted( fw2, fw2, -fw2, -fw2 );
490
491 QPainterPath path;
492 path.addRoundedRect( r, borderRadius, borderRadius );
493 return path;
494 }
495 }
496
497 return QPainterPath();
498 }
499
500 class QwtPlotAbstractCanvas::PrivateData
501 {
502 public:
503 PrivateData()
504 : focusIndicator( NoFocusIndicator )
505 , borderRadius( 0 )
506 {
507 styleSheet.hasBorder = false;
508 }
509
510 FocusIndicator focusIndicator;
511 double borderRadius;
512
513 struct StyleSheet
514 {
515 bool hasBorder;
516 QPainterPath borderPath;
517 QVector< QRectF > cornerRects;
518
519 struct StyleSheetBackground
520 {
521 QBrush brush;
522 QPointF origin;
523 } background;
524
525 } styleSheet;
526
527 QWidget* canvasWidget;
528 };
529
534 QwtPlotAbstractCanvas::QwtPlotAbstractCanvas( QWidget* canvasWidget )
535 {
536 m_data = new PrivateData;
537 m_data->canvasWidget = canvasWidget;
538
539 #ifndef QT_NO_CURSOR
540 canvasWidget->setCursor( Qt::CrossCursor );
541 #endif
542 canvasWidget->setAutoFillBackground( true );
543 }
544
546 QwtPlotAbstractCanvas::~QwtPlotAbstractCanvas()
547 {
548 delete m_data;
549 }
550
552 QwtPlot* QwtPlotAbstractCanvas::plot()
553 {
554 return qobject_cast< QwtPlot* >( m_data->canvasWidget->parent() );
555 }
556
558 const QwtPlot* QwtPlotAbstractCanvas::plot() const
559 {
560 return qobject_cast< const QwtPlot* >( m_data->canvasWidget->parent() );
561 }
562
568 void QwtPlotAbstractCanvas::setFocusIndicator( FocusIndicator focusIndicator )
569 {
570 m_data->focusIndicator = focusIndicator;
571 }
572
578 QwtPlotAbstractCanvas::FocusIndicator QwtPlotAbstractCanvas::focusIndicator() const
579 {
580 return m_data->focusIndicator;
581 }
582
587 void QwtPlotAbstractCanvas::drawFocusIndicator( QPainter* painter )
588 {
589 const int margin = 1;
590
591 QRect focusRect = m_data->canvasWidget->contentsRect();
592 focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
593 focusRect.width() - 2 * margin, focusRect.height() - 2 * margin );
594
595 QwtPainter::drawFocusRect( painter, m_data->canvasWidget, focusRect );
596 }
597
604 void QwtPlotAbstractCanvas::setBorderRadius( double radius )
605 {
606 m_data->borderRadius = qwtMaxF( 0.0, radius );
607 }
608
613 double QwtPlotAbstractCanvas::borderRadius() const
614 {
615 return m_data->borderRadius;
616 }
617
619 QPainterPath QwtPlotAbstractCanvas::canvasBorderPath( const QRect& rect ) const
620 {
621 return qwtBorderPath( canvasWidget(), rect );
622 }
623
628 void QwtPlotAbstractCanvas::drawBorder( QPainter* painter )
629 {
630 const QWidget* w = canvasWidget();
631
632 if ( m_data->borderRadius > 0 )
633 {
634 const int frameWidth = w->property( "frameWidth" ).toInt();
635 if ( frameWidth > 0 )
636 {
637 const int frameShape = w->property( "frameShape" ).toInt();
638 const int frameShadow = w->property( "frameShadow" ).toInt();
639
640 const QRectF frameRect = w->property( "frameRect" ).toRect();
641
642 QwtPainter::drawRoundedFrame( painter, frameRect,
643 m_data->borderRadius, m_data->borderRadius,
644 w->palette(), frameWidth, frameShape | frameShadow );
645 }
646 }
647 else
648 {
649 const int frameShape = w->property( "frameShape" ).toInt();
650 const int frameShadow = w->property( "frameShadow" ).toInt();
651
652 #if QT_VERSION < 0x050000
653 QStyleOptionFrameV3 opt;
654 #else
655 QStyleOptionFrame opt;
656 #endif
657 opt.initFrom( w );
658
659 opt.frameShape = QFrame::Shape( int( opt.frameShape ) | frameShape );
660
661 switch (frameShape)
662 {
663 case QFrame::Box:
664 case QFrame::HLine:
665 case QFrame::VLine:
666 case QFrame::StyledPanel:
667 case QFrame::Panel:
668 {
669 opt.lineWidth = w->property( "lineWidth" ).toInt();
670 opt.midLineWidth = w->property( "midLineWidth" ).toInt();
671 break;
672 }
673 default:
674 {
675 opt.lineWidth = w->property( "frameWidth" ).toInt();
676 break;
677 }
678 }
679
680 if ( frameShadow == QFrame::Sunken )
681 opt.state |= QStyle::State_Sunken;
682 else if ( frameShadow == QFrame::Raised )
683 opt.state |= QStyle::State_Raised;
684
685 w->style()->drawControl(QStyle::CE_ShapedFrame, &opt, painter, w );
686 }
687 }
688
690 void QwtPlotAbstractCanvas::drawBackground( QPainter* painter )
691 {
692 qwtDrawBackground( painter, canvasWidget() );
693 }
694
696 void QwtPlotAbstractCanvas::fillBackground( QPainter* painter )
697 {
698 qwtFillBackground( painter, canvasWidget() );
699 }
700
702 void QwtPlotAbstractCanvas::drawUnstyled( QPainter* painter )
703 {
704 fillBackground( painter );
705
706 QWidget* w = canvasWidget();
707
708 if ( w->autoFillBackground() )
709 {
710 const QRect canvasRect = w->rect();
711
712 painter->save();
713
714 painter->setPen( Qt::NoPen );
715 painter->setBrush( w->palette().brush( w->backgroundRole() ) );
716
717 const QRect frameRect = w->property( "frameRect" ).toRect();
718 if ( borderRadius() > 0.0 && ( canvasRect == frameRect ) )
719 {
720 const int frameWidth = w->property( "frameWidth" ).toInt();
721 if ( frameWidth > 0 )
722 {
723 painter->setClipPath( canvasBorderPath( canvasRect ) );
724 painter->drawRect( canvasRect );
725 }
726 else
727 {
728 painter->setRenderHint( QPainter::Antialiasing, true );
729 painter->drawPath( canvasBorderPath( canvasRect ) );
730 }
731 }
732 else
733 {
734 painter->drawRect( canvasRect );
735 }
736
737 painter->restore();
738 }
739
740 drawCanvas( painter );
741 }
742
744 void QwtPlotAbstractCanvas::drawStyled( QPainter* painter, bool hackStyledBackground )
745 {
746 fillBackground( painter );
747
748 if ( hackStyledBackground )
749 {
750 // Antialiasing rounded borders is done by
751 // inserting pixels with colors between the
752 // border color and the color on the canvas,
753 // When the border is painted before the plot items
754 // these colors are interpolated for the canvas
755 // and the plot items need to be clipped excluding
756 // the antialiased pixels. In situations, where
757 // the plot items fill the area at the rounded
758 // borders this is noticeable.
759 // The only way to avoid these annoying "artefacts"
760 // is to paint the border on top of the plot items.
761
762 if ( !m_data->styleSheet.hasBorder ||
763 m_data->styleSheet.borderPath.isEmpty() )
764 {
765 // We have no border with at least one rounded corner
766 hackStyledBackground = false;
767 }
768 }
769
770 QWidget* w = canvasWidget();
771
772 if ( hackStyledBackground )
773 {
774 painter->save();
775
776 // paint background without border
777 painter->setPen( Qt::NoPen );
778 painter->setBrush( m_data->styleSheet.background.brush );
779 painter->setBrushOrigin( m_data->styleSheet.background.origin );
780 painter->setClipPath( m_data->styleSheet.borderPath );
781 painter->drawRect( w->contentsRect() );
782
783 painter->restore();
784
785 drawCanvas( painter );
786
787 // Now paint the border on top
788 QStyleOptionFrame opt;
789 opt.initFrom( w );
790 w->style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, w);
791 }
792 else
793 {
794 QStyleOption opt;
795 opt.initFrom( w );
796 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w );
797
798 drawCanvas( painter );
799 }
800 }
801
803 void QwtPlotAbstractCanvas::drawCanvas( QPainter* painter )
804 {
805 QWidget* w = canvasWidget();
806
807 painter->save();
808
809 if ( !m_data->styleSheet.borderPath.isEmpty() )
810 {
811 painter->setClipPath(
812 m_data->styleSheet.borderPath, Qt::IntersectClip );
813 }
814 else
815 {
816 if ( borderRadius() > 0.0 )
817 {
818 const QRect frameRect = w->property( "frameRect" ).toRect();
819 painter->setClipPath( canvasBorderPath( frameRect ), Qt::IntersectClip );
820 }
821 else
822 {
823 painter->setClipRect( w->contentsRect(), Qt::IntersectClip );
824 }
825 }
826
827 QwtPlot* plot = qobject_cast< QwtPlot* >( w->parent() );
828 if ( plot )
829 plot->drawCanvas( painter );
830
831 painter->restore();
832 }
833
835 void QwtPlotAbstractCanvas::updateStyleSheetInfo()
836 {
837 QWidget* w = canvasWidget();
838
839 if ( !w->testAttribute( Qt::WA_StyledBackground ) )
840 return;
841
842 QwtStyleSheetRecorder recorder( w->size() );
843
844 QPainter painter( &recorder );
845
846 QStyleOption opt;
847 opt.initFrom(w);
848 w->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, w);
849
850 painter.end();
851
852 m_data->styleSheet.hasBorder = !recorder.border.rectList.isEmpty();
853 m_data->styleSheet.cornerRects = recorder.clipRects;
854
855 if ( recorder.background.path.isEmpty() )
856 {
857 if ( !recorder.border.rectList.isEmpty() )
858 {
859 m_data->styleSheet.borderPath =
860 qwtCombinePathList( w->rect(), recorder.border.pathList );
861 }
862 }
863 else
864 {
865 m_data->styleSheet.borderPath = recorder.background.path;
866 m_data->styleSheet.background.brush = recorder.background.brush;
867 m_data->styleSheet.background.origin = recorder.background.origin;
868 }
869 }
870
872 QWidget* QwtPlotAbstractCanvas::canvasWidget()
873 {
874 return m_data->canvasWidget;
875 }
876
878 const QWidget* QwtPlotAbstractCanvas::canvasWidget() const
879 {
880 return m_data->canvasWidget;
881 }
882
883 class QwtPlotAbstractGLCanvas::PrivateData
884 {
885 public:
886 PrivateData():
887 frameStyle( QFrame::Panel | QFrame::Sunken),
888 lineWidth( 2 ),
889 midLineWidth( 0 )
890 {
891 }
892
893 QwtPlotAbstractGLCanvas::PaintAttributes paintAttributes;
894
895 int frameStyle;
896 int lineWidth;
897 int midLineWidth;
898 };
899
904 QwtPlotAbstractGLCanvas::QwtPlotAbstractGLCanvas( QWidget* canvasWidget ):
905 QwtPlotAbstractCanvas( canvasWidget )
906 {
907 m_data = new PrivateData;
908
909 qwtUpdateContentsRect( frameWidth(), canvasWidget );
910 m_data->paintAttributes = QwtPlotAbstractGLCanvas::BackingStore;
911 }
912
914 QwtPlotAbstractGLCanvas::~QwtPlotAbstractGLCanvas()
915 {
916 delete m_data;
917 }
918
927 void QwtPlotAbstractGLCanvas::setPaintAttribute( PaintAttribute attribute, bool on )
928 {
929 if ( bool( m_data->paintAttributes & attribute ) == on )
930 return;
931
932 if ( on )
933 {
934 m_data->paintAttributes |= attribute;
935 }
936 else
937 {
938 m_data->paintAttributes &= ~attribute;
939
940 if ( attribute == BackingStore )
941 clearBackingStore();
942 }
943 }
944
952 bool QwtPlotAbstractGLCanvas::testPaintAttribute( PaintAttribute attribute ) const
953 {
954 return m_data->paintAttributes & attribute;
955 }
956
965 void QwtPlotAbstractGLCanvas::setFrameStyle( int style )
966 {
967 if ( style != m_data->frameStyle )
968 {
969 m_data->frameStyle = style;
970 qwtUpdateContentsRect( frameWidth(), canvasWidget() );
971
972 canvasWidget()->update();
973 }
974 }
975
980 int QwtPlotAbstractGLCanvas::frameStyle() const
981 {
982 return m_data->frameStyle;
983 }
984
991 void QwtPlotAbstractGLCanvas::setFrameShadow( QFrame::Shadow shadow )
992 {
993 setFrameStyle( ( m_data->frameStyle & QFrame::Shape_Mask ) | shadow );
994 }
995
1000 QFrame::Shadow QwtPlotAbstractGLCanvas::frameShadow() const
1001 {
1002 return (QFrame::Shadow) ( m_data->frameStyle & QFrame::Shadow_Mask );
1003 }
1004
1011 void QwtPlotAbstractGLCanvas::setFrameShape( QFrame::Shape shape )
1012 {
1013 setFrameStyle( ( m_data->frameStyle & QFrame::Shadow_Mask ) | shape );
1014 }
1015
1020 QFrame::Shape QwtPlotAbstractGLCanvas::frameShape() const
1021 {
1022 return (QFrame::Shape) ( m_data->frameStyle & QFrame::Shape_Mask );
1023 }
1024
1033 void QwtPlotAbstractGLCanvas::setLineWidth( int width )
1034 {
1035 width = qMax( width, 0 );
1036 if ( width != m_data->lineWidth )
1037 {
1038 m_data->lineWidth = qMax( width, 0 );
1039 qwtUpdateContentsRect( frameWidth(), canvasWidget() );
1040 canvasWidget()->update();
1041 }
1042 }
1043
1048 int QwtPlotAbstractGLCanvas::lineWidth() const
1049 {
1050 return m_data->lineWidth;
1051 }
1052
1061 void QwtPlotAbstractGLCanvas::setMidLineWidth( int width )
1062 {
1063 width = qMax( width, 0 );
1064 if ( width != m_data->midLineWidth )
1065 {
1066 m_data->midLineWidth = width;
1067 qwtUpdateContentsRect( frameWidth(), canvasWidget() );
1068 canvasWidget()->update();
1069 }
1070 }
1071
1076 int QwtPlotAbstractGLCanvas::midLineWidth() const
1077 {
1078 return m_data->midLineWidth;
1079 }
1080
1084 int QwtPlotAbstractGLCanvas::frameWidth() const
1085 {
1086 return ( frameStyle() != QFrame::NoFrame ) ? m_data->lineWidth : 0;
1087 }
1088
1093 void QwtPlotAbstractGLCanvas::replot()
1094 {
1095 invalidateBackingStore();
1096
1097 QWidget* w = canvasWidget();
1098 if ( testPaintAttribute( QwtPlotAbstractGLCanvas::ImmediatePaint ) )
1099 w->repaint( w->contentsRect() );
1100 else
1101 w->update( w->contentsRect() );
1102 }
1103
1105 QRect QwtPlotAbstractGLCanvas::frameRect() const
1106 {
1107 const int fw = frameWidth();
1108 return canvasWidget()->contentsRect().adjusted( -fw, -fw, fw, fw );
1109 }
1110
1112 void QwtPlotAbstractGLCanvas::draw( QPainter* painter )
1113 {
1114 #if FIX_GL_TRANSLATION
1115 if ( painter->paintEngine()->type() == QPaintEngine::OpenGL2 )
1116 {
1117 // work around a translation bug of QPaintEngine::OpenGL2
1118 painter->translate( 1, 1 );
1119 }
1120 #endif
1121
1122 if ( canvasWidget()->testAttribute( Qt::WA_StyledBackground ) )
1123 drawStyled( painter, true );
1124 else
1125 drawUnstyled( painter );
1126
1127 if ( frameWidth() > 0 )
1128 drawBorder( painter );
1129 }
QList
Definition: qwt_abstract_legend.h:17
QVector< QRectF >
QwtNullPaintDevice
A null paint device doing nothing.
Definition: qwt_null_paintdevice.h:33
QwtNullPaintDevice::drawPath
virtual void drawPath(const QPainterPath &)
See QPaintEngine::drawPath()
Definition: qwt_null_paintdevice.cpp:518
QwtNullPaintDevice::drawRects
virtual void drawRects(const QRect *, int)
See QPaintEngine::drawRects()
Definition: qwt_null_paintdevice.cpp:474
QwtNullPaintDevice::updateState
virtual void updateState(const QPaintEngineState &)
See QPaintEngine::updateState()
Definition: qwt_null_paintdevice.cpp:598
QwtNullPaintDevice::sizeMetrics
virtual QSize sizeMetrics() const =0
QwtPainter::drawRoundedFrame
static void drawRoundedFrame(QPainter *, const QRectF &, qreal xRadius, qreal yRadius, const QPalette &, int lineWidth, int frameStyle)
Definition: qwt_painter.cpp:1065
QwtPainter::drawFocusRect
static void drawFocusRect(QPainter *, const QWidget *)
Draw a focus rectangle on a widget using its style.
Definition: qwt_painter.cpp:815
QwtPainter::fillPixmap
static void fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())
Definition: qwt_painter.cpp:1311
QwtPlotAbstractCanvas
Base class for all type of plot canvases.
Definition: qwt_plot_abstract_canvas.h:22
QwtPlotAbstractCanvas::fillBackground
void fillBackground(QPainter *)
Helper function for the derived plot canvas.
Definition: qwt_plot_abstract_canvas.cpp:696
QwtPlotAbstractCanvas::plot
QwtPlot * plot()
Return parent plot widget.
Definition: qwt_plot_abstract_canvas.cpp:552
QwtPlotAbstractCanvas::drawBackground
virtual void drawBackground(QPainter *)
Helper function for the derived plot canvas.
Definition: qwt_plot_abstract_canvas.cpp:690
QwtPlotAbstractCanvas::drawUnstyled
void drawUnstyled(QPainter *)
Helper function for the derived plot canvas.
Definition: qwt_plot_abstract_canvas.cpp:702
QwtPlotAbstractCanvas::setFocusIndicator
void setFocusIndicator(FocusIndicator)
Definition: qwt_plot_abstract_canvas.cpp:568
QwtPlotAbstractCanvas::~QwtPlotAbstractCanvas
virtual ~QwtPlotAbstractCanvas()
Destructor.
Definition: qwt_plot_abstract_canvas.cpp:546
QwtPlotAbstractCanvas::focusIndicator
FocusIndicator focusIndicator() const
Definition: qwt_plot_abstract_canvas.cpp:578
QwtPlotAbstractCanvas::updateStyleSheetInfo
void updateStyleSheetInfo()
Update the cached information about the current style sheet.
Definition: qwt_plot_abstract_canvas.cpp:835
QwtPlotAbstractCanvas::borderRadius
double borderRadius() const
Definition: qwt_plot_abstract_canvas.cpp:613
QwtPlotAbstractCanvas::canvasBorderPath
QPainterPath canvasBorderPath(const QRect &rect) const
Definition: qwt_plot_abstract_canvas.cpp:619
QwtPlotAbstractCanvas::drawBorder
virtual void drawBorder(QPainter *)
Definition: qwt_plot_abstract_canvas.cpp:628
QwtPlotAbstractCanvas::QwtPlotAbstractCanvas
QwtPlotAbstractCanvas(QWidget *canvasWidget)
Constructor.
Definition: qwt_plot_abstract_canvas.cpp:534
QwtPlotAbstractCanvas::drawCanvas
void drawCanvas(QPainter *)
Draw the plot to the canvas.
Definition: qwt_plot_abstract_canvas.cpp:803
QwtPlotAbstractCanvas::drawStyled
void drawStyled(QPainter *, bool)
Helper function for the derived plot canvas.
Definition: qwt_plot_abstract_canvas.cpp:744
QwtPlotAbstractCanvas::canvasWidget
QWidget * canvasWidget()
Definition: qwt_plot_abstract_canvas.cpp:872
QwtPlotAbstractCanvas::drawFocusIndicator
virtual void drawFocusIndicator(QPainter *)
Definition: qwt_plot_abstract_canvas.cpp:587
QwtPlotAbstractCanvas::setBorderRadius
void setBorderRadius(double)
Definition: qwt_plot_abstract_canvas.cpp:604
QwtPlotAbstractCanvas::FocusIndicator
FocusIndicator
Focus indicator The default setting is NoFocusIndicator.
Definition: qwt_plot_abstract_canvas.h:31
QwtPlotAbstractCanvas::NoFocusIndicator
@ NoFocusIndicator
Don't paint a focus indicator.
Definition: qwt_plot_abstract_canvas.h:33
QwtPlotAbstractGLCanvas::QwtPlotAbstractGLCanvas
QwtPlotAbstractGLCanvas(QWidget *canvasWidget)
Constructor.
Definition: qwt_plot_abstract_canvas.cpp:904
QwtPlotAbstractGLCanvas::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_plot_abstract_canvas.cpp:952
QwtPlotAbstractGLCanvas::frameRect
QRect frameRect() const
Definition: qwt_plot_abstract_canvas.cpp:1105
QwtPlotAbstractGLCanvas::setLineWidth
void setLineWidth(int)
Definition: qwt_plot_abstract_canvas.cpp:1033
QwtPlotAbstractGLCanvas::setPaintAttribute
void setPaintAttribute(PaintAttribute, bool on=true)
Changing the paint attributes.
Definition: qwt_plot_abstract_canvas.cpp:927
QwtPlotAbstractGLCanvas::frameShadow
QFrame::Shadow frameShadow() const
Definition: qwt_plot_abstract_canvas.cpp:1000
QwtPlotAbstractGLCanvas::frameStyle
int frameStyle() const
Definition: qwt_plot_abstract_canvas.cpp:980
QwtPlotAbstractGLCanvas::setMidLineWidth
void setMidLineWidth(int)
Definition: qwt_plot_abstract_canvas.cpp:1061
QwtPlotAbstractGLCanvas::midLineWidth
int midLineWidth() const
Definition: qwt_plot_abstract_canvas.cpp:1076
QwtPlotAbstractGLCanvas::frameWidth
int frameWidth() const
Definition: qwt_plot_abstract_canvas.cpp:1084
QwtPlotAbstractGLCanvas::invalidateBackingStore
virtual void invalidateBackingStore()=0
Invalidate the internal backing store.
QwtPlotAbstractGLCanvas::PaintAttribute
PaintAttribute
Paint attributes.
Definition: qwt_plot_abstract_canvas.h:98
QwtPlotAbstractGLCanvas::BackingStore
@ BackingStore
Paint double buffered reusing the content of the pixmap buffer when possible.
Definition: qwt_plot_abstract_canvas.h:110
QwtPlotAbstractGLCanvas::ImmediatePaint
@ ImmediatePaint
Definition: qwt_plot_abstract_canvas.h:118
QwtPlotAbstractGLCanvas::setFrameShape
void setFrameShape(QFrame::Shape)
Definition: qwt_plot_abstract_canvas.cpp:1011
QwtPlotAbstractGLCanvas::lineWidth
int lineWidth() const
Definition: qwt_plot_abstract_canvas.cpp:1048
QwtPlotAbstractGLCanvas::replot
void replot()
Definition: qwt_plot_abstract_canvas.cpp:1093
QwtPlotAbstractGLCanvas::frameShape
QFrame::Shape frameShape() const
Definition: qwt_plot_abstract_canvas.cpp:1020
QwtPlotAbstractGLCanvas::~QwtPlotAbstractGLCanvas
virtual ~QwtPlotAbstractGLCanvas()
Destructor.
Definition: qwt_plot_abstract_canvas.cpp:914
QwtPlotAbstractGLCanvas::setFrameShadow
void setFrameShadow(QFrame::Shadow)
Definition: qwt_plot_abstract_canvas.cpp:991
QwtPlotAbstractGLCanvas::PaintAttributes
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
Definition: qwt_plot_abstract_canvas.h:122
QwtPlotAbstractGLCanvas::setFrameStyle
void setFrameStyle(int style)
Definition: qwt_plot_abstract_canvas.cpp:965
QwtPlotAbstractGLCanvas::draw
void draw(QPainter *)
Helper function for the derived plot canvas.
Definition: qwt_plot_abstract_canvas.cpp:1112
QwtPlot
A 2-D plotting widget.
Definition: qwt_plot.h:79
QwtPlot::drawCanvas
virtual void drawCanvas(QPainter *)
Definition: qwt_plot.cpp:742