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),
47
d_hScrollData = new ScrollData;
48
d_vScrollData = new ScrollData;
51
ScrollZoomer::~ScrollZoomer()
53
delete d_cornerWidget;
58
void ScrollZoomer::rescale()
60
QwtScaleWidget *xScale = plot()->axisWidget(xAxis());
61
QwtScaleWidget *yScale = plot()->axisWidget(yAxis());
63
if ( zoomRectIndex() <= 0 )
67
xScale->setMinBorderDist(0, 0);
68
yScale->setMinBorderDist(0, 0);
77
We set a minimum border distance.
78
Otherwise the canvas size changes when scrolling,
79
between situations where the major ticks are at
80
the canvas borders (requiring extra space for the label)
81
and situations where all labels can be painted below/top
82
or left/right of the canvas.
86
xScale->getBorderDistHint(start, end);
87
xScale->setMinBorderDist(start, end);
89
yScale->getBorderDistHint(start, end);
90
yScale->setMinBorderDist(start, end);
96
QwtPlotZoomer::rescale();
100
ScrollBar *ScrollZoomer::scrollBar(Qt::Orientation o)
102
ScrollBar *&sb = (o == Qt::Vertical)
103
? d_vScrollData->scrollBar : d_hScrollData->scrollBar;
107
sb = new ScrollBar(o, canvas());
110
SIGNAL(valueChanged(Qt::Orientation, double, double)),
111
SLOT(scrollBarMoved(Qt::Orientation, double, double)));
116
ScrollBar *ScrollZoomer::horizontalScrollBar() const
118
return d_hScrollData->scrollBar;
121
ScrollBar *ScrollZoomer::verticalScrollBar() const
123
return d_vScrollData->scrollBar;
126
#if QT_VERSION < 0x040000
127
void ScrollZoomer::setHScrollBarMode(QScrollView::ScrollBarMode mode)
129
void ScrollZoomer::setHScrollBarMode(Qt::ScrollBarPolicy mode)
132
if ( hScrollBarMode() != mode )
134
d_hScrollData->mode = mode;
139
#if QT_VERSION < 0x040000
140
void ScrollZoomer::setVScrollBarMode(QScrollView::ScrollBarMode mode)
142
void ScrollZoomer::setVScrollBarMode(Qt::ScrollBarPolicy mode)
145
if ( vScrollBarMode() != mode )
147
d_vScrollData->mode = mode;
152
#if QT_VERSION < 0x040000
153
QScrollView::ScrollBarMode ScrollZoomer::hScrollBarMode() const
155
Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const
158
return d_hScrollData->mode;
161
#if QT_VERSION < 0x040000
162
QScrollView::ScrollBarMode ScrollZoomer::vScrollBarMode() const
164
Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const
167
return d_vScrollData->mode;
170
void ScrollZoomer::setHScrollBarPosition(ScrollBarPosition pos)
172
if ( d_hScrollData->position != pos )
174
d_hScrollData->position = pos;
179
void ScrollZoomer::setVScrollBarPosition(ScrollBarPosition pos)
181
if ( d_vScrollData->position != pos )
183
d_vScrollData->position = pos;
188
ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const
190
return d_hScrollData->position;
193
ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const
195
return d_vScrollData->position;
198
void ScrollZoomer::setCornerWidget(QWidget *w)
200
if ( w != d_cornerWidget )
204
delete d_cornerWidget;
206
if ( d_cornerWidget->parent() != canvas() )
208
#if QT_VERSION < 0x040000
209
d_cornerWidget->reparent(canvas(), QPoint(0, 0));
211
d_cornerWidget->setParent(canvas());
220
QWidget *ScrollZoomer::cornerWidget() const
222
return d_cornerWidget;
225
bool ScrollZoomer::eventFilter(QObject *o, QEvent *e)
233
const int fw = ((QwtPlotCanvas *)canvas())->frameWidth();
236
rect.setSize(((QResizeEvent *)e)->size());
237
rect.setRect(rect.x() + fw, rect.y() + fw,
238
rect.width() - 2 * fw, rect.height() - 2 * fw);
240
layoutScrollBars(rect);
243
case QEvent::ChildRemoved:
245
const QObject *child = ((QChildEvent *)e)->child();
246
if ( child == d_cornerWidget )
247
d_cornerWidget = NULL;
248
else if ( child == d_hScrollData->scrollBar )
249
d_hScrollData->scrollBar = NULL;
250
else if ( child == d_vScrollData->scrollBar )
251
d_vScrollData->scrollBar = NULL;
258
return QwtPlotZoomer::eventFilter(o, e);
261
bool ScrollZoomer::needScrollBar(Qt::Orientation o) const
263
#if QT_VERSION < 0x040000
264
QScrollView::ScrollBarMode mode;
266
Qt::ScrollBarPolicy mode;
268
double zoomMin, zoomMax, baseMin, baseMax;
270
if ( o == Qt::Horizontal )
272
mode = d_hScrollData->mode;
273
baseMin = zoomBase().left();
274
baseMax = zoomBase().right();
275
zoomMin = zoomRect().left();
276
zoomMax = zoomRect().right();
280
mode = d_vScrollData->mode;
281
baseMin = zoomBase().top();
282
baseMax = zoomBase().bottom();
283
zoomMin = zoomRect().top();
284
zoomMax = zoomRect().bottom();
290
#if QT_VERSION < 0x040000
291
case QScrollView::AlwaysOn:
293
case Qt::ScrollBarAlwaysOn:
297
#if QT_VERSION < 0x040000
298
case QScrollView::AlwaysOff:
300
case Qt::ScrollBarAlwaysOff:
306
if ( baseMin < zoomMin || baseMax > zoomMax )
314
void ScrollZoomer::updateScrollBars()
319
const int xAxis = QwtPlotZoomer::xAxis();
320
const int yAxis = QwtPlotZoomer::yAxis();
322
int xScrollBarAxis = xAxis;
323
if ( hScrollBarPosition() == OppositeToScale )
324
xScrollBarAxis = oppositeAxis(xScrollBarAxis);
326
int yScrollBarAxis = yAxis;
327
if ( vScrollBarPosition() == OppositeToScale )
328
yScrollBarAxis = oppositeAxis(yScrollBarAxis);
331
QwtPlotLayout *layout = plot()->plotLayout();
333
bool showHScrollBar = needScrollBar(Qt::Horizontal);
334
if ( showHScrollBar )
336
ScrollBar *sb = scrollBar(Qt::Horizontal);
338
sb->setPalette(plot()->palette());
340
const QwtScaleEngine *se = plot()->axisScaleEngine(xAxis);
341
sb->setInverted(se->testAttribute(QwtScaleEngine::Inverted));
343
sb->setBase(zoomBase().left(), zoomBase().right());
344
sb->moveSlider(zoomRect().left(), zoomRect().right());
346
if ( !sb->isVisibleTo(canvas()) )
349
layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis)
350
+ sb->extent(), xScrollBarAxis);
355
if ( horizontalScrollBar() )
357
horizontalScrollBar()->hide();
358
layout->setCanvasMargin(layout->canvasMargin(xScrollBarAxis)
359
- horizontalScrollBar()->extent(), xScrollBarAxis);
363
bool showVScrollBar = needScrollBar(Qt::Vertical);
364
if ( showVScrollBar )
366
ScrollBar *sb = scrollBar(Qt::Vertical);
368
sb->setPalette(plot()->palette());
370
const QwtScaleEngine *se = plot()->axisScaleEngine(xAxis);
371
sb->setInverted(!(se->testAttribute(QwtScaleEngine::Inverted)));
373
sb->setBase(zoomBase().top(), zoomBase().bottom());
374
sb->moveSlider(zoomRect().top(), zoomRect().bottom());
376
if ( !sb->isVisibleTo(canvas()) )
379
layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis)
380
+ sb->extent(), yScrollBarAxis);
385
if ( verticalScrollBar() )
387
verticalScrollBar()->hide();
388
layout->setCanvasMargin(layout->canvasMargin(yScrollBarAxis)
389
- verticalScrollBar()->extent(), yScrollBarAxis);
393
if ( showHScrollBar && showVScrollBar )
395
if ( d_cornerWidget == NULL )
397
d_cornerWidget = new QWidget(canvas());
398
#if QT_VERSION >= 0x040100
399
d_cornerWidget->setAutoFillBackground(true);
401
d_cornerWidget->setPalette(plot()->palette());
403
d_cornerWidget->show();
407
if ( d_cornerWidget )
408
d_cornerWidget->hide();
411
layoutScrollBars(((QwtPlotCanvas *)canvas())->contentsRect());
412
plot()->updateLayout();
415
void ScrollZoomer::layoutScrollBars(const QRect &rect)
418
if ( hScrollBarPosition() == OppositeToScale )
419
hPos = oppositeAxis(hPos);
422
if ( vScrollBarPosition() == OppositeToScale )
423
vPos = oppositeAxis(vPos);
425
ScrollBar *hScrollBar = horizontalScrollBar();
426
ScrollBar *vScrollBar = verticalScrollBar();
428
const int hdim = hScrollBar ? hScrollBar->extent() : 0;
429
const int vdim = vScrollBar ? vScrollBar->extent() : 0;
431
if ( hScrollBar && hScrollBar->isVisible() )
434
int y = (hPos == QwtPlot::xTop)
435
? rect.top() : rect.bottom() - hdim + 1;
436
int w = rect.width();
438
if ( vScrollBar && vScrollBar->isVisible() )
440
if ( vPos == QwtPlot::yLeft )
445
hScrollBar->setGeometry(x, y, w, hdim);
447
if ( vScrollBar && vScrollBar->isVisible() )
450
if ( vScrollBarPosition() == OppositeToScale )
451
pos = oppositeAxis(pos);
453
int x = (vPos == QwtPlot::yLeft)
454
? rect.left() : rect.right() - vdim + 1;
457
int h = rect.height();
459
if ( hScrollBar && hScrollBar->isVisible() )
461
if ( hPos == QwtPlot::xTop )
467
vScrollBar->setGeometry(x, y, vdim, h);
469
if ( hScrollBar && hScrollBar->isVisible() &&
470
vScrollBar && vScrollBar->isVisible() )
472
if ( d_cornerWidget )
475
vScrollBar->pos().x(), hScrollBar->pos().y(),
477
d_cornerWidget->setGeometry(cornerRect);
482
void ScrollZoomer::scrollBarMoved(Qt::Orientation o, double min, double)
484
if ( o == Qt::Horizontal )
485
move(min, zoomRect().top());
487
move(zoomRect().left(), min);
489
emit zoomed(zoomRect());
492
int ScrollZoomer::oppositeAxis(int axis) const
496
case QwtPlot::xBottom:
497
return QwtPlot::xTop;
499
return QwtPlot::xBottom;
501
return QwtPlot::yRight;
502
case QwtPlot::yRight:
503
return QwtPlot::yLeft;