qwt_plot_abstract_canvas.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 
11 #include "qwt_plot.h"
12 #include "qwt_painter.h"
13 #include <qpainter.h>
14 #include <qdrawutil.h>
15 #include <qstyle.h>
16 #include <qstyleoption.h>
17 
19 {
20 public:
21  explicit QwtStyleSheetRecorder( const QSize &size ):
22  d_size( size )
23  {
24  }
25 
26  virtual void updateState( const QPaintEngineState &state )
27  {
28  if ( state.state() & QPaintEngine::DirtyPen )
29  {
30  d_pen = state.pen();
31  }
32  if ( state.state() & QPaintEngine::DirtyBrush )
33  {
34  d_brush = state.brush();
35  }
36  if ( state.state() & QPaintEngine::DirtyBrushOrigin )
37  {
38  d_origin = state.brushOrigin();
39  }
40  }
41 
42  virtual void drawRects(const QRectF *rects, int count )
43  {
44  for ( int i = 0; i < count; i++ )
45  border.rectList += rects[i];
46  }
47 
48  virtual void drawRects(const QRect *rects, int count )
49  {
50  for ( int i = 0; i < count; i++ )
51  border.rectList += rects[i];
52  }
53 
54  virtual void drawPath( const QPainterPath &path )
55  {
56  const QRectF rect( QPointF( 0.0, 0.0 ), d_size );
57  if ( path.controlPointRect().contains( rect.center() ) )
58  {
59  setCornerRects( path );
60  alignCornerRects( rect );
61 
62  background.path = path;
65  }
66  else
67  {
68  border.pathList += path;
69  }
70  }
71 
72  void setCornerRects( const QPainterPath &path )
73  {
74  QPointF pos( 0.0, 0.0 );
75 
76  for ( int i = 0; i < path.elementCount(); i++ )
77  {
78  QPainterPath::Element el = path.elementAt(i);
79  switch( el.type )
80  {
81  case QPainterPath::MoveToElement:
82  case QPainterPath::LineToElement:
83  {
84  pos.setX( el.x );
85  pos.setY( el.y );
86  break;
87  }
88  case QPainterPath::CurveToElement:
89  {
90  QRectF r( pos, QPointF( el.x, el.y ) );
91  clipRects += r.normalized();
92 
93  pos.setX( el.x );
94  pos.setY( el.y );
95 
96  break;
97  }
98  case QPainterPath::CurveToDataElement:
99  {
100  if ( clipRects.size() > 0 )
101  {
102  QRectF r = clipRects.last();
103  r.setCoords(
104  qMin( r.left(), el.x ),
105  qMin( r.top(), el.y ),
106  qMax( r.right(), el.x ),
107  qMax( r.bottom(), el.y )
108  );
109  clipRects.last() = r.normalized();
110  }
111  break;
112  }
113  }
114  }
115  }
116 
117 protected:
118  virtual QSize sizeMetrics() const
119  {
120  return d_size;
121  }
122 
123 private:
124  void alignCornerRects( const QRectF &rect )
125  {
126  for ( int i = 0; i < clipRects.size(); i++ )
127  {
128  QRectF &r = clipRects[i];
129  if ( r.center().x() < rect.center().x() )
130  r.setLeft( rect.left() );
131  else
132  r.setRight( rect.right() );
133 
134  if ( r.center().y() < rect.center().y() )
135  r.setTop( rect.top() );
136  else
137  r.setBottom( rect.bottom() );
138  }
139  }
140 
141 
142 public:
143  QVector<QRectF> clipRects;
144 
145  struct Border
146  {
147  QList<QPainterPath> pathList;
148  QList<QRectF> rectList;
149  QRegion clipRegion;
150  } border;
151 
152  struct Background
153  {
154  QPainterPath path;
155  QBrush brush;
156  QPointF origin;
157  } background;
158 
159 private:
160  const QSize d_size;
161 
162  QPen d_pen;
163  QBrush d_brush;
164  QPointF d_origin;
165 };
166 
167 static void qwtUpdateContentsRect( int fw, QWidget *canvas )
168 {
169  canvas->setContentsMargins( fw, fw, fw, fw );
170 }
171 
172 static void qwtDrawBackground( QPainter *painter, QWidget *canvas )
173 {
174  painter->save();
175 
176  QPainterPath borderClip;
177 
178  ( void )QMetaObject::invokeMethod(
179  canvas, "borderPath", Qt::DirectConnection,
180  Q_RETURN_ARG( QPainterPath, borderClip ), Q_ARG( QRect, canvas->rect() ) );
181 
182  if ( !borderClip.isEmpty() )
183  painter->setClipPath( borderClip, Qt::IntersectClip );
184 
185  const QBrush &brush =
186  canvas->palette().brush( canvas->backgroundRole() );
187 
188  if ( brush.style() == Qt::TexturePattern )
189  {
190  QPixmap pm( canvas->size() );
191  QwtPainter::fillPixmap( canvas, pm );
192  painter->drawPixmap( 0, 0, pm );
193  }
194  else if ( brush.gradient() )
195  {
196  QVector<QRect> rects;
197 
198  if ( brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode )
199  {
200  rects += canvas->rect();
201  }
202  else
203  {
204  rects = painter->clipRegion().rects();
205  }
206 
207 #if 1
208  bool useRaster = false;
209 
210  if ( painter->paintEngine()->type() == QPaintEngine::X11 )
211  {
212  // Qt 4.7.1: gradients on X11 are broken ( subrects +
213  // QGradient::StretchToDeviceMode ) and horrible slow.
214  // As workaround we have to use the raster paintengine.
215  // Even if the QImage -> QPixmap translation is slow
216  // it is three times faster, than using X11 directly
217 
218  useRaster = true;
219  }
220 #endif
221  if ( useRaster )
222  {
223  QImage::Format format = QImage::Format_RGB32;
224 
225  const QGradientStops stops = brush.gradient()->stops();
226  for ( int i = 0; i < stops.size(); i++ )
227  {
228  if ( stops[i].second.alpha() != 255 )
229  {
230  // don't use Format_ARGB32_Premultiplied. It's
231  // recommended by the Qt docs, but QPainter::drawImage()
232  // is horrible slow on X11.
233 
234  format = QImage::Format_ARGB32;
235  break;
236  }
237  }
238 
239  QImage image( canvas->size(), format );
240 
241  QPainter p( &image );
242  p.setPen( Qt::NoPen );
243  p.setBrush( brush );
244 
245  p.drawRects( rects );
246 
247  p.end();
248 
249  painter->drawImage( 0, 0, image );
250  }
251  else
252  {
253  painter->setPen( Qt::NoPen );
254  painter->setBrush( brush );
255 
256  painter->drawRects( rects );
257  }
258  }
259  else
260  {
261  painter->setPen( Qt::NoPen );
262  painter->setBrush( brush );
263 
264  painter->drawRects( painter->clipRegion().rects() );
265 
266  }
267 
268  painter->restore();
269 }
270 
271 static inline void qwtDrawStyledBackground(
272  QWidget *w, QPainter *painter )
273 {
274  QStyleOption opt;
275  opt.initFrom(w);
276  w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w);
277 }
278 
279 static QWidget *qwtBackgroundWidget( QWidget *w )
280 {
281  if ( w->parentWidget() == NULL )
282  return w;
283 
284  if ( w->autoFillBackground() )
285  {
286  const QBrush brush = w->palette().brush( w->backgroundRole() );
287  if ( brush.color().alpha() > 0 )
288  return w;
289  }
290 
291  if ( w->testAttribute( Qt::WA_StyledBackground ) )
292  {
293  QImage image( 1, 1, QImage::Format_ARGB32 );
294  image.fill( Qt::transparent );
295 
296  QPainter painter( &image );
297  painter.translate( -w->rect().center() );
298  qwtDrawStyledBackground( w, &painter );
299  painter.end();
300 
301  if ( qAlpha( image.pixel( 0, 0 ) ) != 0 )
302  return w;
303  }
304 
305  return qwtBackgroundWidget( w->parentWidget() );
306 }
307 
308 static void qwtFillBackground( QPainter *painter,
309  QWidget *widget, const QVector<QRectF> &fillRects )
310 {
311  if ( fillRects.isEmpty() )
312  return;
313 
314  QRegion clipRegion;
315  if ( painter->hasClipping() )
316  clipRegion = painter->transform().map( painter->clipRegion() );
317  else
318  clipRegion = widget->contentsRect();
319 
320  // Try to find out which widget fills
321  // the unfilled areas of the styled background
322 
323  QWidget *bgWidget = qwtBackgroundWidget( widget->parentWidget() );
324 
325  for ( int i = 0; i < fillRects.size(); i++ )
326  {
327  const QRect rect = fillRects[i].toAlignedRect();
328  if ( clipRegion.intersects( rect ) )
329  {
330  QPixmap pm( rect.size() );
331  QwtPainter::fillPixmap( bgWidget, pm, widget->mapTo( bgWidget, rect.topLeft() ) );
332  painter->drawPixmap( rect, pm );
333  }
334  }
335 }
336 
337 static void qwtFillBackground( QPainter *painter, QWidget *canvas )
338 {
339  QVector<QRectF> rects;
340 
341  if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
342  {
343  QwtStyleSheetRecorder recorder( canvas->size() );
344 
345  QPainter p( &recorder );
346  qwtDrawStyledBackground( canvas, &p );
347  p.end();
348 
349  if ( recorder.background.brush.isOpaque() )
350  rects = recorder.clipRects;
351  else
352  rects += canvas->rect();
353  }
354  else
355  {
356  const double borderRadius = canvas->property( "borderRadius" ).toDouble();
357  if ( borderRadius > 0.0 )
358  {
359  QSizeF sz( borderRadius, borderRadius );
360 
361  const QRectF r = canvas->rect();
362  rects += QRectF( r.topLeft(), sz );
363  rects += QRectF( r.topRight() - QPointF( borderRadius, 0 ), sz );
364  rects += QRectF( r.bottomRight() - QPointF( borderRadius, borderRadius ), sz );
365  rects += QRectF( r.bottomLeft() - QPointF( 0, borderRadius ), sz );
366  }
367  }
368 
369  qwtFillBackground( painter, canvas, rects);
370 }
371 
372 static inline void qwtRevertPath( QPainterPath &path )
373 {
374  if ( path.elementCount() == 4 )
375  {
376  QPainterPath::Element el0 = path.elementAt(0);
377  QPainterPath::Element el3 = path.elementAt(3);
378 
379  path.setElementPositionAt( 0, el3.x, el3.y );
380  path.setElementPositionAt( 3, el0.x, el0.y );
381  }
382 }
383 
384 static QPainterPath qwtCombinePathList( const QRectF &rect,
385  const QList<QPainterPath> &pathList )
386 {
387  if ( pathList.isEmpty() )
388  return QPainterPath();
389 
390  QPainterPath ordered[8]; // starting top left
391 
392  for ( int i = 0; i < pathList.size(); i++ )
393  {
394  int index = -1;
395  QPainterPath subPath = pathList[i];
396 
397  const QRectF br = pathList[i].controlPointRect();
398  if ( br.center().x() < rect.center().x() )
399  {
400  if ( br.center().y() < rect.center().y() )
401  {
402  if ( qAbs( br.top() - rect.top() ) <
403  qAbs( br.left() - rect.left() ) )
404  {
405  index = 1;
406  }
407  else
408  {
409  index = 0;
410  }
411  }
412  else
413  {
414  if ( qAbs( br.bottom() - rect.bottom() ) <
415  qAbs( br.left() - rect.left() ) )
416  {
417  index = 6;
418  }
419  else
420  {
421  index = 7;
422  }
423  }
424 
425  if ( subPath.currentPosition().y() > br.center().y() )
426  qwtRevertPath( subPath );
427  }
428  else
429  {
430  if ( br.center().y() < rect.center().y() )
431  {
432  if ( qAbs( br.top() - rect.top() ) <
433  qAbs( br.right() - rect.right() ) )
434  {
435  index = 2;
436  }
437  else
438  {
439  index = 3;
440  }
441  }
442  else
443  {
444  if ( qAbs( br.bottom() - rect.bottom() ) <
445  qAbs( br.right() - rect.right() ) )
446  {
447  index = 5;
448  }
449  else
450  {
451  index = 4;
452  }
453  }
454  if ( subPath.currentPosition().y() < br.center().y() )
455  qwtRevertPath( subPath );
456  }
457  ordered[index] = subPath;
458  }
459 
460  for ( int i = 0; i < 4; i++ )
461  {
462  if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() )
463  {
464  // we don't accept incomplete rounded borders
465  return QPainterPath();
466  }
467  }
468 
469 
470  const QPolygonF corners( rect );
471 
472  QPainterPath path;
473  //path.moveTo( rect.topLeft() );
474 
475  for ( int i = 0; i < 4; i++ )
476  {
477  if ( ordered[2 * i].isEmpty() )
478  {
479  path.lineTo( corners[i] );
480  }
481  else
482  {
483  path.connectPath( ordered[2 * i] );
484  path.connectPath( ordered[2 * i + 1] );
485  }
486  }
487 
488  path.closeSubpath();
489 
490 #if 0
491  return path.simplified();
492 #else
493  return path;
494 #endif
495 }
496 
497 static QPainterPath qwtBorderPath( const QWidget *canvas, const QRect &rect )
498 {
499  if ( canvas->testAttribute(Qt::WA_StyledBackground ) )
500  {
501  QwtStyleSheetRecorder recorder( rect.size() );
502 
503  QPainter painter( &recorder );
504 
505  QStyleOption opt;
506  opt.initFrom( canvas );
507  opt.rect = rect;
508  canvas->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, canvas );
509 
510  painter.end();
511 
512  if ( !recorder.background.path.isEmpty() )
513  return recorder.background.path;
514 
515  if ( !recorder.border.rectList.isEmpty() )
516  return qwtCombinePathList( rect, recorder.border.pathList );
517  }
518  else
519  {
520  const double borderRadius = canvas->property( "borderRadius" ).toDouble();
521 
522  if ( borderRadius > 0.0 )
523  {
524  double fw2 = canvas->property( "frameWidth" ).toInt() * 0.5;
525  QRectF r = QRectF(rect).adjusted( fw2, fw2, -fw2, -fw2 );
526 
527  QPainterPath path;
528  path.addRoundedRect( r, borderRadius, borderRadius );
529  return path;
530  }
531  }
532 
533  return QPainterPath();
534 }
535 
537 {
538 public:
540  focusIndicator( NoFocusIndicator ),
541  borderRadius( 0 )
542  {
543  styleSheet.hasBorder = false;
544  }
545 
547  double borderRadius;
548 
549  struct StyleSheet
550  {
551  bool hasBorder;
552  QPainterPath borderPath;
553  QVector<QRectF> cornerRects;
554 
556  {
557  QBrush brush;
558  QPointF origin;
559  } background;
560 
561  } styleSheet;
562 
563  QWidget *canvasWidget;
564 };
565 
567 {
568  d_data = new PrivateData;
569  d_data->canvasWidget = canvasWidget;
570 
571 #ifndef QT_NO_CURSOR
572  canvasWidget->setCursor( Qt::CrossCursor );
573 #endif
574 
575  canvasWidget->setAutoFillBackground( true );
576 
577  canvasWidget->setProperty( "lineWidth", 2 );
578  canvasWidget->setProperty( "frameShadow", QFrame::Sunken );
579  canvasWidget->setProperty( "frameShape", QFrame::Panel );
580 }
581 
583 {
584  delete d_data;
585 }
586 
589 {
590  return qobject_cast<QwtPlot *>( d_data->canvasWidget->parent() );
591 }
592 
595 {
596  return qobject_cast<const QwtPlot *>( d_data->canvasWidget->parent() );
597 }
598 
605 {
606  d_data->focusIndicator = focusIndicator;
607 }
608 
615 {
616  return d_data->focusIndicator;
617 }
618 
624 {
625  const int margin = 1;
626 
627  QRect focusRect = d_data->canvasWidget->contentsRect();
628  focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
629  focusRect.width() - 2 * margin, focusRect.height() - 2 * margin );
630 
631  QwtPainter::drawFocusRect( painter, d_data->canvasWidget, focusRect );
632 }
633 
641 {
642  d_data->borderRadius = qMax( 0.0, radius );
643 }
644 
650 {
651  return d_data->borderRadius;
652 }
653 
654 QPainterPath QwtPlotAbstractCanvas::borderPath2( const QRect &rect ) const
655 {
656  return qwtBorderPath( canvasWidget(), rect );
657 }
658 
663 void QwtPlotAbstractCanvas::drawBorder( QPainter *painter )
664 {
665  const QWidget *w = canvasWidget();
666 
667  if ( d_data->borderRadius > 0 )
668  {
669  const int frameWidth = w->property( "frameWidth" ).toInt();
670  if ( frameWidth > 0 )
671  {
672  const int frameShape = w->property( "frameShape" ).toInt();
673  const int frameShadow = w->property( "frameShadow" ).toInt();
674 
675  const QRectF frameRect = w->property( "frameRect" ).toRect();
676 
677  QwtPainter::drawRoundedFrame( painter, frameRect,
678  d_data->borderRadius, d_data->borderRadius,
679  w->palette(), frameWidth, frameShape | frameShadow );
680  }
681  }
682  else
683  {
684 #if QT_VERSION >= 0x040500
685  const int frameShape = w->property( "frameShape" ).toInt();
686  const int frameShadow = w->property( "frameShadow" ).toInt();
687 
688 #if QT_VERSION < 0x050000
689  QStyleOptionFrameV3 opt;
690 #else
691  QStyleOptionFrame opt;
692 #endif
693  opt.init( w );
694 
695  opt.frameShape = QFrame::Shape( int( opt.frameShape ) | frameShape );
696 
697  switch (frameShape)
698  {
699  case QFrame::Box:
700  case QFrame::HLine:
701  case QFrame::VLine:
702  case QFrame::StyledPanel:
703  case QFrame::Panel:
704  {
705  opt.lineWidth = w->property( "lineWidth" ).toInt();
706  opt.midLineWidth = w->property( "midLineWidth" ).toInt();
707  break;
708  }
709  default:
710  {
711  opt.lineWidth = w->property( "frameWidth" ).toInt();
712  break;
713  }
714  }
715 
716  if ( frameShadow == QFrame::Sunken )
717  opt.state |= QStyle::State_Sunken;
718  else if ( frameShadow == QFrame::Raised )
719  opt.state |= QStyle::State_Raised;
720 
721  w->style()->drawControl(QStyle::CE_ShapedFrame, &opt, painter, w );
722 #else
723  // TODO: do we really need Qt 4.4 ?
724 #endif
725  }
726 }
727 
728 void QwtPlotAbstractCanvas::drawBackground( QPainter *painter )
729 {
730  qwtDrawBackground( painter, canvasWidget() );
731 }
732 
733 void QwtPlotAbstractCanvas::fillBackground( QPainter *painter )
734 {
735  qwtFillBackground( painter, canvasWidget() );
736 }
737 
738 void QwtPlotAbstractCanvas::drawUnstyled( QPainter *painter )
739 {
740  fillBackground( painter );
741 
742  QWidget *w = canvasWidget();
743 
744  if ( w->autoFillBackground() )
745  {
746  const QRect canvasRect = w->rect();
747 
748  painter->save();
749 
750  painter->setPen( Qt::NoPen );
751  painter->setBrush( w->palette().brush( w->backgroundRole() ) );
752 
753  const QRect frameRect = w->property( "frameRect" ).toRect();
754  if ( borderRadius() > 0.0 && ( canvasRect == frameRect ) )
755  {
756  const int frameWidth = w->property( "frameWidth" ).toInt();
757  if ( frameWidth > 0 )
758  {
759  painter->setClipPath( borderPath2( canvasRect ) );
760  painter->drawRect( canvasRect );
761  }
762  else
763  {
764  painter->setRenderHint( QPainter::Antialiasing, true );
765  painter->drawPath( borderPath2( canvasRect ) );
766  }
767  }
768  else
769  {
770  painter->drawRect( canvasRect );
771  }
772 
773  painter->restore();
774  }
775 
776  drawCanvas( painter );
777 }
778 
779 void QwtPlotAbstractCanvas::drawStyled( QPainter *painter, bool hackStyledBackground )
780 {
781  fillBackground( painter );
782 
783  if ( hackStyledBackground )
784  {
785  // Antialiasing rounded borders is done by
786  // inserting pixels with colors between the
787  // border color and the color on the canvas,
788  // When the border is painted before the plot items
789  // these colors are interpolated for the canvas
790  // and the plot items need to be clipped excluding
791  // the anialiased pixels. In situations, where
792  // the plot items fill the area at the rounded
793  // borders this is noticeable.
794  // The only way to avoid these annoying "artefacts"
795  // is to paint the border on top of the plot items.
796 
797  if ( !d_data->styleSheet.hasBorder ||
798  d_data->styleSheet.borderPath.isEmpty() )
799  {
800  // We have no border with at least one rounded corner
801  hackStyledBackground = false;
802  }
803  }
804 
805  QWidget *w = canvasWidget();
806 
807  if ( hackStyledBackground )
808  {
809  painter->save();
810 
811  // paint background without border
812  painter->setPen( Qt::NoPen );
813  painter->setBrush( d_data->styleSheet.background.brush );
814  painter->setBrushOrigin( d_data->styleSheet.background.origin );
815  painter->setClipPath( d_data->styleSheet.borderPath );
816  painter->drawRect( w->contentsRect() );
817 
818  painter->restore();
819 
820  drawCanvas( painter );
821 
822  // Now paint the border on top
823  QStyleOptionFrame opt;
824  opt.initFrom( w );
825  w->style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, w);
826  }
827  else
828  {
829  QStyleOption opt;
830  opt.initFrom( w );
831  w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w );
832 
833  drawCanvas( painter );
834  }
835 }
836 
837 void QwtPlotAbstractCanvas::drawCanvas( QPainter *painter )
838 {
839  QWidget *w = canvasWidget();
840 
841  painter->save();
842 
843  if ( !d_data->styleSheet.borderPath.isEmpty() )
844  {
845  painter->setClipPath(
846  d_data->styleSheet.borderPath, Qt::IntersectClip );
847  }
848  else
849  {
850  if ( borderRadius() > 0.0 )
851  {
852  const QRect frameRect = w->property( "frameRect" ).toRect();
853  painter->setClipPath( borderPath2( frameRect ), Qt::IntersectClip );
854  }
855  else
856  {
857  painter->setClipRect( w->contentsRect(), Qt::IntersectClip );
858  }
859  }
860 
861  QwtPlot *plot = qobject_cast< QwtPlot *>( w->parent() );
862  if ( plot )
863  plot->drawCanvas( painter );
864 
865  painter->restore();
866 }
867 
870 {
871  QWidget *w = canvasWidget();
872 
873  if ( !w->testAttribute( Qt::WA_StyledBackground ) )
874  return;
875 
876  QwtStyleSheetRecorder recorder( w->size() );
877 
878  QPainter painter( &recorder );
879 
880  QStyleOption opt;
881  opt.initFrom(w);
882  w->style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, w);
883 
884  painter.end();
885 
886  d_data->styleSheet.hasBorder = !recorder.border.rectList.isEmpty();
887  d_data->styleSheet.cornerRects = recorder.clipRects;
888 
889  if ( recorder.background.path.isEmpty() )
890  {
891  if ( !recorder.border.rectList.isEmpty() )
892  {
893  d_data->styleSheet.borderPath =
894  qwtCombinePathList( w->rect(), recorder.border.pathList );
895  }
896  }
897  else
898  {
899  d_data->styleSheet.borderPath = recorder.background.path;
900  d_data->styleSheet.background.brush = recorder.background.brush;
901  d_data->styleSheet.background.origin = recorder.background.origin;
902  }
903 }
904 
906 {
907  return d_data->canvasWidget;
908 }
909 
911 {
912  return d_data->canvasWidget;
913 }
914 
916 {
917 public:
919  frameStyle( QFrame::Panel | QFrame::Sunken),
920  lineWidth( 2 ),
921  midLineWidth( 0 )
922  {
923  }
924 
926  {
927  }
928 
930 
934 };
935 
937  QwtPlotAbstractCanvas( canvasWidget )
938 {
939  d_data = new PrivateData;
940 
941  qwtUpdateContentsRect( frameWidth(), canvasWidget );
943 }
944 
946 {
947  delete d_data;
948 }
949 
959 {
960  if ( bool( d_data->paintAttributes & attribute ) == on )
961  return;
962 
963  if ( on )
964  {
965  d_data->paintAttributes |= attribute;
966  }
967  else
968  {
969  d_data->paintAttributes &= ~attribute;
970 
971  if ( attribute == BackingStore )
973  }
974 }
975 
984 {
985  return d_data->paintAttributes & attribute;
986 }
987 
997 {
998  if ( style != d_data->frameStyle )
999  {
1000  d_data->frameStyle = style;
1002 
1003  canvasWidget()->update();
1004  }
1005 }
1006 
1012 {
1013  return d_data->frameStyle;
1014 }
1015 
1022 void QwtPlotAbstractGLCanvas::setFrameShadow( QFrame::Shadow shadow )
1023 {
1024  setFrameStyle(( d_data->frameStyle & QFrame::Shape_Mask ) | shadow );
1025 }
1026 
1032 {
1033  return (QFrame::Shadow) ( d_data->frameStyle & QFrame::Shadow_Mask );
1034 }
1035 
1042 void QwtPlotAbstractGLCanvas::setFrameShape( QFrame::Shape shape )
1043 {
1044  setFrameStyle( ( d_data->frameStyle & QFrame::Shadow_Mask ) | shape );
1045 }
1046 
1052 {
1053  return (QFrame::Shape) ( d_data->frameStyle & QFrame::Shape_Mask );
1054 }
1055 
1065 {
1066  width = qMax( width, 0 );
1067  if ( width != d_data->lineWidth )
1068  {
1069  d_data->lineWidth = qMax( width, 0 );
1071  canvasWidget()->update();
1072  }
1073 }
1074 
1080 {
1081  return d_data->lineWidth;
1082 }
1083 
1093 {
1094  width = qMax( width, 0 );
1095  if ( width != d_data->midLineWidth )
1096  {
1097  d_data->midLineWidth = width;
1099  canvasWidget()->update();
1100  }
1101 }
1102 
1108 {
1109  return d_data->midLineWidth;
1110 }
1111 
1116 {
1117  return ( frameStyle() != QFrame::NoFrame ) ? d_data->lineWidth : 0;
1118 }
1119 
1125 {
1127 
1128  QWidget *w = canvasWidget();
1130  w->repaint( w->contentsRect() );
1131  else
1132  w->update( w->contentsRect() );
1133 }
1134 
1137 {
1138  const int fw = frameWidth();
1139  return canvasWidget()->contentsRect().adjusted( -fw, -fw, fw, fw );
1140 }
1141 
1142 void QwtPlotAbstractGLCanvas::draw( QPainter *painter )
1143 {
1144 #if FIX_GL_TRANSLATION
1145  if ( painter->paintEngine()->type() == QPaintEngine::OpenGL2 )
1146  {
1147  // work around a translation bug of QPaintEngine::OpenGL2
1148  painter->translate( 1, 1 );
1149  }
1150 #endif
1151 
1152  if ( canvasWidget()->testAttribute( Qt::WA_StyledBackground ) )
1153  drawStyled( painter, true );
1154  else
1155  drawUnstyled( painter );
1156 
1157  if ( frameWidth() > 0 )
1158  drawBorder( painter );
1159 }
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())
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
QwtPlotAbstractGLCanvas::PaintAttributes paintAttributes
A null paint device doing nothing.
FocusIndicator focusIndicator() const
static void qwtUpdateContentsRect(int fw, QWidget *canvas)
static void qwtDrawBackground(QPainter *painter, QWidget *canvas)
A 2-D plotting widget.
Definition: qwt_plot.h:74
virtual void drawRects(const QRectF *rects, int count)
See QPaintEngine::drawRects()
void drawStyled(QPainter *, bool)
virtual void drawPath(const QPainterPath &path)
See QPaintEngine::drawPath()
virtual QSize sizeMetrics() const
static void drawRoundedFrame(QPainter *, const QRectF &, double xRadius, double yRadius, const QPalette &, int lineWidth, int frameStyle)
struct QwtStyleSheetRecorder::Background background
GraphId path[kMaxDeadlockPathLen]
void alignCornerRects(const QRectF &rect)
virtual void drawCanvas(QPainter *)
Definition: qwt_plot.cpp:735
virtual void drawRects(const QRect *rects, int count)
See QPaintEngine::drawRects()
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)
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
QwtPlotAbstractGLCanvas(QWidget *canvasWidget)
void setFocusIndicator(FocusIndicator)
QPainterPath borderPath2(const QRect &rect) const
TFSIMD_FORCE_INLINE const tfScalar & w() const
virtual void drawBorder(QPainter *)
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
FocusIndicator
Focus indicator The default setting is NoFocusIndicator.
QwtPlot * plot()
Return parent plot widget.
void setCornerRects(const QPainterPath &path)
static QWidget * qwtBackgroundWidget(QWidget *w)
QwtPlotAbstractCanvas(QWidget *canvasWidget)
virtual void drawFocusIndicator(QPainter *)
int i
QwtStyleSheetRecorder(const QSize &size)
virtual void updateState(const QPaintEngineState &state)
See QPaintEngine::updateState()
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
struct QwtStyleSheetRecorder::Border border


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17