-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathqwt_plot_directpainter.cpp
163 lines (133 loc) · 4.44 KB
/
qwt_plot_directpainter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_plot_directpainter.h"
#include "qwt_scale_map.h"
#include "qwt_plot.h"
#include "qwt_plot_canvas.h"
#include "qwt_plot_seriesitem.h"
#include <qpainter.h>
#include <qevent.h>
#include <qapplication.h>
#include <qpixmap.h>
static inline void renderItem(
QPainter *painter, const QRect &canvasRect,
QwtPlotAbstractSeriesItem *seriesItem, int from, int to )
{
QwtPlot *plot = seriesItem->plot();
const QwtScaleMap xMap = plot->canvasMap( QwtPlot::xBottom );
const QwtScaleMap yMap = plot->canvasMap( QwtPlot::yLeft );
painter->setRenderHint( QPainter::Antialiasing,
seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
}
class QwtPlotDirectPainter::PrivateData
{
public:
PrivateData():
seriesItem( NULL )
{
}
QPainter painter;
QwtPlotAbstractSeriesItem *seriesItem;
int from;
int to;
};
//! Constructor
QwtPlotDirectPainter::QwtPlotDirectPainter( QObject *parent ):
QObject( parent )
{
d_data = new PrivateData;
}
//! Destructor
QwtPlotDirectPainter::~QwtPlotDirectPainter()
{
delete d_data;
}
/*!
\brief Draw a set of points of a seriesItem.
When observing an measurement while it is running, new points have to be
added to an existing seriesItem. drawSeries can be used to display them avoiding
a complete redraw of the canvas.
Setting plot()->canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
will result in faster painting, if the paint engine of the canvas widget
supports this feature.
\param seriesItem Item to be painted
\param from Index of the first point to be painted
\param to Index of the last point to be painted. If to < 0 the
series will be painted to its last point.
*/
void QwtPlotDirectPainter::drawSeries(
QwtPlotAbstractSeriesItem *seriesItem, int from, int to )
{
if ( seriesItem == NULL || seriesItem->plot() == NULL )
return;
QwtPlotCanvas *canvas = seriesItem->plot()->canvas();
const QRect canvasRect = canvas->contentsRect();
bool immediatePaint = true;
if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) )
{
#if QT_VERSION < 0x050000
if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
#endif
immediatePaint = false;
}
if ( immediatePaint )
{
QwtPlotCanvas *canvas = seriesItem->plot()->canvas();
if ( !d_data->painter.isActive() )
{
reset();
d_data->painter.begin( canvas );
canvas->installEventFilter( this );
}
d_data->painter.setClipRect( canvasRect );
renderItem( &d_data->painter, canvasRect, seriesItem, from, to );
}
else
{
reset();
d_data->seriesItem = seriesItem;
d_data->from = from;
d_data->to = to;
canvas->installEventFilter( this );
canvas->repaint(canvasRect);
canvas->removeEventFilter( this );
d_data->seriesItem = NULL;
}
}
//! Close the internal QPainter
void QwtPlotDirectPainter::reset()
{
if ( d_data->painter.isActive() )
{
QWidget *w = ( QWidget * )d_data->painter.device();
if ( w )
w->removeEventFilter( this );
d_data->painter.end();
}
}
//! Event filter
bool QwtPlotDirectPainter::eventFilter( QObject *, QEvent *event )
{
if ( event->type() == QEvent::Paint )
{
reset();
if ( d_data->seriesItem )
{
const QPaintEvent *pe = static_cast< QPaintEvent *>( event );
QwtPlotCanvas *canvas = d_data->seriesItem->plot()->canvas();
QPainter painter( canvas );
painter.setClipRegion( pe->region() );
renderItem( &painter, canvas->contentsRect(),
d_data->seriesItem, d_data->from, d_data->to );
return true; // don't call QwtPlotCanvas::paintEvent()
}
}
return false;
}