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
qquickslider.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
4#include "qquickslider_p.h"
5#include "qquickcontrol_p_p.h"
7
8#include <QtQuick/private/qquickwindow_p.h>
9
11
16
58{
59 Q_DECLARE_PUBLIC(QQuickSlider)
60
61public:
63 qreal positionAt(const QPointF &point) const;
65 void updatePosition();
66
67 bool handlePress(const QPointF &point, ulong timestamp) override;
68 bool handleMove(const QPointF &point, ulong timestamp) override;
69 bool handleRelease(const QPointF &point, ulong timestamp) override;
70 void handleUngrab() override;
71
72 void cancelHandle();
73 void executeHandle(bool complete = false);
74
77 void itemDestroyed(QQuickItem *item) override;
78
80 qreal to = 1;
84 qreal touchDragThreshold = -1; // in QQuickWindowPrivate::dragOverThreshold, '-1' implies using styleHints::startDragDistance()
85 bool live = true;
86 bool pressed = false;
90 QQuickDeferredPointer<QQuickItem> handle;
91};
92
94{
95 const qreal range = to - from;
97 return position;
98
99 const qreal effectiveStep = stepSize / range;
100 if (qFuzzyIsNull(effectiveStep))
101 return position;
102
103 return qRound(position / effectiveStep) * effectiveStep;
104}
105
107{
108 Q_Q(const QQuickSlider);
109 qreal pos = 0.0;
111 const qreal hw = handle ? handle->width() : 0;
112 const qreal offset = hw / 2;
113 const qreal extent = q->availableWidth() - hw;
114 if (!qFuzzyIsNull(extent)) {
115 if (q->isMirrored())
116 pos = (q->width() - point.x() - q->rightPadding() - offset) / extent;
117 else
118 pos = (point.x() - q->leftPadding() - offset) / extent;
119 }
120 } else {
121 const qreal hh = handle ? handle->height() : 0;
122 const qreal offset = hh / 2;
123 const qreal extent = q->availableHeight() - hh;
124 if (!qFuzzyIsNull(extent))
125 pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent;
126 }
127 return qBound<qreal>(0.0, pos, 1.0);
128}
129
131{
132 Q_Q(QQuickSlider);
133 pos = qBound<qreal>(0.0, pos, 1.0);
135 return;
136
137 position = pos;
138 emit q->positionChanged();
139 emit q->visualPositionChanged();
140}
141
143{
144 qreal pos = 0;
145 if (!qFuzzyCompare(from, to))
146 pos = (value - from) / (to - from);
148}
149
150bool QQuickSliderPrivate::handlePress(const QPointF &point, ulong timestamp)
151{
152 Q_Q(QQuickSlider);
153 QQuickControlPrivate::handlePress(point, timestamp);
154 pressPoint = point;
155 q->setPressed(true);
156 return true;
157}
158
159bool QQuickSliderPrivate::handleMove(const QPointF &point, ulong timestamp)
160{
161 Q_Q(QQuickSlider);
162 QQuickControlPrivate::handleMove(point, timestamp);
163 const qreal oldPos = position;
164 qreal pos = positionAt(point);
167 if (live)
168 q->setValue(q->valueAt(pos));
171 if (!qFuzzyCompare(pos, oldPos))
172 emit q->moved();
173 return true;
174}
175
177{
178 Q_Q(QQuickSlider);
179 QQuickControlPrivate::handleRelease(point, timestamp);
181 const qreal oldPos = position;
182 qreal pos = positionAt(point);
185 qreal val = q->valueAt(pos);
186 if (!qFuzzyCompare(val, value))
187 q->setValue(val);
188 else if (snapMode != QQuickSlider::NoSnap)
190 if (!qFuzzyCompare(pos, oldPos))
191 emit q->moved();
192 q->setKeepMouseGrab(false);
193 q->setKeepTouchGrab(false);
194 q->setPressed(false);
195 return true;
196}
197
199{
200 Q_Q(QQuickSlider);
203 q->setPressed(false);
204}
205
211
213{
214 Q_Q(QQuickSlider);
215 if (handle.wasExecuted())
216 return;
217
218 if (!handle || complete)
220 if (complete)
222}
223
231
239
241{
242 Q_Q(QQuickSlider);
244 if (item == handle) {
245 handle = nullptr;
246 emit q->handleChanged();
247 }
248}
249
251 : QQuickControl(*(new QQuickSliderPrivate), parent)
252{
253 Q_D(QQuickSlider);
256#ifdef Q_OS_MACOS
258#else
260#endif
262#if QT_CONFIG(quicktemplates2_multitouch)
264#endif
265#if QT_CONFIG(cursor)
267#endif
268}
269
271{
272 Q_D(QQuickSlider);
273 d->removeImplicitSizeListener(d->handle);
274}
275
284{
285 Q_D(const QQuickSlider);
286 return d->from;
287}
288
290{
291 Q_D(QQuickSlider);
292 if (qFuzzyCompare(d->from, from))
293 return;
294
295 d->from = from;
297 if (isComponentComplete()) {
298 setValue(d->value);
299 d->updatePosition();
300 }
301}
302
311{
312 Q_D(const QQuickSlider);
313 return d->to;
314}
315
317{
318 Q_D(QQuickSlider);
319 if (qFuzzyCompare(d->to, to))
320 return;
321
322 d->to = to;
323 emit toChanged();
324 if (isComponentComplete()) {
325 setValue(d->value);
326 d->updatePosition();
327 }
328}
329
338{
339 Q_D(const QQuickSlider);
340 return d->value;
341}
342
344{
345 Q_D(QQuickSlider);
347 value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
348
349 if (qFuzzyCompare(d->value, value))
350 return;
351
352 d->value = value;
353 d->updatePosition();
355}
356
370{
371 Q_D(const QQuickSlider);
372 return d->position;
373}
374
389{
390 Q_D(const QQuickSlider);
391 if (d->orientation == Qt::Vertical || isMirrored())
392 return 1.0 - d->position;
393 return d->position;
394}
395
404{
405 Q_D(const QQuickSlider);
406 return d->stepSize;
407}
408
410{
411 Q_D(QQuickSlider);
412 if (qFuzzyCompare(d->stepSize, step))
413 return;
414
415 d->stepSize = step;
417}
418
447{
448 Q_D(const QQuickSlider);
449 return d->snapMode;
450}
451
453{
454 Q_D(QQuickSlider);
455 if (d->snapMode == mode)
456 return;
457
458 d->snapMode = mode;
460}
461
469{
470 Q_D(const QQuickSlider);
471 return d->pressed;
472}
473
474void QQuickSlider::setPressed(bool pressed)
475{
476 Q_D(QQuickSlider);
477 if (d->pressed == pressed)
478 return;
479
480 d->pressed = pressed;
481 setAccessibleProperty("pressed", pressed);
483}
484
495{
496 Q_D(const QQuickSlider);
497 return d->orientation == Qt::Horizontal;
498}
499
510{
511 Q_D(const QQuickSlider);
512 return d->orientation == Qt::Vertical;
513}
514
527{
528 Q_D(const QQuickSlider);
529 return d->orientation;
530}
531
533{
534 Q_D(QQuickSlider);
535 if (d->orientation == orientation)
536 return;
537
540 else
542
543 d->orientation = orientation;
545}
546
555{
556 QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func());
557 if (!d->handle)
558 d->executeHandle();
559 return d->handle;
560}
561
563{
564 Q_D(QQuickSlider);
565 if (d->handle == handle)
566 return;
567
569
570 if (!d->handle.isExecuting())
571 d->cancelHandle();
572
573 const qreal oldImplicitHandleWidth = implicitHandleWidth();
574 const qreal oldImplicitHandleHeight = implicitHandleHeight();
575
576 d->removeImplicitSizeListener(d->handle);
578 d->handle = handle;
579
580 if (handle) {
581 if (!handle->parentItem())
582 handle->setParentItem(this);
583 d->addImplicitSizeListener(handle);
584 }
585
586 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
587 emit implicitHandleWidthChanged();
588 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
589 emit implicitHandleHeightChanged();
590 if (!d->handle.isExecuting())
592}
593
602qreal QQuickSlider::valueAt(qreal position) const
603{
604 Q_D(const QQuickSlider);
605 const qreal value = (d->to - d->from) * position;
606 if (qFuzzyIsNull(d->stepSize))
607 return d->from + value;
608 return d->from + qRound(value / d->stepSize) * d->stepSize;
609}
610
623{
624 Q_D(const QQuickSlider);
625 return d->live;
626}
627
629{
630 Q_D(QQuickSlider);
631 if (d->live == live)
632 return;
633
634 d->live = live;
635 emit liveChanged();
636}
637
646{
647 Q_D(QQuickSlider);
648 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
649 setValue(d->value + step);
650}
651
660{
661 Q_D(QQuickSlider);
662 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
663 setValue(d->value - step);
664}
665
677{
678 Q_D(const QQuickSlider);
679 return d->touchDragThreshold;
680}
681
683{
684 Q_D(QQuickSlider);
685 if (d->touchDragThreshold == touchDragThreshold)
686 return;
687
688 d->touchDragThreshold = touchDragThreshold;
689 emit touchDragThresholdChanged();
690}
691
696
712{
713 Q_D(const QQuickSlider);
714 if (!d->handle)
715 return 0;
716 return d->handle->implicitWidth();
717}
718
734{
735 Q_D(const QQuickSlider);
736 if (!d->handle)
737 return 0;
738 return d->handle->implicitHeight();
739}
740
742{
743 Q_D(QQuickSlider);
745
746 const qreal oldValue = d->value;
747 if (d->orientation == Qt::Horizontal) {
748 if (event->key() == Qt::Key_Left) {
749 setPressed(true);
750 if (isMirrored())
751 increase();
752 else
753 decrease();
754 event->accept();
755 } else if (event->key() == Qt::Key_Right) {
756 setPressed(true);
757 if (isMirrored())
758 decrease();
759 else
760 increase();
761 event->accept();
762 }
763 } else {
764 if (event->key() == Qt::Key_Up) {
765 setPressed(true);
766 increase();
767 event->accept();
768 } else if (event->key() == Qt::Key_Down) {
769 setPressed(true);
770 decrease();
771 event->accept();
772 }
773 }
774 if (!qFuzzyCompare(d->value, oldValue))
775 emit moved();
776}
777
783
785{
786 Q_D(QQuickSlider);
788 d->handleMove(event->position(), event->timestamp());
789 setKeepMouseGrab(true);
790}
791
792#if QT_CONFIG(quicktemplates2_multitouch)
794{
795 Q_D(QQuickSlider);
796 switch (event->type()) {
798 for (const QTouchEvent::TouchPoint &point : event->points()) {
799 if (!d->acceptTouch(point))
800 continue;
801
802 switch (point.state()) {
804 d->handlePress(point.position(), event->timestamp());
805 break;
807 if (!keepTouchGrab()) {
808 if (d->orientation == Qt::Horizontal)
809 setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point, qRound(d->touchDragThreshold)));
810 else
811 setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point, qRound(d->touchDragThreshold)));
812 }
813 if (keepTouchGrab())
814 d->handleMove(point.position(), event->timestamp());
815 break;
817 d->handleRelease(point.position(), event->timestamp());
818 break;
819 default:
820 break;
821 }
822 }
823 break;
824
825 default:
827 break;
828 }
829}
830#endif
831
832#if QT_CONFIG(wheelevent)
833void QQuickSlider::wheelEvent(QWheelEvent *event)
834{
835 Q_D(QQuickSlider);
836 QQuickControl::wheelEvent(event);
837 if (d->wheelEnabled) {
838 const qreal oldValue = d->value;
839 const QPointF angle = event->angleDelta();
840 const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / int(QWheelEvent::DefaultDeltasPerStep);
841 const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
842 setValue(oldValue + step * delta);
843 const bool wasMoved = !qFuzzyCompare(d->value, oldValue);
844 if (wasMoved)
845 emit moved();
846 }
847}
848#endif
849
855
857{
858 Q_D(QQuickSlider);
859 d->executeHandle(true);
861 setValue(d->value);
862 d->updatePosition();
863}
864
865#if QT_CONFIG(accessibility)
866void QQuickSlider::accessibilityActiveChanged(bool active)
867{
868 QQuickControl::accessibilityActiveChanged(active);
869
870 Q_D(QQuickSlider);
871 if (active)
872 setAccessibleProperty("pressed", d->pressed);
873}
874
875QAccessible::Role QQuickSlider::accessibleRole() const
876{
877 return QAccessible::Slider;
878}
879#endif
880
882
883#include "moc_qquickslider_p.cpp"
The QEventPoint class provides information about a point in a QPointerEvent.
Definition qeventpoint.h:20
@ TouchUpdate
Definition qcoreevent.h:242
The QKeyEvent class describes a key event.
Definition qevent.h:424
static constexpr Policy Preferred
static constexpr Policy Fixed
\inmodule QtGui
Definition qevent.h:196
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
void itemImplicitWidthChanged(QQuickItem *item) override
virtual bool handlePress(const QPointF &point, ulong timestamp)
static void hideOldItem(QQuickItem *item)
virtual void handleUngrab()
virtual bool handleRelease(const QPointF &point, ulong timestamp)
static void warnIfCustomizationNotSupported(QObject *control, QQuickItem *item, const QString &propertyName)
void itemDestroyed(QQuickItem *item) override
virtual bool handleMove(const QPointF &point, ulong timestamp)
void itemImplicitHeightChanged(QQuickItem *item) override
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void mousePressEvent(QMouseEvent *event) override
This event handler can be reimplemented in a subclass to receive mouse press events for an item.
bool setAccessibleProperty(const char *propertyName, const QVariant &value)
bool isMirrored() const
\qmlproperty bool QtQuick.Controls::Control::mirrored \readonly
virtual void mirrorChange()
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setKeepTouchGrab(bool)
Sets whether the touch points grabbed by this item should remain exclusively with this item.
virtual void keyPressEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key press events for an item.
void setParentItem(QQuickItem *parent)
void setAcceptTouchEvents(bool accept)
If enabled is true, this sets the item to accept touch events; otherwise, touch events are not accept...
void setAcceptedMouseButtons(Qt::MouseButtons buttons)
Sets the mouse buttons accepted by this item to buttons.
bool keepTouchGrab() const
Returns whether the touch points grabbed by this item should exclusively remain with this item.
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
void setKeepMouseGrab(bool)
Sets whether the mouse input should remain exclusively with this item.
virtual void touchEvent(QTouchEvent *event)
This event handler can be reimplemented in a subclass to receive touch events for an item.
virtual void keyReleaseEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key release events for an item.
void setFocusPolicy(Qt::FocusPolicy policy)
Sets the focus policy of this item to policy.
void setActiveFocusOnTab(bool)
Used to select a value by sliding a handle along a track.
bool handleRelease(const QPointF &point, ulong timestamp) override
qreal snapPosition(qreal position) const
void itemImplicitWidthChanged(QQuickItem *item) override
void setPosition(qreal position)
bool handleMove(const QPointF &point, ulong timestamp) override
void itemImplicitHeightChanged(QQuickItem *item) override
QQuickSlider::SnapMode snapMode
Qt::Orientation orientation
void handleUngrab() override
qreal positionAt(const QPointF &point) const
bool handlePress(const QPointF &point, ulong timestamp) override
QQuickDeferredPointer< QQuickItem > handle
void executeHandle(bool complete=false)
void itemDestroyed(QQuickItem *item) override
void setOrientation(Qt::Orientation orientation)
qreal implicitHandleHeight
void decrease()
\qmlmethod void QtQuick.Controls::Slider::decrease()
QQuickItem * handle
void increase()
\qmlmethod void QtQuick.Controls::Slider::increase()
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setHandle(QQuickItem *handle)
void stepSizeChanged()
void handleChanged()
void setStepSize(qreal step)
void setTouchDragThreshold(qreal touchDragThreshold)
void snapModeChanged()
void resetTouchDragThreshold()
void setLive(bool live)
SnapMode snapMode
void setPressed(bool pressed)
bool isHorizontal() const
void setFrom(qreal from)
void setSnapMode(SnapMode mode)
void pressedChanged()
void visualPositionChanged()
void keyReleaseEvent(QKeyEvent *event) override
This event handler can be reimplemented in a subclass to receive key release events for an item.
void fromChanged()
QQuickSlider(QQuickItem *parent=nullptr)
bool isVertical() const
void orientationChanged()
void valueChanged()
qreal implicitHandleWidth
void keyPressEvent(QKeyEvent *event) override
This event handler can be reimplemented in a subclass to receive key press events for an item.
void setValue(qreal value)
qreal touchDragThreshold
void mirrorChange() override
void setTo(qreal to)
bool isPressed() const
\qmlproperty bool QtQuick.Controls::Slider::pressed
Qt::Orientation orientation
void mousePressEvent(QMouseEvent *event) override
This event handler can be reimplemented in a subclass to receive mouse press events for an item.
void toChanged()
static bool dragOverThreshold(qreal d, Qt::Axis axis, const QEventPoint *tp, int startDragThreshold=-1)
The QTouchEvent class contains parameters that describe a touch event.
Definition qevent.h:917
Combined button and popup list for selecting options.
@ LeftButton
Definition qnamespace.h:58
@ TabFocus
Definition qnamespace.h:108
@ StrongFocus
Definition qnamespace.h:110
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
@ ArrowCursor
@ Key_Right
Definition qnamespace.h:679
@ Key_Left
Definition qnamespace.h:677
@ Key_Up
Definition qnamespace.h:678
@ Key_Down
Definition qnamespace.h:680
@ XAxis
@ YAxis
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
n void setPosition(void) \n\
GLuint64 GLenum void * handle
GLenum mode
GLsizei range
GLfloat angle
GLenum GLuint GLintptr offset
struct _cl_event * event
GLfixed GLfixed GLint GLint GLfixed points
GLuint GLfloat * val
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
void quickCancelDeferred(QObject *object, const QString &property)
void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer< T > &delegate)
void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer< T > &delegate)
#define QStringLiteral(str)
#define emit
static QString handleName()
unsigned long ulong
Definition qtypes.h:35
double qreal
Definition qtypes.h:187
item setCursor(Qt::IBeamCursor)
[1]
QGraphicsItem * item