Qt 6.x
The Qt SDK
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
79 qreal to = 1;
83 qreal touchDragThreshold = -1; // in QQuickWindowPrivate::dragOverThreshold, '-1' implies using styleHints::startDragDistance()
84 bool live = true;
85 bool pressed = false;
90};
91
93{
94 const qreal range = to - from;
96 return position;
97
98 const qreal effectiveStep = stepSize / range;
99 if (qFuzzyIsNull(effectiveStep))
100 return position;
101
102 return qRound(position / effectiveStep) * effectiveStep;
103}
104
106{
107 Q_Q(const QQuickSlider);
108 qreal pos = 0.0;
110 const qreal hw = handle ? handle->width() : 0;
111 const qreal offset = hw / 2;
112 const qreal extent = q->availableWidth() - hw;
113 if (!qFuzzyIsNull(extent)) {
114 if (q->isMirrored())
115 pos = (q->width() - point.x() - q->rightPadding() - offset) / extent;
116 else
117 pos = (point.x() - q->leftPadding() - offset) / extent;
118 }
119 } else {
120 const qreal hh = handle ? handle->height() : 0;
121 const qreal offset = hh / 2;
122 const qreal extent = q->availableHeight() - hh;
123 if (!qFuzzyIsNull(extent))
124 pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent;
125 }
126 return qBound<qreal>(0.0, pos, 1.0);
127}
128
130{
131 Q_Q(QQuickSlider);
132 pos = qBound<qreal>(0.0, pos, 1.0);
134 return;
135
136 position = pos;
137 emit q->positionChanged();
138 emit q->visualPositionChanged();
139}
140
142{
143 qreal pos = 0;
144 if (!qFuzzyCompare(from, to))
145 pos = (value - from) / (to - from);
147}
148
149bool QQuickSliderPrivate::handlePress(const QPointF &point, ulong timestamp)
150{
151 Q_Q(QQuickSlider);
152 QQuickControlPrivate::handlePress(point, timestamp);
153 pressPoint = point;
154 q->setPressed(true);
155 return true;
156}
157
158bool QQuickSliderPrivate::handleMove(const QPointF &point, ulong timestamp)
159{
160 Q_Q(QQuickSlider);
161 QQuickControlPrivate::handleMove(point, timestamp);
162 const qreal oldPos = position;
163 qreal pos = positionAt(point);
166 if (live)
167 q->setValue(q->valueAt(pos));
170 if (!qFuzzyCompare(pos, oldPos))
171 emit q->moved();
172 return true;
173}
174
176{
177 Q_Q(QQuickSlider);
178 QQuickControlPrivate::handleRelease(point, timestamp);
180 const qreal oldPos = position;
181 qreal pos = positionAt(point);
184 qreal val = q->valueAt(pos);
185 if (!qFuzzyCompare(val, value))
186 q->setValue(val);
187 else if (snapMode != QQuickSlider::NoSnap)
189 if (!qFuzzyCompare(pos, oldPos))
190 emit q->moved();
191 q->setKeepMouseGrab(false);
192 q->setKeepTouchGrab(false);
193 q->setPressed(false);
194 return true;
195}
196
198{
199 Q_Q(QQuickSlider);
202 q->setPressed(false);
203}
204
206{
207 Q_Q(QQuickSlider);
209}
210
212{
213 Q_Q(QQuickSlider);
214 if (handle.wasExecuted())
215 return;
216
217 if (!handle || complete)
219 if (complete)
221}
222
224{
225 Q_Q(QQuickSlider);
227 if (item == handle)
228 emit q->implicitHandleWidthChanged();
229}
230
232{
233 Q_Q(QQuickSlider);
235 if (item == handle)
236 emit q->implicitHandleHeightChanged();
237}
238
241{
243#ifdef Q_OS_MACOS
245#else
247#endif
249#if QT_CONFIG(quicktemplates2_multitouch)
251#endif
252#if QT_CONFIG(cursor)
254#endif
255}
256
258{
259 Q_D(QQuickSlider);
260 d->removeImplicitSizeListener(d->handle);
261}
262
271{
272 Q_D(const QQuickSlider);
273 return d->from;
274}
275
277{
278 Q_D(QQuickSlider);
279 if (qFuzzyCompare(d->from, from))
280 return;
281
282 d->from = from;
284 if (isComponentComplete()) {
285 setValue(d->value);
286 d->updatePosition();
287 }
288}
289
298{
299 Q_D(const QQuickSlider);
300 return d->to;
301}
302
304{
305 Q_D(QQuickSlider);
306 if (qFuzzyCompare(d->to, to))
307 return;
308
309 d->to = to;
310 emit toChanged();
311 if (isComponentComplete()) {
312 setValue(d->value);
313 d->updatePosition();
314 }
315}
316
325{
326 Q_D(const QQuickSlider);
327 return d->value;
328}
329
331{
332 Q_D(QQuickSlider);
334 value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
335
336 if (qFuzzyCompare(d->value, value))
337 return;
338
339 d->value = value;
340 d->updatePosition();
342}
343
357{
358 Q_D(const QQuickSlider);
359 return d->position;
360}
361
376{
377 Q_D(const QQuickSlider);
378 if (d->orientation == Qt::Vertical || isMirrored())
379 return 1.0 - d->position;
380 return d->position;
381}
382
391{
392 Q_D(const QQuickSlider);
393 return d->stepSize;
394}
395
397{
398 Q_D(QQuickSlider);
399 if (qFuzzyCompare(d->stepSize, step))
400 return;
401
402 d->stepSize = step;
404}
405
434{
435 Q_D(const QQuickSlider);
436 return d->snapMode;
437}
438
440{
441 Q_D(QQuickSlider);
442 if (d->snapMode == mode)
443 return;
444
445 d->snapMode = mode;
447}
448
456{
457 Q_D(const QQuickSlider);
458 return d->pressed;
459}
460
461void QQuickSlider::setPressed(bool pressed)
462{
463 Q_D(QQuickSlider);
464 if (d->pressed == pressed)
465 return;
466
467 d->pressed = pressed;
468 setAccessibleProperty("pressed", pressed);
470}
471
482{
483 Q_D(const QQuickSlider);
484 return d->orientation == Qt::Horizontal;
485}
486
497{
498 Q_D(const QQuickSlider);
499 return d->orientation == Qt::Vertical;
500}
501
514{
515 Q_D(const QQuickSlider);
516 return d->orientation;
517}
518
520{
521 Q_D(QQuickSlider);
522 if (d->orientation == orientation)
523 return;
524
525 d->orientation = orientation;
527}
528
537{
538 QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func());
539 if (!d->handle)
540 d->executeHandle();
541 return d->handle;
542}
543
545{
546 Q_D(QQuickSlider);
547 if (d->handle == handle)
548 return;
549
551
552 if (!d->handle.isExecuting())
553 d->cancelHandle();
554
555 const qreal oldImplicitHandleWidth = implicitHandleWidth();
556 const qreal oldImplicitHandleHeight = implicitHandleHeight();
557
558 d->removeImplicitSizeListener(d->handle);
560 d->handle = handle;
561
562 if (handle) {
563 if (!handle->parentItem())
564 handle->setParentItem(this);
565 d->addImplicitSizeListener(handle);
566 }
567
568 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
569 emit implicitHandleWidthChanged();
570 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
571 emit implicitHandleHeightChanged();
572 if (!d->handle.isExecuting())
574}
575
584qreal QQuickSlider::valueAt(qreal position) const
585{
586 Q_D(const QQuickSlider);
587 const qreal value = (d->to - d->from) * position;
588 if (qFuzzyIsNull(d->stepSize))
589 return d->from + value;
590 return d->from + qRound(value / d->stepSize) * d->stepSize;
591}
592
605{
606 Q_D(const QQuickSlider);
607 return d->live;
608}
609
611{
612 Q_D(QQuickSlider);
613 if (d->live == live)
614 return;
615
616 d->live = live;
617 emit liveChanged();
618}
619
628{
629 Q_D(QQuickSlider);
630 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
631 setValue(d->value + step);
632}
633
642{
643 Q_D(QQuickSlider);
644 qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
645 setValue(d->value - step);
646}
647
659{
660 Q_D(const QQuickSlider);
661 return d->touchDragThreshold;
662}
663
665{
666 Q_D(QQuickSlider);
667 if (d->touchDragThreshold == touchDragThreshold)
668 return;
669
670 d->touchDragThreshold = touchDragThreshold;
671 emit touchDragThresholdChanged();
672}
673
675{
677}
678
694{
695 Q_D(const QQuickSlider);
696 if (!d->handle)
697 return 0;
698 return d->handle->implicitWidth();
699}
700
716{
717 Q_D(const QQuickSlider);
718 if (!d->handle)
719 return 0;
720 return d->handle->implicitHeight();
721}
722
724{
725 Q_D(QQuickSlider);
727
728 const qreal oldValue = d->value;
729 if (d->orientation == Qt::Horizontal) {
730 if (event->key() == Qt::Key_Left) {
731 setPressed(true);
732 if (isMirrored())
733 increase();
734 else
735 decrease();
736 event->accept();
737 } else if (event->key() == Qt::Key_Right) {
738 setPressed(true);
739 if (isMirrored())
740 decrease();
741 else
742 increase();
743 event->accept();
744 }
745 } else {
746 if (event->key() == Qt::Key_Up) {
747 setPressed(true);
748 increase();
749 event->accept();
750 } else if (event->key() == Qt::Key_Down) {
751 setPressed(true);
752 decrease();
753 event->accept();
754 }
755 }
756 if (!qFuzzyCompare(d->value, oldValue))
757 emit moved();
758}
759
761{
763 setPressed(false);
764}
765
767{
768 Q_D(QQuickSlider);
770 d->handleMove(event->position(), event->timestamp());
771 setKeepMouseGrab(true);
772}
773
774#if QT_CONFIG(quicktemplates2_multitouch)
776{
777 Q_D(QQuickSlider);
778 switch (event->type()) {
780 for (const QTouchEvent::TouchPoint &point : event->points()) {
781 if (!d->acceptTouch(point))
782 continue;
783
784 switch (point.state()) {
786 d->handlePress(point.position(), event->timestamp());
787 break;
789 if (!keepTouchGrab()) {
790 if (d->orientation == Qt::Horizontal)
791 setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point, qRound(d->touchDragThreshold)));
792 else
793 setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point, qRound(d->touchDragThreshold)));
794 }
795 if (keepTouchGrab())
796 d->handleMove(point.position(), event->timestamp());
797 break;
799 d->handleRelease(point.position(), event->timestamp());
800 break;
801 default:
802 break;
803 }
804 }
805 break;
806
807 default:
809 break;
810 }
811}
812#endif
813
814#if QT_CONFIG(wheelevent)
815void QQuickSlider::wheelEvent(QWheelEvent *event)
816{
817 Q_D(QQuickSlider);
818 QQuickControl::wheelEvent(event);
819 if (d->wheelEnabled) {
820 const qreal oldValue = d->value;
821 const QPointF angle = event->angleDelta();
822 const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / int(QWheelEvent::DefaultDeltasPerStep);
823 const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
824 setValue(oldValue + step * delta);
825 const bool wasMoved = !qFuzzyCompare(d->value, oldValue);
826 if (wasMoved)
827 emit moved();
828 }
829}
830#endif
831
833{
836}
837
839{
840 Q_D(QQuickSlider);
841 d->executeHandle(true);
843 setValue(d->value);
844 d->updatePosition();
845}
846
847#if QT_CONFIG(accessibility)
848void QQuickSlider::accessibilityActiveChanged(bool active)
849{
850 QQuickControl::accessibilityActiveChanged(active);
851
852 Q_D(QQuickSlider);
853 if (active)
854 setAccessibleProperty("pressed", d->pressed);
855}
856
857QAccessible::Role QQuickSlider::accessibleRole() const
858{
859 return QAccessible::Slider;
860}
861#endif
862
864
865#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:423
\inmodule QtGui
Definition qevent.h:195
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:333
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:338
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)
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 setFocusPolicy(Qt::FocusPolicy policy)
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:64
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 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 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:916
Combined button and popup list for selecting options.
@ LeftButton
Definition qnamespace.h:57
@ TabFocus
Definition qnamespace.h:107
@ StrongFocus
Definition qnamespace.h:109
Orientation
Definition qnamespace.h:97
@ Horizontal
Definition qnamespace.h:98
@ Vertical
Definition qnamespace.h:99
@ ArrowCursor
@ Key_Right
Definition qnamespace.h:674
@ Key_Left
Definition qnamespace.h:672
@ Key_Up
Definition qnamespace.h:673
@ Key_Down
Definition qnamespace.h:675
@ XAxis
@ YAxis
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
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:30
double qreal
Definition qtypes.h:92
item setCursor(Qt::IBeamCursor)
[1]
QGraphicsItem * item
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent