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
#if QT_VERSION < 0x040000
16
mode(QScrollView::Auto)
18
mode(Qt::ScrollBarAsNeeded)
29
ScrollZoomer::ScrollBarPosition position;
30
#if QT_VERSION < 0x040000
31
QScrollView::ScrollBarMode mode;
33
Qt::ScrollBarPolicy mode;
37
ScrollZoomer::ScrollZoomer(QwtPlotCanvas *canvas):
38
QwtPlotZoomer(canvas),
43
d_alignCanvasToScales(false)
48
d_hScrollData = new ScrollData;
49
d_vScrollData = new ScrollData;
52
ScrollZoomer::~ScrollZoomer()
54
delete d_cornerWidget;
59
void ScrollZoomer::rescale()
61
QwtScaleWidget *xScale = plot()->axisWidget(xAxis());
62
QwtScaleWidget *yScale = plot()->axisWidget(yAxis());
64
if ( zoomRectIndex() <= 0 )
68
xScale->setMinBorderDist(0, 0);
69
yScale->setMinBorderDist(0, 0);
71
QwtPlotLayout *layout = plot()->plotLayout();
72
layout->setAlignCanvasToScales(d_alignCanvasToScales);
82
We set a minimum border distance.
83
Otherwise the canvas size changes when scrolling,
84
between situations where the major ticks are at
85
the canvas borders (requiring extra space for the label)
86
and situations where all labels can be painted below/top
87
or left/right of the canvas.
91
xScale->getBorderDistHint(start, end);
92
xScale->setMinBorderDist(start, end);
94
yScale->getBorderDistHint(start, end);
95
yScale->setMinBorderDist(start, end);
97
QwtPlotLayout *layout = plot()->plotLayout();
98
d_alignCanvasToScales = layout->alignCanvasToScales();
99
layout->setAlignCanvasToScales(false);
105
QwtPlotZoomer::rescale();
109
ScrollBar *ScrollZoomer::scrollBar(Qt::Orientation o)
111
ScrollBar *&sb = (o == Qt::Vertical)
112
? d_vScrollData->scrollBar : d_hScrollData->scrollBar;
116
sb = new ScrollBar(o, canvas());
119
SIGNAL(valueChanged(Qt::Orientation, double, double)),
120
SLOT(scrollBarMoved(Qt::Orientation, double, double)));
125
ScrollBar *ScrollZoomer::horizontalScrollBar() const
127
return d_hScrollData->scrollBar;
130
ScrollBar *ScrollZoomer::verticalScrollBar() const
132
return d_vScrollData->scrollBar;
135
#if QT_VERSION < 0x040000
136
void ScrollZoomer::setHScrollBarMode(QScrollView::ScrollBarMode mode)
138
void ScrollZoomer::setHScrollBarMode(Qt::ScrollBarPolicy mode)
141
if ( hScrollBarMode() != mode )
143
d_hScrollData->mode = mode;
148
#if QT_VERSION < 0x040000
149
void ScrollZoomer::setVScrollBarMode(QScrollView::ScrollBarMode mode)
151
void ScrollZoomer::setVScrollBarMode(Qt::ScrollBarPolicy mode)
154
if ( vScrollBarMode() != mode )
156
d_vScrollData->mode = mode;
161
#if QT_VERSION < 0x040000
162
QScrollView::ScrollBarMode ScrollZoomer::hScrollBarMode() const
164
Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const
167
return d_hScrollData->mode;
170
#if QT_VERSION < 0x040000
171
QScrollView::ScrollBarMode ScrollZoomer::vScrollBarMode() const
173
Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const
176
return d_vScrollData->mode;
179
void ScrollZoomer::setHScrollBarPosition(ScrollBarPosition pos)
181
if ( d_hScrollData->position != pos )
183
d_hScrollData->position = pos;
188
void ScrollZoomer::setVScrollBarPosition(ScrollBarPosition pos)
190
if ( d_vScrollData->position != pos )
192
d_vScrollData->position = pos;
197
ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const
199
return d_hScrollData->position;
202
ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const
204
return d_vScrollData->position;
207
void ScrollZoomer::setCornerWidget(QWidget *w)
209
if ( w != d_cornerWidget )
213
delete d_cornerWidget;
215
if ( d_cornerWidget->parent() != canvas() )
217
#if QT_VERSION < 0x040000
218
d_cornerWidget->reparent(canvas(), QPoint(0, 0));
220
d_cornerWidget->setParent(canvas());
229
QWidget *ScrollZoomer::cornerWidget() const
231
return d_cornerWidget;
234
bool ScrollZoomer::eventFilter(QObject *o, QEvent *e)
242
const int fw = ((QwtPlotCanvas *)canvas())->frameWidth();
245
rect.setSize(((QResizeEvent *)e)->size());
246
rect.setRect(rect.x() + fw, rect.y() + fw,
247
rect.width() - 2 * fw, rect.height() - 2 * fw);
249
layoutScrollBars(rect);
252
case QEvent::ChildRemoved:
254
const QObject *child = ((QChildEvent *)e)->child();
255
if ( child == d_cornerWidget )
256
d_cornerWidget = NULL;
257
else if ( child == d_hScrollData->scrollBar )
258
d_hScrollData->scrollBar = NULL;
259
else if ( child == d_vScrollData->scrollBar )
260
d_vScrollData->scrollBar = NULL;
267
return QwtPlotZoomer::eventFilter(o, e);
270
bool ScrollZoomer::needScrollBar(Qt::Orientation o) const
272
#if QT_VERSION < 0x040000
273
QScrollView::ScrollBarMode mode;
275
Qt::ScrollBarPolicy mode;
277
double zoomMin, zoomMax, baseMin, baseMax;
279
if ( o == Qt::Horizontal )
281
mode = d_hScrollData->mode;
282
baseMin = zoomBase().left();
283
baseMax = zoomBase().right();
284
zoomMin = zoomRect().left();
285
zoomMax = zoomRect().right();
289
mode = d_vScrollData->mode;
290
baseMin = zoomBase().top();
291
baseMax = zoomBase().bottom();
292
zoomMin = zoomRect().top();
293
zoomMax = zoomRect().bottom();
299
#if QT_VERSION < 0x040000
300
case QScrollView::AlwaysOn:
302
case Qt::ScrollBarAlwaysOn:
306
#if QT_VERSION < 0x040000
307
case QScrollView::AlwaysOff:
309
case Qt::ScrollBarAlwaysOff:
315
if ( baseMin < zoomMin || baseMax > zoomMax )
323
void ScrollZoomer::updateScrollBars()
328
const int xAxis = QwtPlotZoomer::xAxis();
329
const int yAxis = QwtPlotZoomer::yAxis();
331
int xScrollBarAxis = xAxis;
332
if ( hScrollBarPosition() == OppositeToScale )
333
xScrollBarAxis = oppositeAxis(xScrollBarAxis);
335
int yScrollBarAxis = yAxis;
336
if ( vScrollBarPosition() == OppositeToScale )
337
yScrollBarAxis = oppositeAxis(yScrollBarAxis);
340
QwtPlotLayout *layout = plot()->plotLayout();
342
bool showHScrollBar = needScrollBar(Qt::Horizontal);
343
if ( showHScrollBar )
345
ScrollBar *sb = scrollBar(Qt::Horizontal);
347
sb->setPalette(plot()->palette());
349
const QwtScaleDiv *sd = plot()->axisScaleDiv(xAxis);
350
sb->setInverted(sd->lBound() > sd->hBound() );
352
sb->setBase(zoomBase().left(), zoomBase().right());
353
sb->moveSlider(zoomRect().left(), zoomRect().right());
355
if ( !sb->isVisibleTo(canvas()) )
358
layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis)
359
+ sb->extent(), xScrollBarAxis);
364
if ( horizontalScrollBar() )
366
horizontalScrollBar()->hide();
367
layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis)
368
- horizontalScrollBar()->extent(), xScrollBarAxis);
372
bool showVScrollBar = needScrollBar(Qt::Vertical);
373
if ( showVScrollBar )
375
ScrollBar *sb = scrollBar(Qt::Vertical);
377
sb->setPalette(plot()->palette());
379
const QwtScaleDiv *sd = plot()->axisScaleDiv(yAxis);
380
sb->setInverted(sd->lBound() > sd->hBound() );
382
sb->setBase(zoomBase().top(), zoomBase().bottom());
383
sb->moveSlider(zoomRect().top(), zoomRect().bottom());
385
if ( !sb->isVisibleTo(canvas()) )
388
layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis)
389
+ sb->extent(), yScrollBarAxis);
394
if ( verticalScrollBar() )
396
verticalScrollBar()->hide();
397
layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis)
398
- verticalScrollBar()->extent(), yScrollBarAxis);
402
if ( showHScrollBar && showVScrollBar )
404
if ( d_cornerWidget == NULL )
406
d_cornerWidget = new QWidget(canvas());
407
#if QT_VERSION >= 0x040100
408
d_cornerWidget->setAutoFillBackground(true);
410
d_cornerWidget->setPalette(plot()->palette());
412
d_cornerWidget->show();
416
if ( d_cornerWidget )
417
d_cornerWidget->hide();
420
layoutScrollBars(((QwtPlotCanvas *)canvas())->contentsRect());
421
plot()->updateLayout();
424
void ScrollZoomer::layoutScrollBars(const QRect &rect)
427
if ( hScrollBarPosition() == OppositeToScale )
428
hPos = oppositeAxis(hPos);
431
if ( vScrollBarPosition() == OppositeToScale )
432
vPos = oppositeAxis(vPos);
434
ScrollBar *hScrollBar = horizontalScrollBar();
435
ScrollBar *vScrollBar = verticalScrollBar();
437
const int hdim = hScrollBar ? hScrollBar->extent() : 0;
438
const int vdim = vScrollBar ? vScrollBar->extent() : 0;
440
if ( hScrollBar && hScrollBar->isVisible() )
443
int y = (hPos == QwtPlot::xTop)
444
? rect.top() : rect.bottom() - hdim + 1;
445
int w = rect.width();
447
if ( vScrollBar && vScrollBar->isVisible() )
449
if ( vPos == QwtPlot::yLeft )
454
hScrollBar->setGeometry(x, y, w, hdim);
456
if ( vScrollBar && vScrollBar->isVisible() )
459
if ( vScrollBarPosition() == OppositeToScale )
460
pos = oppositeAxis(pos);
462
int x = (vPos == QwtPlot::yLeft)
463
? rect.left() : rect.right() - vdim + 1;
466
int h = rect.height();
468
if ( hScrollBar && hScrollBar->isVisible() )
470
if ( hPos == QwtPlot::xTop )
476
vScrollBar->setGeometry(x, y, vdim, h);
478
if ( hScrollBar && hScrollBar->isVisible() &&
479
vScrollBar && vScrollBar->isVisible() )
481
if ( d_cornerWidget )
484
vScrollBar->pos().x(), hScrollBar->pos().y(),
486
d_cornerWidget->setGeometry(cornerRect);
491
void ScrollZoomer::scrollBarMoved(Qt::Orientation o, double min, double)
493
if ( o == Qt::Horizontal )
494
move(min, zoomRect().top());
496
move(zoomRect().left(), min);
498
emit zoomed(zoomRect());
501
int ScrollZoomer::oppositeAxis(int axis) const
505
case QwtPlot::xBottom:
506
return QwtPlot::xTop;
508
return QwtPlot::xBottom;
510
return QwtPlot::yRight;
511
case QwtPlot::yRight:
512
return QwtPlot::yLeft;