2
#include <qwt_plot_canvas.h>
3
#include <qwt_plot_layout.h>
4
#include <qwt_scale_engine.h>
5
#include <qwt_scale_widget.h>
7
#include "scrollzoomer.h"
14
position(ScrollZoomer::OppositeToScale),
15
mode(Qt::ScrollBarAsNeeded)
25
ScrollZoomer::ScrollBarPosition position;
26
Qt::ScrollBarPolicy mode;
29
ScrollZoomer::ScrollZoomer(QwtPlotCanvas *canvas):
30
QwtPlotZoomer(canvas),
35
d_alignCanvasToScales(false)
40
d_hScrollData = new ScrollData;
41
d_vScrollData = new ScrollData;
44
ScrollZoomer::~ScrollZoomer()
46
delete d_cornerWidget;
51
void ScrollZoomer::rescale()
53
QwtScaleWidget *xScale = plot()->axisWidget(xAxis());
54
QwtScaleWidget *yScale = plot()->axisWidget(yAxis());
56
if ( zoomRectIndex() <= 0 )
60
xScale->setMinBorderDist(0, 0);
61
yScale->setMinBorderDist(0, 0);
63
QwtPlotLayout *layout = plot()->plotLayout();
64
layout->setAlignCanvasToScales(d_alignCanvasToScales);
74
We set a minimum border distance.
75
Otherwise the canvas size changes when scrolling,
76
between situations where the major ticks are at
77
the canvas borders (requiring extra space for the label)
78
and situations where all labels can be painted below/top
79
or left/right of the canvas.
83
xScale->getBorderDistHint(start, end);
84
xScale->setMinBorderDist(start, end);
86
yScale->getBorderDistHint(start, end);
87
yScale->setMinBorderDist(start, end);
89
QwtPlotLayout *layout = plot()->plotLayout();
90
d_alignCanvasToScales = layout->alignCanvasToScales();
91
layout->setAlignCanvasToScales(false);
97
QwtPlotZoomer::rescale();
101
ScrollBar *ScrollZoomer::scrollBar(Qt::Orientation o)
103
ScrollBar *&sb = (o == Qt::Vertical)
104
? d_vScrollData->scrollBar : d_hScrollData->scrollBar;
108
sb = new ScrollBar(o, canvas());
111
SIGNAL(valueChanged(Qt::Orientation, double, double)),
112
SLOT(scrollBarMoved(Qt::Orientation, double, double)));
117
ScrollBar *ScrollZoomer::horizontalScrollBar() const
119
return d_hScrollData->scrollBar;
122
ScrollBar *ScrollZoomer::verticalScrollBar() const
124
return d_vScrollData->scrollBar;
127
void ScrollZoomer::setHScrollBarMode(Qt::ScrollBarPolicy mode)
129
if ( hScrollBarMode() != mode )
131
d_hScrollData->mode = mode;
136
void ScrollZoomer::setVScrollBarMode(Qt::ScrollBarPolicy mode)
138
if ( vScrollBarMode() != mode )
140
d_vScrollData->mode = mode;
145
Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const
147
return d_hScrollData->mode;
150
Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const
152
return d_vScrollData->mode;
155
void ScrollZoomer::setHScrollBarPosition(ScrollBarPosition pos)
157
if ( d_hScrollData->position != pos )
159
d_hScrollData->position = pos;
164
void ScrollZoomer::setVScrollBarPosition(ScrollBarPosition pos)
166
if ( d_vScrollData->position != pos )
168
d_vScrollData->position = pos;
173
ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const
175
return d_hScrollData->position;
178
ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const
180
return d_vScrollData->position;
183
void ScrollZoomer::setCornerWidget(QWidget *w)
185
if ( w != d_cornerWidget )
189
delete d_cornerWidget;
191
if ( d_cornerWidget->parent() != canvas() )
192
d_cornerWidget->setParent(canvas());
199
QWidget *ScrollZoomer::cornerWidget() const
201
return d_cornerWidget;
204
bool ScrollZoomer::eventFilter(QObject *o, QEvent *e)
212
const int fw = ((QwtPlotCanvas *)canvas())->frameWidth();
215
rect.setSize(((QResizeEvent *)e)->size());
216
rect.setRect(rect.x() + fw, rect.y() + fw,
217
rect.width() - 2 * fw, rect.height() - 2 * fw);
219
layoutScrollBars(rect);
222
case QEvent::ChildRemoved:
224
const QObject *child = ((QChildEvent *)e)->child();
225
if ( child == d_cornerWidget )
226
d_cornerWidget = NULL;
227
else if ( child == d_hScrollData->scrollBar )
228
d_hScrollData->scrollBar = NULL;
229
else if ( child == d_vScrollData->scrollBar )
230
d_vScrollData->scrollBar = NULL;
237
return QwtPlotZoomer::eventFilter(o, e);
240
bool ScrollZoomer::needScrollBar(Qt::Orientation o) const
242
Qt::ScrollBarPolicy mode;
243
double zoomMin, zoomMax, baseMin, baseMax;
245
if ( o == Qt::Horizontal )
247
mode = d_hScrollData->mode;
248
baseMin = zoomBase().left();
249
baseMax = zoomBase().right();
250
zoomMin = zoomRect().left();
251
zoomMax = zoomRect().right();
255
mode = d_vScrollData->mode;
256
baseMin = zoomBase().top();
257
baseMax = zoomBase().bottom();
258
zoomMin = zoomRect().top();
259
zoomMax = zoomRect().bottom();
265
case Qt::ScrollBarAlwaysOn:
268
case Qt::ScrollBarAlwaysOff:
273
if ( baseMin < zoomMin || baseMax > zoomMax )
281
void ScrollZoomer::updateScrollBars()
286
const int xAxis = QwtPlotZoomer::xAxis();
287
const int yAxis = QwtPlotZoomer::yAxis();
289
int xScrollBarAxis = xAxis;
290
if ( hScrollBarPosition() == OppositeToScale )
291
xScrollBarAxis = oppositeAxis(xScrollBarAxis);
293
int yScrollBarAxis = yAxis;
294
if ( vScrollBarPosition() == OppositeToScale )
295
yScrollBarAxis = oppositeAxis(yScrollBarAxis);
298
QwtPlotLayout *layout = plot()->plotLayout();
300
bool showHScrollBar = needScrollBar(Qt::Horizontal);
301
if ( showHScrollBar )
303
ScrollBar *sb = scrollBar(Qt::Horizontal);
305
sb->setPalette(plot()->palette());
307
const QwtScaleDiv *sd = plot()->axisScaleDiv(xAxis);
308
sb->setInverted(sd->lowerBound() > sd->upperBound() );
310
sb->setBase(zoomBase().left(), zoomBase().right());
311
sb->moveSlider(zoomRect().left(), zoomRect().right());
313
if ( !sb->isVisibleTo(canvas()) )
316
layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis)
317
+ sb->extent(), xScrollBarAxis);
322
if ( horizontalScrollBar() )
324
horizontalScrollBar()->hide();
325
layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis)
326
- horizontalScrollBar()->extent(), xScrollBarAxis);
330
bool showVScrollBar = needScrollBar(Qt::Vertical);
331
if ( showVScrollBar )
333
ScrollBar *sb = scrollBar(Qt::Vertical);
335
sb->setPalette(plot()->palette());
337
const QwtScaleDiv *sd = plot()->axisScaleDiv(yAxis);
338
sb->setInverted(sd->lowerBound() < sd->upperBound() );
340
sb->setBase(zoomBase().top(), zoomBase().bottom());
341
sb->moveSlider(zoomRect().top(), zoomRect().bottom());
343
if ( !sb->isVisibleTo(canvas()) )
346
layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis)
347
+ sb->extent(), yScrollBarAxis);
352
if ( verticalScrollBar() )
354
verticalScrollBar()->hide();
355
layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis)
356
- verticalScrollBar()->extent(), yScrollBarAxis);
360
if ( showHScrollBar && showVScrollBar )
362
if ( d_cornerWidget == NULL )
364
d_cornerWidget = new QWidget(canvas());
365
d_cornerWidget->setAutoFillBackground(true);
366
d_cornerWidget->setPalette(plot()->palette());
368
d_cornerWidget->show();
372
if ( d_cornerWidget )
373
d_cornerWidget->hide();
376
layoutScrollBars(((QwtPlotCanvas *)canvas())->contentsRect());
377
plot()->updateLayout();
380
void ScrollZoomer::layoutScrollBars(const QRect &rect)
383
if ( hScrollBarPosition() == OppositeToScale )
384
hPos = oppositeAxis(hPos);
387
if ( vScrollBarPosition() == OppositeToScale )
388
vPos = oppositeAxis(vPos);
390
ScrollBar *hScrollBar = horizontalScrollBar();
391
ScrollBar *vScrollBar = verticalScrollBar();
393
const int hdim = hScrollBar ? hScrollBar->extent() : 0;
394
const int vdim = vScrollBar ? vScrollBar->extent() : 0;
396
if ( hScrollBar && hScrollBar->isVisible() )
399
int y = (hPos == QwtPlot::xTop)
400
? rect.top() : rect.bottom() - hdim + 1;
401
int w = rect.width();
403
if ( vScrollBar && vScrollBar->isVisible() )
405
if ( vPos == QwtPlot::yLeft )
410
hScrollBar->setGeometry(x, y, w, hdim);
412
if ( vScrollBar && vScrollBar->isVisible() )
415
if ( vScrollBarPosition() == OppositeToScale )
416
pos = oppositeAxis(pos);
418
int x = (vPos == QwtPlot::yLeft)
419
? rect.left() : rect.right() - vdim + 1;
422
int h = rect.height();
424
if ( hScrollBar && hScrollBar->isVisible() )
426
if ( hPos == QwtPlot::xTop )
432
vScrollBar->setGeometry(x, y, vdim, h);
434
if ( hScrollBar && hScrollBar->isVisible() &&
435
vScrollBar && vScrollBar->isVisible() )
437
if ( d_cornerWidget )
440
vScrollBar->pos().x(), hScrollBar->pos().y(),
442
d_cornerWidget->setGeometry(cornerRect);
447
void ScrollZoomer::scrollBarMoved(
448
Qt::Orientation o, double min, double max)
452
if ( o == Qt::Horizontal )
453
moveTo( QPointF( min, zoomRect().top() ) );
455
moveTo( QPointF( zoomRect().left(), min ) );
457
Q_EMIT zoomed(zoomRect());
460
int ScrollZoomer::oppositeAxis(int axis) const
464
case QwtPlot::xBottom:
465
return QwtPlot::xTop;
467
return QwtPlot::xBottom;
469
return QwtPlot::yRight;
470
case QwtPlot::yRight:
471
return QwtPlot::yLeft;