aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates/qquickscrollindicator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates/qquickscrollindicator.cpp')
-rw-r--r--src/quicktemplates/qquickscrollindicator.cpp648
1 files changed, 648 insertions, 0 deletions
diff --git a/src/quicktemplates/qquickscrollindicator.cpp b/src/quicktemplates/qquickscrollindicator.cpp
new file mode 100644
index 0000000000..9928503e86
--- /dev/null
+++ b/src/quicktemplates/qquickscrollindicator.cpp
@@ -0,0 +1,648 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickscrollindicator_p.h"
+#include "qquickcontrol_p_p.h"
+
+#include <QtQml/qqmlinfo.h>
+#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuick/private/qquickitemchangelistener_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype ScrollIndicator
+ \inherits Control
+//! \instantiates QQuickScrollIndicator
+ \inqmlmodule QtQuick.Controls
+ \since 5.7
+ \ingroup qtquickcontrols-indicators
+ \brief Vertical or horizontal non-interactive scroll indicator.
+
+ \image qtquickcontrols-scrollindicator.gif
+
+ ScrollIndicator is a non-interactive indicator that indicates the current scroll
+ position. A scroll indicator can be either \l vertical or \l horizontal, and can
+ be attached to any \l Flickable, such as \l ListView and \l GridView.
+
+ \code
+ Flickable {
+ // ...
+ ScrollIndicator.vertical: ScrollIndicator { }
+ }
+ \endcode
+
+ \section1 Attaching ScrollIndicator to a Flickable
+
+ \note When ScrollIndicator is attached \l {ScrollIndicator::vertical}{vertically}
+ or \l {ScrollIndicator::horizontal}{horizontally} to a Flickable, its geometry and
+ the following properties are automatically set and updated as appropriate:
+
+ \list
+ \li \l orientation
+ \li \l position
+ \li \l size
+ \li \l active
+ \endlist
+
+ An attached ScrollIndicator re-parents itself to the target Flickable. A vertically
+ attached ScrollIndicator resizes itself to the height of the Flickable, and positions
+ itself to either side of it based on the \l {Control::mirrored}{layout direction}.
+ A horizontally attached ScrollIndicator resizes itself to the width of the Flickable,
+ and positions itself to the bottom. The automatic geometry management can be disabled
+ by specifying another parent for the attached ScrollIndicator. This can be useful, for
+ example, if the ScrollIndicator should be placed outside a clipping Flickable. This is
+ demonstrated by the following example:
+
+ \code
+ Flickable {
+ id: flickable
+ clip: true
+ // ...
+ ScrollIndicator.vertical: ScrollIndicator {
+ parent: flickable.parent
+ anchors.top: flickable.top
+ anchors.left: flickable.right
+ anchors.bottom: flickable.bottom
+ }
+ }
+ \endcode
+
+ \section1 Binding the Active State of Horizontal and Vertical Scroll Indicators
+
+ Horizontal and vertical scroll indicators do not share the \l active state with
+ each other by default. In order to keep both indicators visible whilst scrolling
+ to either direction, establish a two-way binding between the active states as
+ presented by the following example:
+
+ \snippet qtquickcontrols-scrollindicator-active.qml 1
+
+ \section1 Non-attached Scroll Indicators
+
+ It is possible to create an instance of ScrollIndicator without using the
+ attached property API. This is useful when the behavior of the attached
+ scoll indicator is not sufficient or a \l Flickable is not in use. In the
+ following example, horizontal and vertical scroll indicators are used to
+ indicate how far the user has scrolled over the text (using \l MouseArea
+ instead of \l Flickable):
+
+ \snippet qtquickcontrols-scrollindicator-non-attached.qml 1
+
+ \image qtquickcontrols-scrollindicator-non-attached.png
+
+ \sa ScrollBar, {Customizing ScrollIndicator}, {Indicator Controls}
+*/
+
+static const QQuickItemPrivate::ChangeTypes QsiChangeTypes = QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed;
+static const QQuickItemPrivate::ChangeTypes QsiHorizontalChangeTypes = QsiChangeTypes | QQuickItemPrivate::ImplicitHeight;
+static const QQuickItemPrivate::ChangeTypes QsiVerticalChangeTypes = QsiChangeTypes | QQuickItemPrivate::ImplicitWidth;
+
+class QQuickScrollIndicatorPrivate : public QQuickControlPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickScrollIndicator)
+
+public:
+ struct VisualArea
+ {
+ VisualArea(qreal pos, qreal sz)
+ : position(pos), size(sz) { }
+ qreal position = 0;
+ qreal size = 0;
+ };
+ VisualArea visualArea() const;
+ void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea);
+
+ void resizeContent() override;
+
+ qreal size = 0;
+ qreal minimumSize = 0;
+ qreal position = 0;
+ bool active = false;
+ Qt::Orientation orientation = Qt::Vertical;
+};
+
+QQuickScrollIndicatorPrivate::VisualArea QQuickScrollIndicatorPrivate::visualArea() const
+{
+ qreal visualPos = position;
+ if (minimumSize > size)
+ visualPos = position / (1.0 - size) * (1.0 - minimumSize);
+
+ qreal maximumSize = qMax<qreal>(0.0, 1.0 - visualPos);
+ qreal visualSize = qMax<qreal>(minimumSize,
+ qMin<qreal>(qMax(size, minimumSize) + qMin<qreal>(0, visualPos),
+ maximumSize));
+
+ visualPos = qMax<qreal>(0,qMin<qreal>(visualPos,qMax<qreal>(0, 1.0 - visualSize)));
+
+ return VisualArea(visualPos, visualSize);
+}
+
+void QQuickScrollIndicatorPrivate::visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea)
+{
+ Q_Q(QQuickScrollIndicator);
+ if (!qFuzzyCompare(newVisualArea.size, oldVisualArea.size))
+ emit q->visualSizeChanged();
+ if (!qFuzzyCompare(newVisualArea.position, oldVisualArea.position))
+ emit q->visualPositionChanged();
+}
+
+void QQuickScrollIndicatorPrivate::resizeContent()
+{
+ Q_Q(QQuickScrollIndicator);
+ if (!contentItem)
+ return;
+
+ // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size
+ // - positive overshoot (pos + size > 1): clamp the size to 1-pos
+ const VisualArea visual = visualArea();
+
+ if (orientation == Qt::Horizontal) {
+ contentItem->setPosition(QPointF(q->leftPadding() + visual.position * q->availableWidth(), q->topPadding()));
+ contentItem->setSize(QSizeF(q->availableWidth() * visual.size, q->availableHeight()));
+ } else {
+ contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + visual.position * q->availableHeight()));
+ contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * visual.size));
+ }
+}
+
+QQuickScrollIndicator::QQuickScrollIndicator(QQuickItem *parent)
+ : QQuickControl(*(new QQuickScrollIndicatorPrivate), parent)
+{
+ Q_D(QQuickScrollIndicator);
+ d->setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Fixed);
+}
+
+QQuickScrollIndicatorAttached *QQuickScrollIndicator::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickScrollIndicatorAttached(object);
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::ScrollIndicator::size
+
+ This property holds the size of the indicator, scaled to \c {0.0 - 1.0}.
+
+ \sa {Flickable::visibleArea.heightRatio}{Flickable::visibleArea}
+
+ This property is automatically set when the scroll indicator is
+ \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
+
+ \sa minimumSize, visualSize
+*/
+qreal QQuickScrollIndicator::size() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->size;
+}
+
+void QQuickScrollIndicator::setSize(qreal size)
+{
+ Q_D(QQuickScrollIndicator);
+ if (qFuzzyCompare(d->size, size))
+ return;
+
+ auto oldVisualArea = d->visualArea();
+ d->size = size;
+ if (d->size + d->position > 1.0) {
+ setPosition(1.0 - d->size);
+ oldVisualArea = d->visualArea();
+ }
+ if (isComponentComplete())
+ d->resizeContent();
+ emit sizeChanged();
+ d->visualAreaChange(d->visualArea(), oldVisualArea);
+}
+
+/*!
+ \qmlproperty real QtQuick.Controls::ScrollIndicator::position
+
+ This property holds the position of the indicator, scaled to \c {0.0 - 1.0}.
+
+ This property is automatically set when the scroll indicator is
+ \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
+
+ \sa {Flickable::visibleArea.yPosition}{Flickable::visibleArea}, visualPosition
+*/
+qreal QQuickScrollIndicator::position() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->position;
+}
+
+void QQuickScrollIndicator::setPosition(qreal position)
+{
+ Q_D(QQuickScrollIndicator);
+ if (qFuzzyCompare(d->position, position))
+ return;
+
+ auto oldVisualArea = d->visualArea();
+ d->position = position;
+ if (isComponentComplete())
+ d->resizeContent();
+ emit positionChanged();
+ d->visualAreaChange(d->visualArea(), oldVisualArea);
+}
+
+/*!
+ \qmlproperty bool QtQuick.Controls::ScrollIndicator::active
+
+ This property holds whether the indicator is active, that is, when the
+ attached Flickable is \l {Flickable::moving}{moving}.
+
+ It is possible to keep \l {Binding the Active State of Horizontal and Vertical Scroll Indicators}
+ {both horizontal and vertical indicators visible} while scrolling in either direction.
+
+ This property is automatically set when the scroll indicator is
+ \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
+*/
+bool QQuickScrollIndicator::isActive() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->active;
+}
+
+void QQuickScrollIndicator::setActive(bool active)
+{
+ Q_D(QQuickScrollIndicator);
+ if (d->active == active)
+ return;
+
+ d->active = active;
+ emit activeChanged();
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Controls::ScrollIndicator::orientation
+
+ This property holds the orientation of the indicator.
+
+ Possible values:
+ \value Qt.Horizontal Horizontal
+ \value Qt.Vertical Vertical (default)
+
+ This property is automatically set when the scroll indicator is
+ \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
+
+ \sa horizontal, vertical
+*/
+Qt::Orientation QQuickScrollIndicator::orientation() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->orientation;
+}
+
+void QQuickScrollIndicator::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QQuickScrollIndicator);
+ if (d->orientation == orientation)
+ return;
+
+ if (orientation == Qt::Horizontal)
+ d->setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Fixed);
+ else
+ d->setSizePolicy(QLayoutPolicy::Fixed, QLayoutPolicy::Preferred);
+
+ d->orientation = orientation;
+ if (isComponentComplete())
+ d->resizeContent();
+ emit orientationChanged();
+}
+
+/*!
+ \since QtQuick.Controls 2.3 (Qt 5.10)
+ \qmlproperty bool QtQuick.Controls::ScrollIndicator::horizontal
+ \readonly
+
+ This property holds whether the scroll indicator is horizontal.
+
+ \sa orientation
+*/
+bool QQuickScrollIndicator::isHorizontal() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->orientation == Qt::Horizontal;
+}
+
+/*!
+ \since QtQuick.Controls 2.3 (Qt 5.10)
+ \qmlproperty bool QtQuick.Controls::ScrollIndicator::vertical
+ \readonly
+
+ This property holds whether the scroll indicator is vertical.
+
+ \sa orientation
+*/
+bool QQuickScrollIndicator::isVertical() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->orientation == Qt::Vertical;
+}
+
+/*!
+ \since QtQuick.Controls 2.4 (Qt 5.11)
+ \qmlproperty real QtQuick.Controls::ScrollIndicator::minimumSize
+
+ This property holds the minimum size of the indicator, scaled to \c {0.0 - 1.0}.
+
+ \sa size, visualSize, visualPosition
+*/
+qreal QQuickScrollIndicator::minimumSize() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->minimumSize;
+}
+
+void QQuickScrollIndicator::setMinimumSize(qreal minimumSize)
+{
+ Q_D(QQuickScrollIndicator);
+ if (qFuzzyCompare(d->minimumSize, minimumSize))
+ return;
+
+ auto oldVisualArea = d->visualArea();
+ d->minimumSize = minimumSize;
+ if (isComponentComplete())
+ d->resizeContent();
+ emit minimumSizeChanged();
+ d->visualAreaChange(d->visualArea(), oldVisualArea);
+}
+
+/*!
+ \since QtQuick.Controls 2.4 (Qt 5.11)
+ \qmlproperty real QtQuick.Controls::ScrollIndicator::visualSize
+
+ This property holds the effective visual size of the indicator,
+ which may be limited by the \l {minimumSize}{minimum size}.
+
+ \sa size, minimumSize
+*/
+qreal QQuickScrollIndicator::visualSize() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->visualArea().size;
+}
+
+/*!
+ \since QtQuick.Controls 2.4 (Qt 5.11)
+ \qmlproperty real QtQuick.Controls::ScrollIndicator::visualPosition
+
+ This property holds the effective visual position of the indicator,
+ which may be limited by the \l {minimumSize}{minimum size}.
+
+ \sa position, minimumSize
+*/
+qreal QQuickScrollIndicator::visualPosition() const
+{
+ Q_D(const QQuickScrollIndicator);
+ return d->visualArea().position;
+}
+
+class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+{
+public:
+ void activateHorizontal();
+ void activateVertical();
+
+ void layoutHorizontal(bool move = true);
+ void layoutVertical(bool move = true);
+
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
+ void itemDestroyed(QQuickItem *item) override;
+
+ QQuickFlickable *flickable = nullptr;
+ QQuickScrollIndicator *horizontal = nullptr;
+ QQuickScrollIndicator *vertical = nullptr;
+};
+
+void QQuickScrollIndicatorAttachedPrivate::activateHorizontal()
+{
+ horizontal->setActive(flickable->isMovingHorizontally());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::activateVertical()
+{
+ vertical->setActive(flickable->isMovingVertically());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move)
+{
+ Q_ASSERT(horizontal && flickable);
+ if (horizontal->parentItem() != flickable)
+ return;
+ horizontal->setWidth(flickable->width());
+ if (move)
+ horizontal->setY(flickable->height() - horizontal->height());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move)
+{
+ Q_ASSERT(vertical && flickable);
+ if (vertical->parentItem() != flickable)
+ return;
+ vertical->setHeight(flickable->height());
+ if (move && !QQuickItemPrivate::get(vertical)->isMirrored())
+ vertical->setX(flickable->width() - vertical->width());
+}
+
+void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
+{
+ Q_UNUSED(item);
+ Q_UNUSED(change);
+ if (horizontal && horizontal->height() > 0) {
+#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
+ bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), diff.height() - horizontal->height());
+#else
+ bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height());
+#endif
+ layoutHorizontal(move);
+ }
+ if (vertical && vertical->width() > 0) {
+#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
+ bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), diff.width() - vertical->width());
+#else
+ bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width());
+#endif
+ layoutVertical(move);
+ }
+}
+
+void QQuickScrollIndicatorAttachedPrivate::itemImplicitWidthChanged(QQuickItem *item)
+{
+ if (item == vertical)
+ layoutVertical(true);
+}
+
+void QQuickScrollIndicatorAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item)
+{
+ if (item == horizontal)
+ layoutHorizontal(true);
+}
+
+void QQuickScrollIndicatorAttachedPrivate::itemDestroyed(QQuickItem *item)
+{
+ if (item == horizontal)
+ horizontal = nullptr;
+ if (item == vertical)
+ vertical = nullptr;
+}
+
+QQuickScrollIndicatorAttached::QQuickScrollIndicatorAttached(QObject *parent)
+ : QObject(*(new QQuickScrollIndicatorAttachedPrivate), parent)
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ d->flickable = qobject_cast<QQuickFlickable *>(parent);
+ if (d->flickable)
+ QQuickItemPrivate::get(d->flickable)->updateOrAddGeometryChangeListener(d, QQuickGeometryChange::Size);
+ else if (parent)
+ qmlWarning(parent) << "ScrollIndicator must be attached to a Flickable";
+}
+
+QQuickScrollIndicatorAttached::~QQuickScrollIndicatorAttached()
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ if (d->flickable) {
+ if (d->horizontal)
+ QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QsiHorizontalChangeTypes);
+ if (d->vertical)
+ QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QsiVerticalChangeTypes);
+ // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size).
+ // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling
+ // pointer on destruction.
+ QQuickItemPrivate::get(d->flickable)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+ }
+}
+
+/*!
+ \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::horizontal
+
+ This property attaches a horizontal scroll indicator to a \l Flickable.
+
+ \code
+ Flickable {
+ contentWidth: 2000
+ ScrollIndicator.horizontal: ScrollIndicator { }
+ }
+ \endcode
+
+ \sa {Attaching ScrollIndicator to a Flickable}
+*/
+QQuickScrollIndicator *QQuickScrollIndicatorAttached::horizontal() const
+{
+ Q_D(const QQuickScrollIndicatorAttached);
+ return d->horizontal;
+}
+
+void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizontal)
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ if (d->horizontal == horizontal)
+ return;
+
+ if (d->horizontal && d->flickable) {
+ QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QsiHorizontalChangeTypes);
+ QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ disconnect(area, SIGNAL(widthRatioChanged(qreal)), d->horizontal, SLOT(setSize(qreal)));
+ disconnect(area, SIGNAL(xPositionChanged(qreal)), d->horizontal, SLOT(setPosition(qreal)));
+ }
+
+ d->horizontal = horizontal;
+
+ if (horizontal && d->flickable) {
+ if (!horizontal->parentItem())
+ horizontal->setParentItem(d->flickable);
+ horizontal->setOrientation(Qt::Horizontal);
+
+ QQuickItemPrivate::get(horizontal)->addItemChangeListener(d, QsiHorizontalChangeTypes);
+ QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
+ connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
+
+ d->layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+ }
+ emit horizontalChanged();
+}
+
+/*!
+ \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::vertical
+
+ This property attaches a vertical scroll indicator to a \l Flickable.
+
+ \code
+ Flickable {
+ contentHeight: 2000
+ ScrollIndicator.vertical: ScrollIndicator { }
+ }
+ \endcode
+
+ \sa {Attaching ScrollIndicator to a Flickable}
+*/
+QQuickScrollIndicator *QQuickScrollIndicatorAttached::vertical() const
+{
+ Q_D(const QQuickScrollIndicatorAttached);
+ return d->vertical;
+}
+
+void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical)
+{
+ Q_D(QQuickScrollIndicatorAttached);
+ if (d->vertical == vertical)
+ return;
+
+ if (d->vertical && d->flickable) {
+ QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QsiVerticalChangeTypes);
+ QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ disconnect(area, SIGNAL(heightRatioChanged(qreal)), d->vertical, SLOT(setSize(qreal)));
+ disconnect(area, SIGNAL(yPositionChanged(qreal)), d->vertical, SLOT(setPosition(qreal)));
+ }
+
+ d->vertical = vertical;
+
+ if (vertical && d->flickable) {
+ if (!vertical->parentItem())
+ vertical->setParentItem(d->flickable);
+ vertical->setOrientation(Qt::Vertical);
+
+ QQuickItemPrivate::get(vertical)->addItemChangeListener(d, QsiVerticalChangeTypes);
+ QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical);
+
+ // TODO: export QQuickFlickableVisibleArea
+ QObject *area = d->flickable->property("visibleArea").value<QObject *>();
+ connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
+ connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
+
+ d->layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+ }
+ emit verticalChanged();
+}
+
+#if QT_CONFIG(quicktemplates2_multitouch)
+void QQuickScrollIndicator::touchEvent(QTouchEvent *event)
+{
+ event->ignore(); // QTBUG-61785
+}
+#endif
+
+#if QT_CONFIG(accessibility)
+QAccessible::Role QQuickScrollIndicator::accessibleRole() const
+{
+ return QAccessible::Indicator;
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qquickscrollindicator_p.cpp"