aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickscrollbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2/qquickscrollbar.cpp')
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp118
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()