diff options
Diffstat (limited to 'src/gui/widgets/qabstractscrollarea.cpp')
-rw-r--r-- | src/gui/widgets/qabstractscrollarea.cpp | 97 |
1 files changed, 85 insertions, 12 deletions
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 57cdd6d..770e769 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -52,9 +52,15 @@ #include "qboxlayout.h" #include "qpainter.h" +#ifdef Q_WS_WIN +#include "qstandardgestures.h" +#endif + #include "qabstractscrollarea_p.h" #include <qwidget.h> +#include <private/qapplication_p.h> + #ifdef Q_WS_MAC #include <private/qt_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> @@ -157,6 +163,9 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded), viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0), xoffset(0), yoffset(0), viewportFilter(0) +#ifdef Q_WS_WIN + , panGesture(0), singleFingerPanEnabled(false) +#endif { } @@ -281,15 +290,28 @@ void QAbstractScrollAreaPrivate::init() scrollBarContainers[Qt::Vertical]->setVisible(false); QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int))); QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection); - viewportFilter = new QAbstractScrollAreaFilter(this); - viewport->installEventFilter(viewportFilter); + viewportFilter.reset(new QAbstractScrollAreaFilter(this)); + viewport->installEventFilter(viewportFilter.data()); viewport->setFocusProxy(q); q->setFocusPolicy(Qt::WheelFocus); q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); + +#ifdef Q_WS_WIN + panGesture = new QPanGesture(viewport); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); +#endif // Q_WS_WIN } +#ifdef Q_WS_WIN +void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on) +{ + singleFingerPanEnabled = on; + winSetupGestures(); +} +#endif // Q_WS_WIN + void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); @@ -459,9 +481,6 @@ void QAbstractScrollAreaPrivate::layoutChildren() viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last } -// ### Fix for 4.4, talk to Bjoern E or Girish. -void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} - /*! \internal @@ -471,7 +490,12 @@ QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget :QFrame(dd, parent) { Q_D(QAbstractScrollArea); - d->init(); + QT_TRY { + d->init(); + } QT_CATCH(...) { + d->viewportFilter.reset(); + QT_RETHROW; + } } /*! @@ -483,7 +507,12 @@ QAbstractScrollArea::QAbstractScrollArea(QWidget *parent) :QFrame(*new QAbstractScrollAreaPrivate, parent) { Q_D(QAbstractScrollArea); - d->init(); + QT_TRY { + d->init(); + } QT_CATCH(...) { + d->viewportFilter.reset(); + QT_RETHROW; + } } @@ -493,7 +522,8 @@ QAbstractScrollArea::QAbstractScrollArea(QWidget *parent) QAbstractScrollArea::~QAbstractScrollArea() { Q_D(QAbstractScrollArea); - delete d->viewportFilter; + // reset it here, otherwise we'll have a dangling pointer in ~QWidget + d->viewportFilter.reset(); } @@ -517,11 +547,14 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport = widget; d->viewport->setParent(this); d->viewport->setFocusProxy(this); - d->viewport->installEventFilter(d->viewportFilter); + d->viewport->installEventFilter(d->viewportFilter.data()); d->layoutChildren(); if (isVisible()) d->viewport->show(); QMetaObject::invokeMethod(this, "setupViewport", Q_ARG(QWidget *, widget)); +#ifdef Q_WS_WIN + d->panGesture->setGestureTarget(widget); +#endif delete oldViewport; } } @@ -873,21 +906,22 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::Resize: d->layoutChildren(); break; - case QEvent::Paint: + case QEvent::Paint: { + QStyleOption option; + option.initFrom(this); if (d->cornerPaintingRect.isValid()) { - QStyleOption option; option.rect = d->cornerPaintingRect; QPainter p(this); style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this); } #ifdef Q_WS_MAC if (d->reverseCornerPaintingRect.isValid()) { - QStyleOption option; option.rect = d->reverseCornerPaintingRect; QPainter p(this); style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p, this); } #endif + } QFrame::paintEvent((QPaintEvent*)e); break; #ifndef QT_NO_CONTEXTMENU @@ -908,6 +942,10 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif + // ignore touch events in case they have been propagated from the viewport + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: @@ -948,6 +986,9 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e) case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: case QEvent::MouseMove: case QEvent::ContextMenu: #ifndef QT_NO_WHEELEVENT @@ -1237,6 +1278,11 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y) void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars() { layoutChildren(); +#ifdef Q_OS_WIN + // Need to re-subscribe to gestures as the content changes to make sure we + // enable/disable panning when needed. + winSetupGestures(); +#endif // Q_OS_WIN } QPoint QAbstractScrollAreaPrivate::contentsOffset() const @@ -1264,6 +1310,12 @@ QSize QAbstractScrollArea::minimumSizeHint() const int hsbExt = d->hbar->sizeHint().height(); int vsbExt = d->vbar->sizeHint().width(); int extra = 2 * d->frameWidth; + QStyleOption opt; + opt.initFrom(this); + if ((d->frameStyle != QFrame::NoFrame) + && style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, this)) { + extra += style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, this); + } return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra, d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra); } @@ -1295,6 +1347,27 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport) Q_UNUSED(viewport); } +#ifdef Q_WS_WIN +void QAbstractScrollAreaPrivate::_q_gestureTriggered() +{ + Q_Q(QAbstractScrollArea); + QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + QSizeF delta = g->lastOffset(); + if (!delta.isNull()) { + if (QApplication::isRightToLeft()) + delta.rwidth() *= -1; + int newX = hBar->value() - delta.width(); + int newY = vBar->value() - delta.height(); + hbar->setValue(newX); + vbar->setValue(newY); + } +} +#endif + QT_END_NAMESPACE #include "moc_qabstractscrollarea.cpp" |