Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickscrollindicator.cpp
Go to the documentation of this file.
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
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
12
17
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
101{
102 Q_DECLARE_PUBLIC(QQuickScrollIndicator)
103
104public:
106 {
108 : position(pos), size(sz) { }
111 };
112 VisualArea visualArea() const;
113 void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea);
114
115 void resizeContent() override;
116
120 bool active = false;
122};
123
125{
126 qreal visualPos = position;
127 if (minimumSize > size)
128 visualPos = position / (1.0 - size) * (1.0 - minimumSize);
129
130 qreal maximumSize = qMax<qreal>(0.0, 1.0 - visualPos);
131 qreal visualSize = qMax<qreal>(minimumSize,
132 qMin<qreal>(qMax(size, minimumSize) + qMin<qreal>(0, visualPos),
133 maximumSize));
134
135 visualPos = qMax<qreal>(0,qMin<qreal>(visualPos,qMax<qreal>(0, 1.0 - visualSize)));
136
137 return VisualArea(visualPos, visualSize);
138}
139
140void QQuickScrollIndicatorPrivate::visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea)
141{
143 if (!qFuzzyCompare(newVisualArea.size, oldVisualArea.size))
144 emit q->visualSizeChanged();
145 if (!qFuzzyCompare(newVisualArea.position, oldVisualArea.position))
146 emit q->visualPositionChanged();
147}
148
150{
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
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
174
179
193{
194 Q_D(const QQuickScrollIndicator);
195 return d->size;
196}
197
199{
201 if (qFuzzyCompare(d->size, size))
202 return;
203
204 auto oldVisualArea = d->visualArea();
205 d->size = size;
206 if (d->size + d->position > 1.0) {
207 setPosition(1.0 - d->size);
208 oldVisualArea = d->visualArea();
209 }
211 d->resizeContent();
213 d->visualAreaChange(d->visualArea(), oldVisualArea);
214}
215
227{
228 Q_D(const QQuickScrollIndicator);
229 return d->position;
230}
231
233{
235 if (qFuzzyCompare(d->position, position))
236 return;
237
238 auto oldVisualArea = d->visualArea();
239 d->position = position;
241 d->resizeContent();
243 d->visualAreaChange(d->visualArea(), oldVisualArea);
244}
245
259{
260 Q_D(const QQuickScrollIndicator);
261 return d->active;
262}
263
265{
267 if (d->active == active)
268 return;
269
270 d->active = active;
272}
273
289{
290 Q_D(const QQuickScrollIndicator);
291 return d->orientation;
292}
293
295{
297 if (d->orientation == orientation)
298 return;
299
302 else
304
305 d->orientation = orientation;
307 d->resizeContent();
309}
310
321{
322 Q_D(const QQuickScrollIndicator);
323 return d->orientation == Qt::Horizontal;
324}
325
336{
337 Q_D(const QQuickScrollIndicator);
338 return d->orientation == Qt::Vertical;
339}
340
350{
351 Q_D(const QQuickScrollIndicator);
352 return d->minimumSize;
353}
354
356{
358 if (qFuzzyCompare(d->minimumSize, minimumSize))
359 return;
360
361 auto oldVisualArea = d->visualArea();
362 d->minimumSize = minimumSize;
364 d->resizeContent();
365 emit minimumSizeChanged();
366 d->visualAreaChange(d->visualArea(), oldVisualArea);
367}
368
379{
380 Q_D(const QQuickScrollIndicator);
381 return d->visualArea().size;
382}
383
394{
395 Q_D(const QQuickScrollIndicator);
396 return d->visualArea().position;
397}
398
400{
401public:
402 void activateHorizontal();
403 void activateVertical();
404
405 void layoutHorizontal(bool move = true);
406 void layoutVertical(bool move = true);
407
408 void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override;
411 void itemDestroyed(QQuickItem *item) override;
412
416};
417
422
427
437
447
449{
450 Q_UNUSED(item);
451 Q_UNUSED(change);
452 if (horizontal && horizontal->height() > 0) {
453#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
454 bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), diff.height() - horizontal->height());
455#else
456 bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height());
457#endif
458 layoutHorizontal(move);
459 }
460 if (vertical && vertical->width() > 0) {
461#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry
462 bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), diff.width() - vertical->width());
463#else
464 bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width());
465#endif
466 layoutVertical(move);
467 }
468}
469
475
481
483{
484 if (item == horizontal)
485 horizontal = nullptr;
486 if (item == vertical)
487 vertical = nullptr;
488}
489
492{
494 d->flickable = qobject_cast<QQuickFlickable *>(parent);
495 if (d->flickable)
496 QQuickItemPrivate::get(d->flickable)->updateOrAddGeometryChangeListener(d, QQuickGeometryChange::Size);
497 else if (parent)
498 qmlWarning(parent) << "ScrollIndicator must be attached to a Flickable";
499}
500
502{
504 if (d->flickable) {
505 if (d->horizontal)
506 QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QsiHorizontalChangeTypes);
507 if (d->vertical)
508 QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QsiVerticalChangeTypes);
509 // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size).
510 // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling
511 // pointer on destruction.
512 QQuickItemPrivate::get(d->flickable)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
513 }
514}
515
535
537{
539 if (d->horizontal == horizontal)
540 return;
541
542 if (d->horizontal && d->flickable) {
543 QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QsiHorizontalChangeTypes);
545
546 // TODO: export QQuickFlickableVisibleArea
547 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
548 disconnect(area, SIGNAL(widthRatioChanged(qreal)), d->horizontal, SLOT(setSize(qreal)));
549 disconnect(area, SIGNAL(xPositionChanged(qreal)), d->horizontal, SLOT(setPosition(qreal)));
550 }
551
552 d->horizontal = horizontal;
553
554 if (horizontal && d->flickable) {
555 if (!horizontal->parentItem())
556 horizontal->setParentItem(d->flickable);
558
561
562 // TODO: export QQuickFlickableVisibleArea
563 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
564 connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
565 connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
566
567 d->layoutHorizontal();
568 horizontal->setSize(area->property("widthRatio").toReal());
569 horizontal->setPosition(area->property("xPosition").toReal());
570 }
572}
573
593
595{
597 if (d->vertical == vertical)
598 return;
599
600 if (d->vertical && d->flickable) {
601 QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QsiVerticalChangeTypes);
603
604 // TODO: export QQuickFlickableVisibleArea
605 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
606 disconnect(area, SIGNAL(heightRatioChanged(qreal)), d->vertical, SLOT(setSize(qreal)));
607 disconnect(area, SIGNAL(yPositionChanged(qreal)), d->vertical, SLOT(setPosition(qreal)));
608 }
609
610 d->vertical = vertical;
611
612 if (vertical && d->flickable) {
613 if (!vertical->parentItem())
614 vertical->setParentItem(d->flickable);
616
619
620 // TODO: export QQuickFlickableVisibleArea
621 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
622 connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
623 connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
624
625 d->layoutVertical();
626 vertical->setSize(area->property("heightRatio").toReal());
627 vertical->setPosition(area->property("yPosition").toReal());
628 }
630}
631
632#if QT_CONFIG(quicktemplates2_multitouch)
634{
635 event->ignore(); // QTBUG-61785
636}
637#endif
638
639#if QT_CONFIG(accessibility)
640QAccessible::Role QQuickScrollIndicator::accessibleRole() const
641{
642 return QAccessible::Indicator;
643}
644#endif
645
647
648#include "moc_qquickscrollindicator_p.cpp"
static constexpr Policy Preferred
static constexpr Policy Fixed
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:299
static bool disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
Definition qobject_p.h:328
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
\inmodule QtCore\reentrant
Definition qpoint.h:217
QQuickDeferredPointer< QQuickItem > contentItem
bool isMovingHorizontally() const
void movingHorizontallyChanged()
void movingVerticallyChanged()
bool isMovingVertically() const
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setSize(const QSizeF &size)
qreal x
\qmlproperty real QtQuick::Item::x \qmlproperty real QtQuick::Item::y \qmlproperty real QtQuick::Item...
Definition qquickitem.h:72
void setParentItem(QQuickItem *parent)
qreal y
Defines the item's y position relative to its parent.
Definition qquickitem.h:73
void setHeight(qreal)
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
QQuickItem * parentItem() const
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
virtual void touchEvent(QTouchEvent *event)
This event handler can be reimplemented in a subclass to receive touch events for an item.
qreal height
This property holds the height of this item.
Definition qquickitem.h:76
void setPosition(const QPointF &)
void setWidth(qreal)
void setX(qreal)
void setY(qreal)
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override
void itemImplicitHeightChanged(QQuickItem *item) override
void itemImplicitWidthChanged(QQuickItem *item) override
void itemDestroyed(QQuickItem *item) override
void setVertical(QQuickScrollIndicator *vertical)
void setHorizontal(QQuickScrollIndicator *horizontal)
QQuickScrollIndicatorAttached(QObject *parent=nullptr)
void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea)
void setPosition(qreal position)
bool isActive() const
\qmlproperty bool QtQuick.Controls::ScrollIndicator::active
void setMinimumSize(qreal minimumSize)
QQuickScrollIndicator(QQuickItem *parent=nullptr)
static QQuickScrollIndicatorAttached * qmlAttachedProperties(QObject *object)
void setOrientation(Qt::Orientation orientation)
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:732
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
\inmodule QtCore
Definition qsize.h:208
The QTouchEvent class contains parameters that describe a touch event.
Definition qevent.h:917
Combined button and popup list for selecting options.
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
static int area(const QSize &s)
Definition qicon.cpp:153
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
n void setPosition(void) \n\
GLenum GLuint GLintptr GLsizeiptr size
[1]
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static const QQuickItemPrivate::ChangeTypes QsiVerticalChangeTypes
static const QQuickItemPrivate::ChangeTypes QsiHorizontalChangeTypes
static QT_BEGIN_NAMESPACE const QQuickItemPrivate::ChangeTypes QsiChangeTypes
Vertical or horizontal non-interactive scroll indicator.
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define emit
#define Q_UNUSED(x)
double qreal
Definition qtypes.h:187
myObject disconnect()
[26]
QGraphicsItem * item