diff options
Diffstat (limited to 'src/quicktemplates2/qquickscrollbar.cpp')
-rw-r--r-- | src/quicktemplates2/qquickscrollbar.cpp | 118 |
1 files changed, 106 insertions, 12 deletions
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index c17b3be6..e8c523f2 100644 --- a/src/quicktemplates2/qquickscrollbar.cpp +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -158,7 +158,7 @@ class QQuickScrollBarPrivate : public QQuickControlPrivate public: QQuickScrollBarPrivate() : size(0), position(0), stepSize(0), offset(0), active(false), pressed(false), moving(false), - orientation(Qt::Vertical) + orientation(Qt::Vertical), snapMode(QQuickScrollBar::NoSnap) { } @@ -167,10 +167,16 @@ public: return bar->d_func(); } - qreal positionAt(const QPoint &point) const; + qreal snapPosition(qreal position) const; + qreal positionAt(const QPointF &point) const; void updateActive(); void resizeContent() override; + void handlePress(const QPointF &point); + void handleMove(const QPointF &point); + void handleRelease(const QPointF &point); + void handleUngrab(); + qreal size; qreal position; qreal stepSize; @@ -179,9 +185,19 @@ public: bool pressed; bool moving; Qt::Orientation orientation; + QQuickScrollBar::SnapMode snapMode; }; -qreal QQuickScrollBarPrivate::positionAt(const QPoint &point) const +qreal QQuickScrollBarPrivate::snapPosition(qreal position) const +{ + const qreal effectiveStep = stepSize * (1.0 - size); + if (qFuzzyIsNull(effectiveStep)) + return position; + + return qRound(position / effectiveStep) * effectiveStep; +} + +qreal QQuickScrollBarPrivate::positionAt(const QPointF &point) const { Q_Q(const QQuickScrollBar); if (orientation == Qt::Horizontal) @@ -211,6 +227,42 @@ void QQuickScrollBarPrivate::resizeContent() } } +void QQuickScrollBarPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickScrollBar); + offset = positionAt(point) - position; + if (offset < 0 || offset > size) + offset = size / 2; + q->setPressed(true); +} + +void QQuickScrollBarPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickScrollBar); + qreal pos = qBound<qreal>(0.0, positionAt(point) - offset, 1.0 - size); + if (snapMode == QQuickScrollBar::SnapAlways) + pos = snapPosition(pos); + q->setPosition(pos); +} + +void QQuickScrollBarPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickScrollBar); + qreal pos = qBound<qreal>(0.0, positionAt(point) - offset, 1.0 - size); + if (snapMode != QQuickScrollBar::NoSnap) + pos = snapPosition(pos); + q->setPosition(pos); + offset = 0.0; + q->setPressed(false); +} + +void QQuickScrollBarPrivate::handleUngrab() +{ + Q_Q(QQuickScrollBar); + offset = 0.0; + q->setPressed(false); +} + QQuickScrollBar::QQuickScrollBar(QQuickItem *parent) : QQuickControl(*(new QQuickScrollBarPrivate), parent) { @@ -290,7 +342,7 @@ void QQuickScrollBar::setPosition(qreal position) This property holds the step size. The default value is \c 0.0. - \sa increase(), decrease() + \sa snapMode, increase(), decrease() */ qreal QQuickScrollBar::stepSize() const { @@ -390,6 +442,46 @@ void QQuickScrollBar::setOrientation(Qt::Orientation orientation) } /*! + \since QtQuick.Controls 2.2 + \qmlproperty enumeration QtQuick.Controls::ScrollBar::snapMode + + This property holds the snap mode. + + Possible values: + \value ScrollBar.NoSnap The scrollbar does not snap (default). + \value ScrollBar.SnapAlways The scrollbar snaps while dragged. + \value ScrollBar.SnapOnRelease The scrollbar does not snap while being dragged, but only after released. + + In the following table, the various modes are illustrated with animations. + The movement and the \l stepSize (\c 0.25) are identical in each animation. + + \table + \header + \row \li \b Value \li \b Example + \row \li \c ScrollBar.NoSnap \li \image qtquickcontrols2-scrollbar-nosnap.gif + \row \li \c ScrollBar.SnapAlways \li \image qtquickcontrols2-scrollbar-snapalways.gif + \row \li \c ScrollBar.SnapOnRelease \li \image qtquickcontrols2-scrollbar-snaponrelease.gif + \endtable + + \sa stepSize +*/ +QQuickScrollBar::SnapMode QQuickScrollBar::snapMode() const +{ + Q_D(const QQuickScrollBar); + return d->snapMode; +} + +void QQuickScrollBar::setSnapMode(SnapMode mode) +{ + Q_D(QQuickScrollBar); + if (d->snapMode == mode) + return; + + d->snapMode = mode; + emit snapModeChanged(); +} + +/*! \qmlmethod void QtQuick.Controls::ScrollBar::increase() Increases the position by \l stepSize or \c 0.1 if stepSize is \c 0.0. @@ -427,26 +519,28 @@ void QQuickScrollBar::mousePressEvent(QMouseEvent *event) { Q_D(QQuickScrollBar); QQuickControl::mousePressEvent(event); - d->offset = d->positionAt(event->pos()) - d->position; - if (d->offset < 0 || d->offset > d->size) - d->offset = d->size / 2; - setPressed(true); + d->handlePress(event->localPos()); } void QQuickScrollBar::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickScrollBar); QQuickControl::mouseMoveEvent(event); - setPosition(qBound<qreal>(0.0, d->positionAt(event->pos()) - d->offset, 1.0 - d->size)); + d->handleMove(event->localPos()); } void QQuickScrollBar::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickScrollBar); QQuickControl::mouseReleaseEvent(event); - setPosition(qBound<qreal>(0.0, d->positionAt(event->pos()) - d->offset, 1.0 - d->size)); - d->offset = 0.0; - setPressed(false); + d->handleRelease(event->localPos()); +} + +void QQuickScrollBar::mouseUngrabEvent() +{ + Q_D(QQuickScrollBar); + QQuickControl::mouseUngrabEvent(); + d->handleUngrab(); } void QQuickScrollBar::hoverChange() |