1
#include <qapplication.h>
3
#include <qwhatsthis.h>
6
#include <qwt_symbol.h>
7
#include <qwt_scale_map.h>
8
#include <qwt_plot_canvas.h>
9
#include <qwt_plot_curve.h>
10
#include <qwt_plot_directpainter.h>
11
#include "canvaspicker.h"
13
CanvasPicker::CanvasPicker(QwtPlot *plot):
15
d_selectedCurve(NULL),
18
QwtPlotCanvas *canvas = plot->canvas();
20
canvas->installEventFilter(this);
22
// We want the focus, but no focus rect. The
23
// selected point will be highlighted instead.
25
canvas->setFocusPolicy(Qt::StrongFocus);
27
canvas->setCursor(Qt::PointingHandCursor);
29
canvas->setFocusIndicator(QwtPlotCanvas::ItemFocusIndicator);
33
"All points can be moved using the left mouse button "
34
"or with these keys:\n\n"
35
"- Up:\t\tSelect next curve\n"
36
"- Down:\t\tSelect previous curve\n"
37
"- Left, �-�:\tSelect next point\n"
38
"- Right, �+�:\tSelect previous point\n"
39
"- 7, 8, 9, 4, 6, 1, 2, 3:\tMove selected point";
40
canvas->setWhatsThis(text);
42
shiftCurveCursor(true);
45
bool CanvasPicker::event(QEvent *e)
47
if ( e->type() == QEvent::User )
52
return QObject::event(e);
55
bool CanvasPicker::eventFilter(QObject *object, QEvent *e)
57
if ( object != (QObject *)plot()->canvas() )
64
case QEvent::FocusOut:
69
QApplication::postEvent(this, new QEvent(QEvent::User));
72
case QEvent::MouseButtonPress:
74
select(((QMouseEvent *)e)->pos());
77
case QEvent::MouseMove:
79
move(((QMouseEvent *)e)->pos());
82
case QEvent::KeyPress:
85
switch(((const QKeyEvent *)e)->key())
88
shiftCurveCursor(true);
92
shiftCurveCursor(false);
97
if ( d_selectedCurve )
98
shiftPointCursor(true);
100
shiftCurveCursor(true);
105
if ( d_selectedCurve )
106
shiftPointCursor(false);
108
shiftCurveCursor(true);
111
// The following keys represent a direction, they are
112
// organized on the keyboard.
115
moveBy(-delta, delta);
121
moveBy(delta, delta);
130
moveBy(-delta, -delta);
136
moveBy(delta, -delta);
145
return QObject::eventFilter(object, e);
148
// Select the point at a position. If there is no point
149
// deselect the selected point
151
void CanvasPicker::select(const QPoint &pos)
153
QwtPlotCurve *curve = NULL;
157
const QwtPlotItemList& itmList = plot()->itemList();
158
for ( QwtPlotItemIterator it = itmList.begin();
159
it != itmList.end(); ++it )
161
if ( (*it)->rtti() == QwtPlotItem::Rtti_PlotCurve )
163
QwtPlotCurve *c = (QwtPlotCurve*)(*it);
166
int idx = c->closestPoint(pos, &d);
177
d_selectedCurve = NULL;
178
d_selectedPoint = -1;
180
if ( curve && dist < 10 ) // 10 pixels tolerance
182
d_selectedCurve = curve;
183
d_selectedPoint = index;
188
// Move the selected point
189
void CanvasPicker::moveBy(int dx, int dy)
191
if ( dx == 0 && dy == 0 )
194
if ( !d_selectedCurve )
197
const QPointF sample =
198
d_selectedCurve->sample(d_selectedPoint);
200
const double x = plot()->transform(
201
d_selectedCurve->xAxis(), sample.x());
202
const double y = plot()->transform(
203
d_selectedCurve->yAxis(), sample.y());
205
move( QPoint(qRound(x + dx), qRound(y + dy)) );
208
// Move the selected point
209
void CanvasPicker::move(const QPoint &pos)
211
if ( !d_selectedCurve )
214
QVector<double> xData(d_selectedCurve->dataSize());
215
QVector<double> yData(d_selectedCurve->dataSize());
217
for ( int i = 0; i < (int)d_selectedCurve->dataSize(); i++ )
219
if ( i == d_selectedPoint )
221
xData[i] = plot()->invTransform(
222
d_selectedCurve->xAxis(), pos.x());
223
yData[i] = plot()->invTransform(
224
d_selectedCurve->yAxis(), pos.y());
228
const QPointF sample = d_selectedCurve->sample(i);
229
xData[i] = sample.x();
230
yData[i] = sample.y();
233
d_selectedCurve->setSamples(xData, yData);
239
// Hightlight the selected point
240
void CanvasPicker::showCursor(bool showIt)
242
if ( !d_selectedCurve )
245
QwtSymbol *symbol = const_cast<QwtSymbol *>( d_selectedCurve->symbol() );
247
const QBrush brush = symbol->brush();
249
symbol->setBrush(symbol->brush().color().dark(150));
251
const bool doReplot = plot()->autoReplot();
253
plot()->setAutoReplot(false);
255
QwtPlotDirectPainter directPainter;
256
directPainter.drawSeries(d_selectedCurve, d_selectedPoint, d_selectedPoint);
259
symbol->setBrush(brush); // reset brush
261
plot()->setAutoReplot(doReplot);
264
// Select the next/previous curve
265
void CanvasPicker::shiftCurveCursor(bool up)
267
QwtPlotItemIterator it;
269
const QwtPlotItemList &itemList = plot()->itemList();
271
QwtPlotItemList curveList;
272
for ( it = itemList.begin(); it != itemList.end(); ++it )
274
if ( (*it)->rtti() == QwtPlotItem::Rtti_PlotCurve )
277
if ( curveList.isEmpty() )
280
it = curveList.begin();
282
if ( d_selectedCurve )
284
for ( it = curveList.begin(); it != curveList.end(); ++it )
286
if ( d_selectedCurve == *it )
289
if ( it == curveList.end() ) // not found
290
it = curveList.begin();
295
if ( it == curveList.end() )
296
it = curveList.begin();
300
if ( it == curveList.begin() )
301
it = curveList.end();
308
d_selectedCurve = (QwtPlotCurve *)*it;
312
// Select the next/previous neighbour of the selected point
313
void CanvasPicker::shiftPointCursor(bool up)
315
if ( !d_selectedCurve )
318
int index = d_selectedPoint + (up ? 1 : -1);
319
index = (index + d_selectedCurve->dataSize()) % d_selectedCurve->dataSize();
321
if ( index != d_selectedPoint )
324
d_selectedPoint = index;