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//! \nativetype 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 \include varying-delegate-heights-section.qdocinc {file} {1} {ScrollIndicator}
94
95 \sa ScrollBar, {Customizing ScrollIndicator}, {Indicator Controls}
96*/
97
98static const QQuickItemPrivate::ChangeTypes QsiChangeTypes = QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed;
99static const QQuickItemPrivate::ChangeTypes QsiHorizontalChangeTypes = QsiChangeTypes | QQuickItemPrivate::ImplicitHeight;
100static const QQuickItemPrivate::ChangeTypes QsiVerticalChangeTypes = QsiChangeTypes | QQuickItemPrivate::ImplicitWidth;
101
102class QQuickScrollIndicatorPrivate : public QQuickControlPrivate
103{
104 Q_DECLARE_PUBLIC(QQuickScrollIndicator)
105
106public:
107 struct VisualArea
108 {
109 VisualArea(qreal pos, qreal sz)
110 : position(pos), size(sz) { }
111 qreal position = 0;
112 qreal size = 0;
113 };
114 VisualArea visualArea() const;
115 void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea);
116
117 void resizeContent() override;
118
119 qreal size = 0;
120 qreal minimumSize = 0;
121 qreal position = 0;
122 bool active = false;
123 Qt::Orientation orientation = Qt::Vertical;
124};
125
126QQuickScrollIndicatorPrivate::VisualArea QQuickScrollIndicatorPrivate::visualArea() const
127{
128 qreal visualPos = position;
129 if (minimumSize > size)
130 visualPos = position / (1.0 - size) * (1.0 - minimumSize);
131
132 qreal maximumSize = qMax<qreal>(a: 0.0, b: 1.0 - visualPos);
133 qreal visualSize = qMax<qreal>(a: minimumSize,
134 b: qMin<qreal>(a: qMax(a: size, b: minimumSize) + qMin<qreal>(a: 0, b: visualPos),
135 b: maximumSize));
136
137 visualPos = qMax<qreal>(a: 0,b: qMin<qreal>(a: visualPos,b: qMax<qreal>(a: 0, b: 1.0 - visualSize)));
138
139 return VisualArea(visualPos, visualSize);
140}
141
142void QQuickScrollIndicatorPrivate::visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea)
143{
144 Q_Q(QQuickScrollIndicator);
145 if (!qFuzzyCompare(p1: newVisualArea.size, p2: oldVisualArea.size))
146 emit q->visualSizeChanged();
147 if (!qFuzzyCompare(p1: newVisualArea.position, p2: oldVisualArea.position))
148 emit q->visualPositionChanged();
149}
150
151void QQuickScrollIndicatorPrivate::resizeContent()
152{
153 Q_Q(QQuickScrollIndicator);
154 if (!contentItem)
155 return;
156
157 // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size
158 // - positive overshoot (pos + size > 1): clamp the size to 1-pos
159 const VisualArea visual = visualArea();
160
161 if (orientation == Qt::Horizontal) {
162 contentItem->setPosition(QPointF(q->leftPadding() + visual.position * q->availableWidth(), q->topPadding()));
163 contentItem->setSize(QSizeF(q->availableWidth() * visual.size, q->availableHeight()));
164 } else {
165 contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + visual.position * q->availableHeight()));
166 contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * visual.size));
167 }
168}
169
170QQuickScrollIndicator::QQuickScrollIndicator(QQuickItem *parent)
171 : QQuickControl(*(new QQuickScrollIndicatorPrivate), parent)
172{
173 Q_D(QQuickScrollIndicator);
174 d->setSizePolicy(horizontalPolicy: QLayoutPolicy::Preferred, verticalPolicy: QLayoutPolicy::Fixed);
175}
176
177QQuickScrollIndicatorAttached *QQuickScrollIndicator::qmlAttachedProperties(QObject *object)
178{
179 return new QQuickScrollIndicatorAttached(object);
180}
181
182/*!
183 \qmlproperty real QtQuick.Controls::ScrollIndicator::size
184
185 This property holds the size of the indicator, scaled to \c {0.0 - 1.0}.
186
187 \sa {Flickable::visibleArea.heightRatio}{Flickable::visibleArea}
188
189 This property is automatically set when the scroll indicator is
190 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
191
192 \sa minimumSize, visualSize
193*/
194qreal QQuickScrollIndicator::size() const
195{
196 Q_D(const QQuickScrollIndicator);
197 return d->size;
198}
199
200void QQuickScrollIndicator::setSize(qreal size)
201{
202 Q_D(QQuickScrollIndicator);
203 if (qFuzzyCompare(p1: d->size, p2: size))
204 return;
205
206 auto oldVisualArea = d->visualArea();
207 d->size = size;
208 if (d->size + d->position > 1.0) {
209 setPosition(1.0 - d->size);
210 oldVisualArea = d->visualArea();
211 }
212 if (isComponentComplete())
213 d->resizeContent();
214 emit sizeChanged();
215 d->visualAreaChange(newVisualArea: d->visualArea(), oldVisualArea);
216}
217
218/*!
219 \qmlproperty real QtQuick.Controls::ScrollIndicator::position
220
221 This property holds the position of the indicator, scaled to \c {0.0 - 1.0}.
222
223 This property is automatically set when the scroll indicator is
224 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
225
226 \sa {Flickable::visibleArea.yPosition}{Flickable::visibleArea}, visualPosition
227*/
228qreal QQuickScrollIndicator::position() const
229{
230 Q_D(const QQuickScrollIndicator);
231 return d->position;
232}
233
234void QQuickScrollIndicator::setPosition(qreal position)
235{
236 Q_D(QQuickScrollIndicator);
237 if (qFuzzyCompare(p1: d->position, p2: position))
238 return;
239
240 auto oldVisualArea = d->visualArea();
241 d->position = position;
242 if (isComponentComplete())
243 d->resizeContent();
244 emit positionChanged();
245 d->visualAreaChange(newVisualArea: d->visualArea(), oldVisualArea);
246}
247
248/*!
249 \qmlproperty bool QtQuick.Controls::ScrollIndicator::active
250
251 This property holds whether the indicator is active, that is, when the
252 attached Flickable is \l {Flickable::moving}{moving}.
253
254 It is possible to keep \l {Binding the Active State of Horizontal and Vertical Scroll Indicators}
255 {both horizontal and vertical indicators visible} while scrolling in either direction.
256
257 This property is automatically set when the scroll indicator is
258 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
259*/
260bool QQuickScrollIndicator::isActive() const
261{
262 Q_D(const QQuickScrollIndicator);
263 return d->active;
264}
265
266void QQuickScrollIndicator::setActive(bool active)
267{
268 Q_D(QQuickScrollIndicator);
269 if (d->active == active)
270 return;
271
272 d->active = active;
273 emit activeChanged();
274}
275
276/*!
277 \qmlproperty enumeration QtQuick.Controls::ScrollIndicator::orientation
278
279 This property holds the orientation of the indicator.
280
281 Possible values:
282 \value Qt.Horizontal Horizontal
283 \value Qt.Vertical Vertical (default)
284
285 This property is automatically set when the scroll indicator is
286 \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}.
287
288 \sa horizontal, vertical
289*/
290Qt::Orientation QQuickScrollIndicator::orientation() const
291{
292 Q_D(const QQuickScrollIndicator);
293 return d->orientation;
294}
295
296void QQuickScrollIndicator::setOrientation(Qt::Orientation orientation)
297{
298 Q_D(QQuickScrollIndicator);
299 if (d->orientation == orientation)
300 return;
301
302 if (orientation == Qt::Horizontal)
303 d->setSizePolicy(horizontalPolicy: QLayoutPolicy::Preferred, verticalPolicy: QLayoutPolicy::Fixed);
304 else
305 d->setSizePolicy(horizontalPolicy: QLayoutPolicy::Fixed, verticalPolicy: QLayoutPolicy::Preferred);
306
307 d->orientation = orientation;
308 if (isComponentComplete())
309 d->resizeContent();
310 emit orientationChanged();
311}
312
313/*!
314 \since QtQuick.Controls 2.3 (Qt 5.10)
315 \qmlproperty bool QtQuick.Controls::ScrollIndicator::horizontal
316 \readonly
317
318 This property holds whether the scroll indicator is horizontal.
319
320 \sa orientation
321*/
322bool QQuickScrollIndicator::isHorizontal() const
323{
324 Q_D(const QQuickScrollIndicator);
325 return d->orientation == Qt::Horizontal;
326}
327
328/*!
329 \since QtQuick.Controls 2.3 (Qt 5.10)
330 \qmlproperty bool QtQuick.Controls::ScrollIndicator::vertical
331 \readonly
332
333 This property holds whether the scroll indicator is vertical.
334
335 \sa orientation
336*/
337bool QQuickScrollIndicator::isVertical() const
338{
339 Q_D(const QQuickScrollIndicator);
340 return d->orientation == Qt::Vertical;
341}
342
343/*!
344 \since QtQuick.Controls 2.4 (Qt 5.11)
345 \qmlproperty real QtQuick.Controls::ScrollIndicator::minimumSize
346
347 This property holds the minimum size of the indicator, scaled to \c {0.0 - 1.0}.
348
349 \sa size, visualSize, visualPosition
350*/
351qreal QQuickScrollIndicator::minimumSize() const
352{
353 Q_D(const QQuickScrollIndicator);
354 return d->minimumSize;
355}
356
357void QQuickScrollIndicator::setMinimumSize(qreal minimumSize)
358{
359 Q_D(QQuickScrollIndicator);
360 if (qFuzzyCompare(p1: d->minimumSize, p2: minimumSize))
361 return;
362
363 auto oldVisualArea = d->visualArea();
364 d->minimumSize = minimumSize;
365 if (isComponentComplete())
366 d->resizeContent();
367 emit minimumSizeChanged();
368 d->visualAreaChange(newVisualArea: d->visualArea(), oldVisualArea);
369}
370
371/*!
372 \since QtQuick.Controls 2.4 (Qt 5.11)
373 \qmlproperty real QtQuick.Controls::ScrollIndicator::visualSize
374
375 This property holds the effective visual size of the indicator,
376 which may be limited by the \l {minimumSize}{minimum size}.
377
378 \sa size, minimumSize
379*/
380qreal QQuickScrollIndicator::visualSize() const
381{
382 Q_D(const QQuickScrollIndicator);
383 return d->visualArea().size;
384}
385
386/*!
387 \since QtQuick.Controls 2.4 (Qt 5.11)
388 \qmlproperty real QtQuick.Controls::ScrollIndicator::visualPosition
389
390 This property holds the effective visual position of the indicator,
391 which may be limited by the \l {minimumSize}{minimum size}.
392
393 \sa position, minimumSize
394*/
395qreal QQuickScrollIndicator::visualPosition() const
396{
397 Q_D(const QQuickScrollIndicator);
398 return d->visualArea().position;
399}
400
401class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate,
402 public QSafeQuickItemChangeListener<QQuickScrollIndicatorAttachedPrivate>
403{
404public:
405 void activateHorizontal();
406 void activateVertical();
407
408 void layoutHorizontal(bool move = true);
409 void layoutVertical(bool move = true);
410
411 void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
412 void itemImplicitWidthChanged(QQuickItem *item) override;
413 void itemImplicitHeightChanged(QQuickItem *item) override;
414 void itemDestroyed(QQuickItem *item) override;
415
416 QQuickFlickable *flickable = nullptr;
417 QQuickScrollIndicator *horizontal = nullptr;
418 QQuickScrollIndicator *vertical = nullptr;
419};
420
421void QQuickScrollIndicatorAttachedPrivate::activateHorizontal()
422{
423 horizontal->setActive(flickable->isMovingHorizontally());
424}
425
426void QQuickScrollIndicatorAttachedPrivate::activateVertical()
427{
428 vertical->setActive(flickable->isMovingVertically());
429}
430
431void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move)
432{
433 Q_ASSERT(horizontal && flickable);
434 if (horizontal->parentItem() != flickable)
435 return;
436 horizontal->setWidth(flickable->width());
437 if (move)
438 horizontal->setY(flickable->height() - horizontal->height());
439}
440
441void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move)
442{
443 Q_ASSERT(vertical && flickable);
444 if (vertical->parentItem() != flickable)
445 return;
446 vertical->setHeight(flickable->height());
447 if (move && !QQuickItemPrivate::get(item: vertical)->isMirrored())
448 vertical->setX(flickable->width() - vertical->width());
449}
450
451void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
452{
453 Q_UNUSED(item);
454 Q_UNUSED(change);
455 if (horizontal && horizontal->height() > 0) {
456#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
457 bool move = qFuzzyIsNull(d: horizontal->y()) || qFuzzyCompare(p1: horizontal->y(), p2: diff.height() - horizontal->height());
458#else
459 bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height());
460#endif
461 layoutHorizontal(move);
462 }
463 if (vertical && vertical->width() > 0) {
464#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
465 bool move = qFuzzyIsNull(d: vertical->x()) || qFuzzyCompare(p1: vertical->x(), p2: diff.width() - vertical->width());
466#else
467 bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width());
468#endif
469 layoutVertical(move);
470 }
471}
472
473void QQuickScrollIndicatorAttachedPrivate::itemImplicitWidthChanged(QQuickItem *item)
474{
475 if (item == vertical)
476 layoutVertical(move: true);
477}
478
479void QQuickScrollIndicatorAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item)
480{
481 if (item == horizontal)
482 layoutHorizontal(move: true);
483}
484
485void QQuickScrollIndicatorAttachedPrivate::itemDestroyed(QQuickItem *item)
486{
487 if (item == horizontal)
488 horizontal = nullptr;
489 if (item == vertical)
490 vertical = nullptr;
491}
492
493QQuickScrollIndicatorAttached::QQuickScrollIndicatorAttached(QObject *parent)
494 : QObject(*(new QQuickScrollIndicatorAttachedPrivate), parent)
495{
496 Q_D(QQuickScrollIndicatorAttached);
497 d->flickable = qobject_cast<QQuickFlickable *>(object: parent);
498 if (d->flickable)
499 QQuickItemPrivate::get(item: d->flickable)->updateOrAddGeometryChangeListener(listener: d, types: QQuickGeometryChange::Size);
500 else if (parent)
501 qmlWarning(me: parent) << "ScrollIndicator attached property must be attached to an object deriving from Flickable";
502}
503
504QQuickScrollIndicatorAttached::~QQuickScrollIndicatorAttached()
505{
506 Q_D(QQuickScrollIndicatorAttached);
507 if (d->flickable) {
508 if (d->horizontal)
509 QQuickItemPrivate::get(item: d->horizontal)->removeItemChangeListener(d, types: QsiHorizontalChangeTypes);
510 if (d->vertical)
511 QQuickItemPrivate::get(item: d->vertical)->removeItemChangeListener(d, types: QsiVerticalChangeTypes);
512 // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size).
513 // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling
514 // pointer on destruction.
515 QQuickItemPrivate::get(item: d->flickable)->removeItemChangeListener(d, types: QQuickItemPrivate::Geometry);
516 }
517}
518
519/*!
520 \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::horizontal
521
522 This property attaches a horizontal scroll indicator to a \l Flickable.
523
524 \code
525 Flickable {
526 contentWidth: 2000
527 ScrollIndicator.horizontal: ScrollIndicator { }
528 }
529 \endcode
530
531 \sa {Attaching ScrollIndicator to a Flickable}
532*/
533QQuickScrollIndicator *QQuickScrollIndicatorAttached::horizontal() const
534{
535 Q_D(const QQuickScrollIndicatorAttached);
536 return d->horizontal;
537}
538
539void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizontal)
540{
541 Q_D(QQuickScrollIndicatorAttached);
542 if (d->horizontal == horizontal)
543 return;
544
545 if (d->horizontal && d->flickable) {
546 QQuickItemPrivate::get(item: d->horizontal)->removeItemChangeListener(d, types: QsiHorizontalChangeTypes);
547 QObjectPrivate::disconnect(sender: d->flickable, signal: &QQuickFlickable::movingHorizontallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
548
549 // TODO: export QQuickFlickableVisibleArea
550 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
551 disconnect(sender: area, SIGNAL(widthRatioChanged(qreal)), receiver: d->horizontal, SLOT(setSize(qreal)));
552 disconnect(sender: area, SIGNAL(xPositionChanged(qreal)), receiver: d->horizontal, SLOT(setPosition(qreal)));
553 }
554
555 d->horizontal = horizontal;
556
557 if (horizontal && d->flickable) {
558 if (!horizontal->parentItem())
559 horizontal->setParentItem(d->flickable);
560 horizontal->setOrientation(Qt::Horizontal);
561
562 QQuickItemPrivate::get(item: horizontal)->addItemChangeListener(listener: d, types: QsiHorizontalChangeTypes);
563 QObjectPrivate::connect(sender: d->flickable, signal: &QQuickFlickable::movingHorizontallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateHorizontal);
564
565 // TODO: export QQuickFlickableVisibleArea
566 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
567 connect(sender: area, SIGNAL(widthRatioChanged(qreal)), receiver: horizontal, SLOT(setSize(qreal)));
568 connect(sender: area, SIGNAL(xPositionChanged(qreal)), receiver: horizontal, SLOT(setPosition(qreal)));
569
570 d->layoutHorizontal();
571 horizontal->setSize(area->property(name: "widthRatio").toReal());
572 horizontal->setPosition(area->property(name: "xPosition").toReal());
573 }
574 emit horizontalChanged();
575}
576
577/*!
578 \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::vertical
579
580 This property attaches a vertical scroll indicator to a \l Flickable.
581
582 \code
583 Flickable {
584 contentHeight: 2000
585 ScrollIndicator.vertical: ScrollIndicator { }
586 }
587 \endcode
588
589 \sa {Attaching ScrollIndicator to a Flickable}
590*/
591QQuickScrollIndicator *QQuickScrollIndicatorAttached::vertical() const
592{
593 Q_D(const QQuickScrollIndicatorAttached);
594 return d->vertical;
595}
596
597void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical)
598{
599 Q_D(QQuickScrollIndicatorAttached);
600 if (d->vertical == vertical)
601 return;
602
603 if (d->vertical && d->flickable) {
604 QQuickItemPrivate::get(item: d->vertical)->removeItemChangeListener(d, types: QsiVerticalChangeTypes);
605 QObjectPrivate::disconnect(sender: d->flickable, signal: &QQuickFlickable::movingVerticallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateVertical);
606
607 // TODO: export QQuickFlickableVisibleArea
608 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
609 disconnect(sender: area, SIGNAL(heightRatioChanged(qreal)), receiver: d->vertical, SLOT(setSize(qreal)));
610 disconnect(sender: area, SIGNAL(yPositionChanged(qreal)), receiver: d->vertical, SLOT(setPosition(qreal)));
611 }
612
613 d->vertical = vertical;
614
615 if (vertical && d->flickable) {
616 if (!vertical->parentItem())
617 vertical->setParentItem(d->flickable);
618 vertical->setOrientation(Qt::Vertical);
619
620 QQuickItemPrivate::get(item: vertical)->addItemChangeListener(listener: d, types: QsiVerticalChangeTypes);
621 QObjectPrivate::connect(sender: d->flickable, signal: &QQuickFlickable::movingVerticallyChanged, receiverPrivate: d, slot: &QQuickScrollIndicatorAttachedPrivate::activateVertical);
622
623 // TODO: export QQuickFlickableVisibleArea
624 QObject *area = d->flickable->property(name: "visibleArea").value<QObject *>();
625 connect(sender: area, SIGNAL(heightRatioChanged(qreal)), receiver: vertical, SLOT(setSize(qreal)));
626 connect(sender: area, SIGNAL(yPositionChanged(qreal)), receiver: vertical, SLOT(setPosition(qreal)));
627
628 d->layoutVertical();
629 vertical->setSize(area->property(name: "heightRatio").toReal());
630 vertical->setPosition(area->property(name: "yPosition").toReal());
631 }
632 emit verticalChanged();
633}
634
635#if QT_CONFIG(quicktemplates2_multitouch)
636void QQuickScrollIndicator::touchEvent(QTouchEvent *event)
637{
638 event->ignore(); // QTBUG-61785
639}
640#endif
641
642#if QT_CONFIG(accessibility)
643QAccessible::Role QQuickScrollIndicator::accessibleRole() const
644{
645 return QAccessible::Indicator;
646}
647#endif
648
649QT_END_NAMESPACE
650
651#include "moc_qquickscrollindicator_p.cpp"
652

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