1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquickscrollindicator_p.h"
5#include "qquickcontrol_p_p.h"
6
7#include <QtQml/qqmlinfo.h>
8#include <QtQuick/private/qquickflickable_p.h>
9#include <QtQuick/private/qquickitemchangelistener_p.h>
10
11QT_BEGIN_NAMESPACE
12
13/*!
14 \qmltype ScrollIndicator
15 \inherits Control
16//! \instantiates QQuickScrollIndicator
17 \inqmlmodule QtQuick.Controls
18 \since 5.7
19 \ingroup qtquickcontrols-indicators
20 \brief Vertical or horizontal non-interactive scroll indicator.
21
22 \image qtquickcontrols-scrollindicator.gif
23
24 ScrollIndicator is a non-interactive indicator that indicates the current scroll
25 position. A scroll indicator can be either \l vertical or \l horizontal, and can
26 be attached to any \l Flickable, such as \l ListView and \l GridView.
27
28 \code
29 Flickable {
30 // ...
31 ScrollIndicator.vertical: ScrollIndicator { }
32 }
33 \endcode
34
35 \section1 Attaching ScrollIndicator to a Flickable
36
37 \note When ScrollIndicator is attached \l {ScrollIndicator::vertical}{vertically}
38 or \l {ScrollIndicator::horizontal}{horizontally} to a Flickable, its geometry and
39 the following properties are automatically set and updated as appropriate:
40
41 \list
42 \li \l orientation
43 \li \l position
44 \li \l size
45 \li \l active
46 \endlist
47
48 An attached ScrollIndicator re-parents itself to the target Flickable. A vertically
49 attached ScrollIndicator resizes itself to the height of the Flickable, and positions
50 itself to either side of it based on the \l {Control::mirrored}{layout direction}.
51 A horizontally attached ScrollIndicator resizes itself to the width of the Flickable,
52 and positions itself to the bottom. The automatic geometry management can be disabled
53 by specifying another parent for the attached ScrollIndicator. This can be useful, for
54 example, if the ScrollIndicator should be placed outside a clipping Flickable. This is
55 demonstrated by the following example:
56
57 \code
58 Flickable {
59 id: flickable
60 clip: true
61 // ...
62 ScrollIndicator.vertical: ScrollIndicator {
63 parent: flickable.parent
64 anchors.top: flickable.top
65 anchors.left: flickable.right
66 anchors.bottom: flickable.bottom
67 }
68 }
69 \endcode
70
71 \section1 Binding the Active State of Horizontal and Vertical Scroll Indicators
72
73 Horizontal and vertical scroll indicators do not share the \l active state with
74 each other by default. In order to keep both indicators visible whilst scrolling
75 to either direction, establish a two-way binding between the active states as
76 presented by the following example:
77
78 \snippet qtquickcontrols-scrollindicator-active.qml 1
79
80 \section1 Non-attached Scroll Indicators
81
82 It is possible to create an instance of ScrollIndicator without using the
83 attached property API. This is useful when the behavior of the attached
84 scoll indicator is not sufficient or a \l Flickable is not in use. In the
85 following example, horizontal and vertical scroll indicators are used to
86 indicate how far the user has scrolled over the text (using \l MouseArea
87 instead of \l Flickable):
88
89 \snippet qtquickcontrols-scrollindicator-non-attached.qml 1
90
91 \image qtquickcontrols-scrollindicator-non-attached.png
92
93 \sa ScrollBar, {Customizing ScrollIndicator}, {Indicator Controls}
94*/
95
96static const QQuickItemPrivate::ChangeTypes QsiChangeTypes = QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed;
97static const QQuickItemPrivate::ChangeTypes QsiHorizontalChangeTypes = QsiChangeTypes | QQuickItemPrivate::ImplicitHeight;
98static const QQuickItemPrivate::ChangeTypes QsiVerticalChangeTypes = QsiChangeTypes | QQuickItemPrivate::ImplicitWidth;
99
100class QQuickScrollIndicatorPrivate : public QQuickControlPrivate
101{
102 Q_DECLARE_PUBLIC(QQuickScrollIndicator)
103
104public:
105 struct VisualArea
106 {
107 VisualArea(qreal pos, qreal sz)
108 : position(pos), size(sz) { }
109 qreal position = 0;
110 qreal size = 0;
111 };
112 VisualArea visualArea() const;
113 void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea);
114
115 void resizeContent() override;
116
117 qreal size = 0;
118 qreal minimumSize = 0;
119 qreal position = 0;
120 bool active = false;
121 Qt::Orientation orientation = Qt::Vertical;
122};
123
124QQuickScrollIndicatorPrivate::VisualArea QQuickScrollIndicatorPrivate::visualArea() const
125{
126 qreal visualPos = position;
127 if (minimumSize > size)
128 visualPos = position / (1.0 - size) * (1.0 - minimumSize);
129
130 qreal maximumSize = qMax<qreal>(a: 0.0, b: 1.0 - visualPos);
131 qreal visualSize = qMax<qreal>(a: minimumSize,
132 b: qMin<qreal>(a: qMax(a: size, b: minimumSize) + qMin<qreal>(a: 0, b: visualPos),
133 b: maximumSize));
134
135 visualPos = qMax<qreal>(a: 0,b: qMin<qreal>(a: visualPos,b: qMax<qreal>(a: 0, b: 1.0 - visualSize)));
136
137 return VisualArea(visualPos, visualSize);
138}
139
140void QQuickScrollIndicatorPrivate::visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea)
141{
142 Q_Q(QQuickScrollIndicator);
143 if (!qFuzzyCompare(p1: newVisualArea.size, p2: oldVisualArea.size))
144 emit q->visualSizeChanged();
145 if (!qFuzzyCompare(p1: newVisualArea.position, p2: oldVisualArea.position))
146 emit q->visualPositionChanged();
147}
148
149void QQuickScrollIndicatorPrivate::resizeContent()
150{
151 Q_Q(QQuickScrollIndicator);
152 if (!contentItem)
153 return;
154
155 // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size
156 // - positive overshoot (pos + size > 1): clamp the size to 1-pos
157 const VisualArea visual = visualArea();
158
159 if (orientation == Qt::Horizontal) {
160 contentItem->setPosition(QPointF(q->leftPadding() + visual.position * q->availableWidth(), q->topPadding()));
161 contentItem->setSize(QSizeF(q->availableWidth() * visual.size, q->availableHeight()));
162 } else {
163 contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + visual.position * q->availableHeight()));
164 contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * visual.size));
165 }
166}
167
168QQuickScrollIndicator::QQuickScrollIndicator(QQuickItem *parent)
169 : QQuickControl(*(new QQuickScrollIndicatorPrivate), parent)
170{
171}
172
173QQuickScrollIndicatorAttached *QQuickScrollIndicator::qmlAttachedProperties(QObject *object)
174{
175 return new QQuickScrollIndicatorAttached(object);
176}
177
178/*!
179 \qmlproperty real QtQuick.Controls::ScrollIndicator::size
180
181 This property holds the size of the indicator, scaled to \c {0.0 - 1.0}.
182
183 \sa {Flickable::visibleArea.heightRatio}{Flickable::visibleArea}
184
185 This property is automatically set when the scroll indicator is
186 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
187
188 \sa minimumSize, visualSize
189*/
190qreal QQuickScrollIndicator::size() const
191{
192 Q_D(const QQuickScrollIndicator);
193 return d->size;
194}
195
196void QQuickScrollIndicator::setSize(qreal size)
197{
198 Q_D(QQuickScrollIndicator);
199 if (qFuzzyCompare(p1: d->size, p2: size))
200 return;
201
202 auto oldVisualArea = d->visualArea();
203 d->size = size;
204 if (d->size + d->position > 1.0) {
205 setPosition(1.0 - d->size);
206 oldVisualArea = d->visualArea();
207 }
208 if (isComponentComplete())
209 d->resizeContent();
210 emit sizeChanged();
211 d->visualAreaChange(newVisualArea: d->visualArea(), oldVisualArea);
212}
213
214/*!
215 \qmlproperty real QtQuick.Controls::ScrollIndicator::position
216
217 This property holds the position of the indicator, scaled to \c {0.0 - 1.0}.
218
219 This property is automatically set when the scroll indicator is
220 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
221
222 \sa {Flickable::visibleArea.yPosition}{Flickable::visibleArea}, visualPosition
223*/
224qreal QQuickScrollIndicator::position() const
225{
226 Q_D(const QQuickScrollIndicator);
227 return d->position;
228}
229
230void QQuickScrollIndicator::setPosition(qreal position)
231{
232 Q_D(QQuickScrollIndicator);
233 if (qFuzzyCompare(p1: d->position, p2: position))
234 return;
235
236 auto oldVisualArea = d->visualArea();
237 d->position = position;
238 if (isComponentComplete())
239 d->resizeContent();
240 emit positionChanged();
241 d->visualAreaChange(newVisualArea: d->visualArea(), oldVisualArea);
242}
243
244/*!
245 \qmlproperty bool QtQuick.Controls::ScrollIndicator::active
246
247 This property holds whether the indicator is active, that is, when the
248 attached Flickable is \l {Flickable::moving}{moving}.
249
250 It is possible to keep \l {Binding the Active State of Horizontal and Vertical Scroll Indicators}
251 {both horizontal and vertical indicators visible} while scrolling in either direction.
252
253 This property is automatically set when the scroll indicator is
254 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
255*/
256bool QQuickScrollIndicator::isActive() const
257{
258 Q_D(const QQuickScrollIndicator);
259 return d->active;
260}
261
262void QQuickScrollIndicator::setActive(bool active)
263{
264 Q_D(QQuickScrollIndicator);
265 if (d->active == active)
266 return;
267
268 d->active = active;
269 emit activeChanged();
270}
271
272/*!
273 \qmlproperty enumeration QtQuick.Controls::ScrollIndicator::orientation
274
275 This property holds the orientation of the indicator.
276
277 Possible values:
278 \value Qt.Horizontal Horizontal
279 \value Qt.Vertical Vertical (default)
280
281 This property is automatically set when the scroll indicator is
282 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
283
284 \sa horizontal, vertical
285*/
286Qt::Orientation QQuickScrollIndicator::orientation() const
287{
288 Q_D(const QQuickScrollIndicator);
289 return d->orientation;
290}
291
292void QQuickScrollIndicator::setOrientation(Qt::Orientation orientation)
293{
294 Q_D(QQuickScrollIndicator);
295 if (d->orientation == orientation)
296 return;
297
298 d->orientation = orientation;
299 if (isComponentComplete())
300 d->resizeContent();
301 emit orientationChanged();
302}
303
304/*!
305 \since QtQuick.Controls 2.3 (Qt 5.10)
306 \qmlproperty bool QtQuick.Controls::ScrollIndicator::horizontal
307 \readonly
308
309 This property holds whether the scroll indicator is horizontal.
310
311 \sa orientation
312*/
313bool QQuickScrollIndicator::isHorizontal() const
314{
315 Q_D(const QQuickScrollIndicator);
316 return d->orientation == Qt::Horizontal;
317}
318
319/*!
320 \since QtQuick.Controls 2.3 (Qt 5.10)
321 \qmlproperty bool QtQuick.Controls::ScrollIndicator::vertical
322 \readonly
323
324 This property holds whether the scroll indicator is vertical.
325
326 \sa orientation
327*/
328bool QQuickScrollIndicator::isVertical() const
329{
330 Q_D(const QQuickScrollIndicator);
331 return d->orientation == Qt::Vertical;
332}
333
334/*!
335 \since QtQuick.Controls 2.4 (Qt 5.11)
336 \qmlproperty real QtQuick.Controls::ScrollIndicator::minimumSize
337
338 This property holds the minimum size of the indicator, scaled to \c {0.0 - 1.0}.
339
340 \sa size, visualSize, visualPosition
341*/
342qreal QQuickScrollIndicator::minimumSize() const
343{
344 Q_D(const QQuickScrollIndicator);
345 return d->minimumSize;
346}
347
348void QQuickScrollIndicator::setMinimumSize(qreal minimumSize)
349{
350 Q_D(QQuickScrollIndicator);
351 if (qFuzzyCompare(p1: d->minimumSize, p2: minimumSize))
352 return;
353
354 auto oldVisualArea = d->visualArea();
355 d->minimumSize = minimumSize;
356 if (isComponentComplete())
357 d->resizeContent();
358 emit minimumSizeChanged();
359 d->visualAreaChange(newVisualArea: d->visualArea(), oldVisualArea);
360}
361
362/*!
363 \since QtQuick.Controls 2.4 (Qt 5.11)
364 \qmlproperty real QtQuick.Controls::ScrollIndicator::visualSize
365
366 This property holds the effective visual size of the indicator,
367 which may be limited by the \l {minimumSize}{minimum size}.
368
369 \sa size, minimumSize
370*/
371qreal QQuickScrollIndicator::visualSize() const
372{
373 Q_D(const QQuickScrollIndicator);
374 return d->visualArea().size;
375}
376
377/*!
378 \since QtQuick.Controls 2.4 (Qt 5.11)
379 \qmlproperty real QtQuick.Controls::ScrollIndicator::visualPosition
380
381 This property holds the effective visual position of the indicator,
382 which may be limited by the \l {minimumSize}{minimum size}.
383
384 \sa position, minimumSize
385*/
386qreal QQuickScrollIndicator::visualPosition() const
387{
388 Q_D(const QQuickScrollIndicator);
389 return d->visualArea().position;
390}
391
392class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
393{
394public:
395 void activateHorizontal();
396 void activateVertical();
397
398 void layoutHorizontal(bool move = true);
399 void layoutVertical(bool move = true);
400
401 void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
402 void itemImplicitWidthChanged(QQuickItem *item) override;
403 void itemImplicitHeightChanged(QQuickItem *item) override;
404 void itemDestroyed(QQuickItem *item) override;
405
406 QQuickFlickable *flickable = nullptr;
407 QQuickScrollIndicator *horizontal = nullptr;
408 QQuickScrollIndicator *vertical = nullptr;
409};
410
411void QQuickScrollIndicatorAttachedPrivate::activateHorizontal()
412{
413 horizontal->setActive(flickable->isMovingHorizontally());
414}
415
416void QQuickScrollIndicatorAttachedPrivate::activateVertical()
417{
418 vertical->setActive(flickable->isMovingVertically());
419}
420
421void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move)
422{
423 Q_ASSERT(horizontal && flickable);
424 if (horizontal->parentItem() != flickable)
425 return;
426 horizontal->setWidth(flickable->width());
427 if (move)
428 horizontal->setY(flickable->height() - horizontal->height());
429}
430
431void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move)
432{
433 Q_ASSERT(vertical && flickable);
434 if (vertical->parentItem() != flickable)
435 return;
436 vertical->setHeight(flickable->height());
437 if (move && !QQuickItemPrivate::get(item: vertical)->isMirrored())
438 vertical->setX(flickable->width() - vertical->width());
439}
440
441void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
442{
443 Q_UNUSED(item);
444 Q_UNUSED(change);
445 if (horizontal && horizontal->height() > 0) {
446#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
447 bool move = qFuzzyIsNull(d: horizontal->y()) || qFuzzyCompare(p1: horizontal->y(), p2: diff.height() - horizontal->height());
448#else
449 bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height());
450#endif
451 layoutHorizontal(move);
452 }
453 if (vertical && vertical->width() > 0) {
454#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
455 bool move = qFuzzyIsNull(d: vertical->x()) || qFuzzyCompare(p1: vertical->x(), p2: diff.width() - vertical->width());
456#else
457 bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width());
458#endif
459 layoutVertical(move);
460 }
461}
462
463void QQuickScrollIndicatorAttachedPrivate::itemImplicitWidthChanged(QQuickItem *item)
464{
465 if (item == vertical)
466 layoutVertical(move: true);
467}
468
469void QQuickScrollIndicatorAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item)
470{
471 if (item == horizontal)
472 layoutHorizontal(move: true);
473}
474
475void QQuickScrollIndicatorAttachedPrivate::itemDestroyed(QQuickItem *item)
476{
477 if (item == horizontal)
478 horizontal = nullptr;
479 if (item == vertical)
480 vertical = nullptr;
481}
482
483QQuickScrollIndicatorAttached::QQuickScrollIndicatorAttached(QObject *parent)
484 : QObject(*(new QQuickScrollIndicatorAttachedPrivate), parent)
485{
486 Q_D(QQuickScrollIndicatorAttached);
487 d->flickable = qobject_cast<QQuickFlickable *>(object: parent);
488 if (d->flickable)
489 QQuickItemPrivate::get(item: d->flickable)->updateOrAddGeometryChangeListener(listener: d, types: QQuickGeometryChange::Size);
490 else if (parent)
491 qmlWarning(me: parent) << "ScrollIndicator must be attached to a Flickable";
492}
493
494QQuickScrollIndicatorAttached::~QQuickScrollIndicatorAttached()
495{
496 Q_D(QQuickScrollIndicatorAttached);
497 if (d->flickable) {
498 if (d->horizontal)
499 QQuickItemPrivate::get(item: d->horizontal)->removeItemChangeListener(d, types: QsiHorizontalChangeTypes);
500 if (d->vertical)
501 QQuickItemPrivate::get(item: d->vertical)->removeItemChangeListener(d, types: QsiVerticalChangeTypes);
502 // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size).
503 // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling
504 // pointer on destruction.
505 QQuickItemPrivate::get(item: d->flickable)->removeItemChangeListener(d, types: QQuickItemPrivate::Geometry);
506 }
507}
508
509/*!
510 \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::horizontal
511
512 This property attaches a horizontal scroll indicator to a \l Flickable.
513
514 \code
515 Flickable {
516 contentWidth: 2000
517 ScrollIndicator.horizontal: ScrollIndicator { }
518 }
519 \endcode
520
521 \sa {Attaching ScrollIndicator to a Flickable}
522*/
523QQuickScrollIndicator *QQuickScrollIndicatorAttached::horizontal() const
524{
525 Q_D(const QQuickScrollIndicatorAttached);
526 return d->horizontal;
527}
528
529void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizontal)
530{
531 Q_D(QQuickScrollIndicatorAttached);
532 if (d->horizontal == horizontal)
533 return;
534
535 if (d->horizontal && d->flickable) {
536 QQuickItemPrivate::get(item: d->horizontal)->removeItemChangeListener(d, types: QsiHorizontalChangeTypes);
537 QObjectPrivate::disconnect(sender: d->flickable, signal: &QQuickFlickable::movingHorizontallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
538
539 // TODO: export QQuickFlickableVisibleArea
540 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
541 disconnect(sender: area, SIGNAL(widthRatioChanged(qreal)), receiver: d->horizontal, SLOT(setSize(qreal)));
542 disconnect(sender: area, SIGNAL(xPositionChanged(qreal)), receiver: d->horizontal, SLOT(setPosition(qreal)));
543 }
544
545 d->horizontal = horizontal;
546
547 if (horizontal && d->flickable) {
548 if (!horizontal->parentItem())
549 horizontal->setParentItem(d->flickable);
550 horizontal->setOrientation(Qt::Horizontal);
551
552 QQuickItemPrivate::get(item: horizontal)->addItemChangeListener(listener: d, types: QsiHorizontalChangeTypes);
553 QObjectPrivate::connect(sender: d->flickable, signal: &QQuickFlickable::movingHorizontallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
554
555 // TODO: export QQuickFlickableVisibleArea
556 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
557 connect(sender: area, SIGNAL(widthRatioChanged(qreal)), receiver: horizontal, SLOT(setSize(qreal)));
558 connect(sender: area, SIGNAL(xPositionChanged(qreal)), receiver: horizontal, SLOT(setPosition(qreal)));
559
560 d->layoutHorizontal();
561 horizontal->setSize(area->property(name: "widthRatio").toReal());
562 horizontal->setPosition(area->property(name: "xPosition").toReal());
563 }
564 emit horizontalChanged();
565}
566
567/*!
568 \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::vertical
569
570 This property attaches a vertical scroll indicator to a \l Flickable.
571
572 \code
573 Flickable {
574 contentHeight: 2000
575 ScrollIndicator.vertical: ScrollIndicator { }
576 }
577 \endcode
578
579 \sa {Attaching ScrollIndicator to a Flickable}
580*/
581QQuickScrollIndicator *QQuickScrollIndicatorAttached::vertical() const
582{
583 Q_D(const QQuickScrollIndicatorAttached);
584 return d->vertical;
585}
586
587void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical)
588{
589 Q_D(QQuickScrollIndicatorAttached);
590 if (d->vertical == vertical)
591 return;
592
593 if (d->vertical && d->flickable) {
594 QQuickItemPrivate::get(item: d->vertical)->removeItemChangeListener(d, types: QsiVerticalChangeTypes);
595 QObjectPrivate::disconnect(sender: d->flickable, signal: &QQuickFlickable::movingVerticallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateVertical);
596
597 // TODO: export QQuickFlickableVisibleArea
598 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
599 disconnect(sender: area, SIGNAL(heightRatioChanged(qreal)), receiver: d->vertical, SLOT(setSize(qreal)));
600 disconnect(sender: area, SIGNAL(yPositionChanged(qreal)), receiver: d->vertical, SLOT(setPosition(qreal)));
601 }
602
603 d->vertical = vertical;
604
605 if (vertical && d->flickable) {
606 if (!vertical->parentItem())
607 vertical->setParentItem(d->flickable);
608 vertical->setOrientation(Qt::Vertical);
609
610 QQuickItemPrivate::get(item: vertical)->addItemChangeListener(listener: d, types: QsiVerticalChangeTypes);
611 QObjectPrivate::connect(sender: d->flickable, signal: &QQuickFlickable::movingVerticallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateVertical);
612
613 // TODO: export QQuickFlickableVisibleArea
614 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
615 connect(sender: area, SIGNAL(heightRatioChanged(qreal)), receiver: vertical, SLOT(setSize(qreal)));
616 connect(sender: area, SIGNAL(yPositionChanged(qreal)), receiver: vertical, SLOT(setPosition(qreal)));
617
618 d->layoutVertical();
619 vertical->setSize(area->property(name: "heightRatio").toReal());
620 vertical->setPosition(area->property(name: "yPosition").toReal());
621 }
622 emit verticalChanged();
623}
624
625#if QT_CONFIG(quicktemplates2_multitouch)
626void QQuickScrollIndicator::touchEvent(QTouchEvent *event)
627{
628 event->ignore(); // QTBUG-61785
629}
630#endif
631
632#if QT_CONFIG(accessibility)
633QAccessible::Role QQuickScrollIndicator::accessibleRole() const
634{
635 return QAccessible::Indicator;
636}
637#endif
638
639QT_END_NAMESPACE
640
641#include "moc_qquickscrollindicator_p.cpp"
642

source code of qtdeclarative/src/quicktemplates/qquickscrollindicator.cpp