#include <qevent.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_layout.h>
#include <qwt_scale_engine.h>
#include <qwt_scale_widget.h>
#include "scrollbar.h"
#include "scrollzoomer.h"
class ScrollData
{
public:
ScrollData():
scrollBar(NULL),
position(ScrollZoomer::OppositeToScale),
#if QT_VERSION < 0x040000
mode(QScrollView::Auto)
#else
mode(Qt::ScrollBarAsNeeded)
#endif
{
}
~ScrollData()
{
delete scrollBar;
}
ScrollBar *scrollBar;
ScrollZoomer::ScrollBarPosition position;
#if QT_VERSION < 0x040000
QScrollView::ScrollBarMode mode;
#else
Qt::ScrollBarPolicy mode;
#endif
};
ScrollZoomer::ScrollZoomer(QwtPlotCanvas *canvas):
QwtPlotZoomer(canvas),
d_cornerWidget(NULL),
d_hScrollData(NULL),
d_vScrollData(NULL),
d_inZoom(false),
d_alignCanvasToScales(false)
{
if ( !canvas )
return;
d_hScrollData = new ScrollData;
d_vScrollData = new ScrollData;
}
ScrollZoomer::~ScrollZoomer()
{
delete d_cornerWidget;
delete d_vScrollData;
delete d_hScrollData;
}
void ScrollZoomer::rescale()
{
QwtScaleWidget *xScale = plot()->axisWidget(xAxis());
QwtScaleWidget *yScale = plot()->axisWidget(yAxis());
if ( zoomRectIndex() <= 0 )
{
if ( d_inZoom )
{
xScale->setMinBorderDist(0, 0);
yScale->setMinBorderDist(0, 0);
QwtPlotLayout *layout = plot()->plotLayout();
layout->setAlignCanvasToScales(d_alignCanvasToScales);
d_inZoom = false;
}
}
else
{
if ( !d_inZoom )
{
/*
We set a minimum border distance.
Otherwise the canvas size changes when scrolling,
between situations where the major ticks are at
the canvas borders (requiring extra space for the label)
and situations where all labels can be painted below/top
or left/right of the canvas.
*/
int start, end;
xScale->getBorderDistHint(start, end);
xScale->setMinBorderDist(start, end);
yScale->getBorderDistHint(start, end);
yScale->setMinBorderDist(start, end);
QwtPlotLayout *layout = plot()->plotLayout();
d_alignCanvasToScales = layout->alignCanvasToScales();
layout->setAlignCanvasToScales(false);
d_inZoom = true;
}
}
QwtPlotZoomer::rescale();
updateScrollBars();
}
ScrollBar *ScrollZoomer::scrollBar(Qt::Orientation o)
{
ScrollBar *&sb = (o == Qt::Vertical)
? d_vScrollData->scrollBar : d_hScrollData->scrollBar;
if ( sb == NULL )
{
sb = new ScrollBar(o, canvas());
sb->hide();
connect(sb,
SIGNAL(valueChanged(Qt::Orientation, double, double)),
SLOT(scrollBarMoved(Qt::Orientation, double, double)));
}
return sb;
}
ScrollBar *ScrollZoomer::horizontalScrollBar() const
{
return d_hScrollData->scrollBar;
}
ScrollBar *ScrollZoomer::verticalScrollBar() const
{
return d_vScrollData->scrollBar;
}
#if QT_VERSION < 0x040000
void ScrollZoomer::setHScrollBarMode(QScrollView::ScrollBarMode mode)
#else
void ScrollZoomer::setHScrollBarMode(Qt::ScrollBarPolicy mode)
#endif
{
if ( hScrollBarMode() != mode )
{
d_hScrollData->mode = mode;
updateScrollBars();
}
}
#if QT_VERSION < 0x040000
void ScrollZoomer::setVScrollBarMode(QScrollView::ScrollBarMode mode)
#else
void ScrollZoomer::setVScrollBarMode(Qt::ScrollBarPolicy mode)
#endif
{
if ( vScrollBarMode() != mode )
{
d_vScrollData->mode = mode;
updateScrollBars();
}
}
#if QT_VERSION < 0x040000
QScrollView::ScrollBarMode ScrollZoomer::hScrollBarMode() const
#else
Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const
#endif
{
return d_hScrollData->mode;
}
#if QT_VERSION < 0x040000
QScrollView::ScrollBarMode ScrollZoomer::vScrollBarMode() const
#else
Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const
#endif
{
return d_vScrollData->mode;
}
void ScrollZoomer::setHScrollBarPosition(ScrollBarPosition pos)
{
if ( d_hScrollData->position != pos )
{
d_hScrollData->position = pos;
updateScrollBars();
}
}
void ScrollZoomer::setVScrollBarPosition(ScrollBarPosition pos)
{
if ( d_vScrollData->position != pos )
{
d_vScrollData->position = pos;
updateScrollBars();
}
}
ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const
{
return d_hScrollData->position;
}
ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const
{
return d_vScrollData->position;
}
void ScrollZoomer::setCornerWidget(QWidget *w)
{
if ( w != d_cornerWidget )
{
if ( canvas() )
{
delete d_cornerWidget;
d_cornerWidget = w;
if ( d_cornerWidget->parent() != canvas() )
{
#if QT_VERSION < 0x040000
d_cornerWidget->reparent(canvas(), QPoint(0, 0));
#else
d_cornerWidget->setParent(canvas());
#endif
}
updateScrollBars();
}
}
}
QWidget *ScrollZoomer::cornerWidget() const
{
return d_cornerWidget;
}
bool ScrollZoomer::eventFilter(QObject *o, QEvent *e)
{
if ( o == canvas() )
{
switch(e->type())
{
case QEvent::Resize:
{
const int fw = ((QwtPlotCanvas *)canvas())->frameWidth();
QRect rect;
rect.setSize(((QResizeEvent *)e)->size());
rect.setRect(rect.x() + fw, rect.y() + fw,
rect.width() - 2 * fw, rect.height() - 2 * fw);
layoutScrollBars(rect);
break;
}
case QEvent::ChildRemoved:
{
const QObject *child = ((QChildEvent *)e)->child();
if ( child == d_cornerWidget )
d_cornerWidget = NULL;
else if ( child == d_hScrollData->scrollBar )
d_hScrollData->scrollBar = NULL;
else if ( child == d_vScrollData->scrollBar )
d_vScrollData->scrollBar = NULL;
break;
}
default:
break;
}
}
return QwtPlotZoomer::eventFilter(o, e);
}
bool ScrollZoomer::needScrollBar(Qt::Orientation o) const
{
#if QT_VERSION < 0x040000
QScrollView::ScrollBarMode mode;
#else
Qt::ScrollBarPolicy mode;
#endif
double zoomMin, zoomMax, baseMin, baseMax;
{
mode = d_hScrollData->mode;
baseMin = zoomBase().left();
baseMax = zoomBase().right();
zoomMin = zoomRect().left();
zoomMax = zoomRect().right();
}
else
{
mode = d_vScrollData->mode;
baseMin = zoomBase().top();
baseMax = zoomBase().bottom();
zoomMin = zoomRect().top();
zoomMax = zoomRect().bottom();
}
bool needed = false;
switch(mode)
{
#if QT_VERSION < 0x040000
case QScrollView::AlwaysOn:
#else
case Qt::ScrollBarAlwaysOn:
#endif
needed = true;
break;
#if QT_VERSION < 0x040000
case QScrollView::AlwaysOff:
#else
case Qt::ScrollBarAlwaysOff:
#endif
needed = false;