Qt 6.x
The Qt SDK
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
170{
171}
172
174{
175 return new QQuickScrollIndicatorAttached(object);
176}
177
191{
192 Q_D(const QQuickScrollIndicator);
193 return d->size;
194}
195
197{
199 if (qFuzzyCompare(d->size, 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 }
209 d->resizeContent();
211 d->visualAreaChange(d->visualArea(), oldVisualArea);
212}
213
225{
226 Q_D(const QQuickScrollIndicator);
227 return d->position;
228}
229
231{
233 if (qFuzzyCompare(d->position, position))
234 return;
235
236 auto oldVisualArea = d->visualArea();
237 d->position = position;
239 d->resizeContent();
241 d->visualAreaChange(d->visualArea(), oldVisualArea);
242}
243
257{
258 Q_D(const QQuickScrollIndicator);
259 return d->active;
260}
261
263{
265 if (d->active == active)
266 return;
267
268 d->active = active;
270}
271
287{
288 Q_D(const QQuickScrollIndicator);
289 return d->orientation;
290}
291
293{
295 if (d->orientation == orientation)
296 return;
297
298 d->orientation = orientation;
300 d->resizeContent();
302}
303
314{
315 Q_D(const QQuickScrollIndicator);
316 return d->orientation == Qt::Horizontal;
317}
318
329{
330 Q_D(const QQuickScrollIndicator);
331 return d->orientation == Qt::Vertical;
332}
333
343{
344 Q_D(const QQuickScrollIndicator);
345 return d->minimumSize;
346}
347
349{
351 if (qFuzzyCompare(d->minimumSize, minimumSize))
352 return;
353
354 auto oldVisualArea = d->visualArea();
355 d->minimumSize = minimumSize;
357 d->resizeContent();
358 emit minimumSizeChanged();
359 d->visualAreaChange(d->visualArea(), oldVisualArea);
360}
361
372{
373 Q_D(const QQuickScrollIndicator);
374 return d->visualArea().size;
375}
376
387{
388 Q_D(const QQuickScrollIndicator);
389 return d->visualArea().position;
390}
391
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;
404 void itemDestroyed(QQuickItem *item) override;
405
409};
410
412{
414}
415
417{
419}
420
422{
425 return;
427 if (move)
429}
430
432{
434 if (vertical->parentItem() != flickable)
435 return;
437 if (move && !QQuickItemPrivate::get(vertical)->isMirrored())
439}
440
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(horizontal->y()) || qFuzzyCompare(horizontal->y(), 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(vertical->x()) || qFuzzyCompare(vertical->x(), 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
464{
465 if (item == vertical)
466 layoutVertical(true);
467}
468
470{
471 if (item == horizontal)
472 layoutHorizontal(true);
473}
474
476{
477 if (item == horizontal)
478 horizontal = nullptr;
479 if (item == vertical)
480 vertical = nullptr;
481}
482
485{
487 d->flickable = qobject_cast<QQuickFlickable *>(parent);
488 if (d->flickable)
490 else if (parent)
491 qmlWarning(parent) << "ScrollIndicator must be attached to a Flickable";
492}
493
495{
497 if (d->flickable) {
498 if (d->horizontal)
500 if (d->vertical)
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.
506 }
507}
508
524{
526 return d->horizontal;
527}
528
530{
532 if (d->horizontal == horizontal)
533 return;
534
535 if (d->horizontal && d->flickable) {
538
539 // TODO: export QQuickFlickableVisibleArea
540 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
541 disconnect(area, SIGNAL(widthRatioChanged(qreal)), d->horizontal, SLOT(setSize(qreal)));
542 disconnect(area, SIGNAL(xPositionChanged(qreal)), 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);
551
554
555 // TODO: export QQuickFlickableVisibleArea
556 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
557 connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal)));
558 connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal)));
559
560 d->layoutHorizontal();
561 horizontal->setSize(area->property("widthRatio").toReal());
562 horizontal->setPosition(area->property("xPosition").toReal());
563 }
565}
566
582{
584 return d->vertical;
585}
586
588{
590 if (d->vertical == vertical)
591 return;
592
593 if (d->vertical && d->flickable) {
596
597 // TODO: export QQuickFlickableVisibleArea
598 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
599 disconnect(area, SIGNAL(heightRatioChanged(qreal)), d->vertical, SLOT(setSize(qreal)));
600 disconnect(area, SIGNAL(yPositionChanged(qreal)), 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);
609
612
613 // TODO: export QQuickFlickableVisibleArea
614 QObject *area = d->flickable->property("visibleArea").value<QObject *>();
615 connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal)));
616 connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal)));
617
618 d->layoutVertical();
619 vertical->setSize(area->property("heightRatio").toReal());
620 vertical->setPosition(area->property("yPosition").toReal());
621 }
623}
624
625#if QT_CONFIG(quicktemplates2_multitouch)
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
640
641#include "moc_qquickscrollindicator_p.cpp"
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:298
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:327
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
\inmodule QtCore\reentrant
Definition qpoint.h:214
QQuickDeferredPointer< QQuickItem > contentItem
bool isMovingHorizontally() const
void movingHorizontallyChanged()
void movingVerticallyChanged()
bool isMovingVertically() const
void updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, QQuickGeometryChange types)
void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types)
void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
void setSize(const QSizeF &size)
qreal x
\qmlproperty real QtQuick::Item::x \qmlproperty real QtQuick::Item::y \qmlproperty real QtQuick::Item...
Definition qquickitem.h:73
void setParentItem(QQuickItem *parent)
qreal y
Defines the item's y position relative to its parent.
Definition qquickitem.h:74
void setHeight(qreal)
qreal width
This property holds the width of this item.
Definition qquickitem.h:76
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:77
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:483
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:718
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:715
\inmodule QtCore
Definition qsize.h:207
The QTouchEvent class contains parameters that describe a touch event.
Definition qevent.h:916
Combined button and popup list for selecting options.
Orientation
Definition qnamespace.h:97
@ Horizontal
Definition qnamespace.h:98
@ Vertical
Definition qnamespace.h:99
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
static int area(const QSize &s)
Definition qicon.cpp:152
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
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:92
myObject disconnect()
[26]
QGraphicsItem * item
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent