View difference between Paste ID: hzStXsKe and VxJHQ6LT
SHOW: | | - or go back to the newest paste.
1
/****************************************************************************
2
**
3
** Copyright (C) 2017 The Qt Company Ltd.
4
** Contact: http://www.qt.io/licensing/
5
**
6
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
7
**
8
** $QT_BEGIN_LICENSE:LGPL3$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see http://www.qt.io/terms-conditions. For further
15
** information use the contact form at http://www.qt.io/contact-us.
16
**
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or later as published by the Free
28
** Software Foundation and appearing in the file LICENSE.GPL included in
29
** the packaging of this file. Please review the following information to
30
** ensure the GNU General Public License version 2.0 requirements will be
31
** met: http://www.gnu.org/licenses/gpl-2.0.html.
32
**
33
** $QT_END_LICENSE$
34
**
35
****************************************************************************/
36
37
#include "customqquickdial.h"
38
#include "QtQuickTemplates2/private/qquickdeferredexecute_p_p.h"
39
40
#include <QtCore/qmath.h>
41
#include <QtQuick/private/qquickflickable_p.h>
42
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
43
44
QT_BEGIN_NAMESPACE
45
46
/*!
47
    \qmltype Dial
48
    \inherits Control
49
    \instantiates CustomQQuickDial
50
    \inqmlmodule QtQuick.Controls
51
    \since 5.7
52
    \ingroup qtquickcontrols2-input
53
    \brief Circular dial that is rotated to set a value.
54
55
    The Dial is similar to a traditional dial knob that is found on devices
56
    such as stereos or industrial equipment. It allows the user to specify a
57
    value within a range.
58
59
    \image qtquickcontrols2-dial-no-wrap.gif
60
61
    The value of the dial is set with the \l value property. The range is
62
    set with the \l from and \l to properties. To enable or disable wrapping,
63
    use the \l wrap property.
64
65
    The dial can be manipulated with a keyboard. It supports the following
66
    actions:
67
68
    \table
69
    \header \li \b {Action} \li \b {Key}
70
    \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Left
71
    \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Down
72
    \row \li Set \l value to \l from \li \c Qt.Key_Home
73
    \row \li Increase \l value by \l stepSize \li \c Qt.Key_Right
74
    \row \li Increase \l value by \l stepSize \li \c Qt.Key_Up
75
    \row \li Set \l value to \l to \li \c Qt.Key_End
76
    \endtable
77
78
    \include qquickdial.qdocinc inputMode
79
80
    \sa {Customizing Dial}, {Input Controls}
81
*/
82
83
/*!
84
    \since QtQuick.Controls 2.2 (Qt 5.9)
85
    \qmlsignal QtQuick.Controls::Dial::moved()
86
87
    This signal is emitted when the dial has been interactively moved
88
    by the user by either touch, mouse, or keys.
89
*/
90
91
static const qreal startAngleRadians = (M_PI / 2.0); //240
92
static const qreal startAngle = 0; //-140
93
static const qreal endAngleRadians = (M_PI * 2.0)/* * (5.0 / 4.0)*/; //300
94
static const qreal endAngle = 360; //140
95
96
class CustomQQuickDialPrivate : public QQuickControlPrivate
97
{
98
    Q_DECLARE_PUBLIC(CustomQQuickDial)
99
100
public:
101
    qreal valueAt(qreal position) const;
102
    qreal snapPosition(qreal position) const;
103
    qreal positionAt(const QPointF &point) const;
104
    qreal circularPositionAt(const QPointF &point) const;
105
    qreal linearPositionAt(const QPointF &point) const;
106
    void setPosition(qreal position);
107
    void updatePosition();
108
    bool isLargeChange(const QPointF &eventPos, qreal proposedPosition) const;
109
    bool isHorizontalOrVertical() const;
110
111
    void handlePress(const QPointF &point) override;
112
    void handleMove(const QPointF &point) override;
113
    void handleRelease(const QPointF &point) override;
114
    void handleUngrab() override;
115
116
    void cancelHandle();
117
    void executeHandle(bool complete = false);
118
119
    qreal from = 0;
120
    qreal to = 1;
121
    qreal value = 0;
122
    qreal position = 0;
123
    qreal angle = startAngle;
124
    qreal stepSize = 0;
125
    bool pressed = false;
126
    QPointF pressPoint;
127
    qreal positionBeforePress = 0;
128
    CustomQQuickDial::SnapMode snapMode = CustomQQuickDial::NoSnap;
129
    CustomQQuickDial::InputMode inputMode = CustomQQuickDial::Circular;
130
    bool wrap = false;
131
    bool live = true;
132
    QQuickDeferredPointer<QQuickItem> handle;
133
};
134
135
qreal CustomQQuickDialPrivate::valueAt(qreal position) const
136
{
137
    return from + (to - from) * position;
138
}
139
140
qreal CustomQQuickDialPrivate::snapPosition(qreal position) const
141
{
142
    const qreal range = to - from;
143
    if (qFuzzyIsNull(range))
144
        return position;
145
146
    const qreal effectiveStep = stepSize / range;
147
    if (qFuzzyIsNull(effectiveStep))
148
        return position;
149
150
    if((position + effectiveStep) > to)
151
        return from;
152
153
    return qRound(position / effectiveStep) * effectiveStep;
154
}
155
156
qreal CustomQQuickDialPrivate::positionAt(const QPointF &point) const
157
{
158
    return inputMode == CustomQQuickDial::Circular ? circularPositionAt(point) : linearPositionAt(point);
159
}
160
161
qreal CustomQQuickDialPrivate::circularPositionAt(const QPointF &point) const
162
{
163
    qreal yy = height / 2.0 - point.y();
164
    qreal xx = point.x() - width / 2.0;
165
    qreal angle = (xx || yy) ? std::atan2(yy, xx) : 0;
166
167
    angle = -angle;
168
    angle += M_PI/2;
169
170
    if (angle < 0)
171
        angle = angle + M_PI * 2;
172
173
    angle /= 2.0 * M_PI;
174
175
    return angle;
176
}
177
178
qreal CustomQQuickDialPrivate::linearPositionAt(const QPointF &point) const
179
{
180
    // This value determines the range (either horizontal or vertical)
181
    // within which the dial can be dragged.
182
    // The larger this value is, the further the drag distance
183
    // must be to go from a position of e.g. 0.0 to 1.0.
184
    qreal dragArea = 0;
185
186
    // The linear input mode uses a "relative" input system,
187
    // where the distance from the press point is used to calculate
188
    // the change in position. Moving the mouse above the press
189
    // point increases the position (when inputMode is Vertical),
190
    // and vice versa. This prevents the dial from jumping when clicked.
191
    qreal dragDistance = 0;
192
193
    if (inputMode == CustomQQuickDial::Horizontal) {
194
        dragArea = width * 2;
195
        dragDistance = pressPoint.x() - point.x();
196
    } else {
197
        dragArea = height * 2;
198
        dragDistance = point.y() - pressPoint.y();
199
    }
200
    const qreal normalisedDifference = dragDistance / dragArea;
201
    return qBound(0.0, positionBeforePress - normalisedDifference, 1.0);
202
}
203
204
void CustomQQuickDialPrivate::setPosition(qreal pos)
205
{
206
    Q_Q(CustomQQuickDial);
207
    pos = qBound<qreal>(0.0, pos, 1.0);
208
    if (qFuzzyCompare(position, pos))
209
        return;
210
211
    position = pos;
212
213
    angle = startAngle + position * qAbs(endAngle - startAngle);
214
215
    emit q->positionChanged();
216
    emit q->angleChanged();
217
}
218
219
void CustomQQuickDialPrivate::updatePosition()
220
{
221
    qreal pos = 0;
222
    if (!qFuzzyCompare(from, to))
223
        pos = (value - from) / (to - from);
224
    setPosition(pos);
225
}
226
227
bool CustomQQuickDialPrivate::isLargeChange(const QPointF &eventPos, qreal proposedPosition) const
228
{
229
    return qAbs(proposedPosition - position) >= 0.5 && eventPos.y() >= height / 2;
230
}
231
232
bool CustomQQuickDialPrivate::isHorizontalOrVertical() const
233
{
234
    return inputMode == CustomQQuickDial::Horizontal || inputMode == CustomQQuickDial::Vertical;
235
}
236
237
void CustomQQuickDialPrivate::handlePress(const QPointF &point)
238
{
239
    Q_Q(CustomQQuickDial);
240
    QQuickControlPrivate::handlePress(point);
241
    pressPoint = point;
242
    positionBeforePress = position;
243
    q->setPressed(true);
244
}
245
246
void CustomQQuickDialPrivate::handleMove(const QPointF &point)
247
{
248
    Q_Q(CustomQQuickDial);
249
    QQuickControlPrivate::handleMove(point);
250
    const qreal oldPos = position;
251
    qreal pos = positionAt(point);
252
    if (snapMode == CustomQQuickDial::SnapAlways)
253
        pos = snapPosition(pos);
254
255
    if (wrap || (!wrap && (isHorizontalOrVertical() || !isLargeChange(point, pos)))) {
256
        if (live)
257
            q->setValue(valueAt(pos));
258
        else
259
            setPosition(pos);
260
        if (!qFuzzyCompare(pos, oldPos))
261
            emit q->moved();
262
    }
263
}
264
265
void CustomQQuickDialPrivate::handleRelease(const QPointF &point)
266
{
267
    Q_Q(CustomQQuickDial);
268
    QQuickControlPrivate::handleRelease(point);
269
    if (q->keepMouseGrab() || q->keepTouchGrab()) {
270
        const qreal oldPos = position;
271
        qreal pos = positionAt(point);
272
        if (snapMode != CustomQQuickDial::NoSnap)
273
            pos = snapPosition(pos);
274
275
        if (wrap || (!wrap && (isHorizontalOrVertical() || !isLargeChange(point, pos))))
276
            q->setValue(valueAt(pos));
277
        if (!qFuzzyCompare(pos, oldPos))
278
            emit q->moved();
279
280
        q->setKeepMouseGrab(false);
281
        q->setKeepTouchGrab(false);
282
    }
283
284
    q->setPressed(false);
285
    pressPoint = QPointF();
286
    positionBeforePress = 0;
287
}
288
289
void CustomQQuickDialPrivate::handleUngrab()
290
{
291
    Q_Q(CustomQQuickDial);
292
    QQuickControlPrivate::handleUngrab();
293
    pressPoint = QPointF();
294
    positionBeforePress = 0;
295
    q->setPressed(false);
296
}
297
298
static inline QString handleName() { return QStringLiteral("handle"); }
299
300
void CustomQQuickDialPrivate::cancelHandle()
301
{
302
    Q_Q(CustomQQuickDial);
303
    quickCancelDeferred(q, handleName());
304
}
305
306
void CustomQQuickDialPrivate::executeHandle(bool complete)
307
{
308
    Q_Q(CustomQQuickDial);
309
    if (handle.wasExecuted())
310
        return;
311
312
    if (!handle || complete)
313
        quickBeginDeferred(q, handleName(), handle);
314
    if (complete)
315
        quickCompleteDeferred(q, handleName(), handle);
316
}
317
318
CustomQQuickDial::CustomQQuickDial(QQuickItem *parent)
319
    : QQuickControl(*(new CustomQQuickDialPrivate), parent)
320
{
321
    setActiveFocusOnTab(true);
322
    setAcceptedMouseButtons(Qt::LeftButton);
323
#if QT_CONFIG(cursor)
324
    setCursor(Qt::ArrowCursor);
325
#endif
326
}
327
328
/*!
329
    \qmlproperty real QtQuick.Controls::Dial::from
330
331
    This property holds the starting value for the range. The default value is \c 0.0.
332
333
    \sa to, value
334
*/
335
qreal CustomQQuickDial::from() const
336
{
337
    Q_D(const CustomQQuickDial);
338
    return d->from;
339
}
340
341
void CustomQQuickDial::setFrom(qreal from)
342
{
343
    Q_D(CustomQQuickDial);
344
    if (qFuzzyCompare(d->from, from))
345
        return;
346
347
    d->from = from;
348
    emit fromChanged();
349
    if (isComponentComplete()) {
350
        setValue(d->value);
351
        d->updatePosition();
352
    }
353
}
354
355
/*!
356
    \qmlproperty real QtQuick.Controls::Dial::to
357
358
    This property holds the end value for the range. The default value is
359
    \c 1.0.
360
361
    \sa from, value
362
*/
363
qreal CustomQQuickDial::to() const
364
{
365
    Q_D(const CustomQQuickDial);
366
    return d->to;
367
}
368
369
void CustomQQuickDial::setTo(qreal to)
370
{
371
    Q_D(CustomQQuickDial);
372
    if (qFuzzyCompare(d->to, to))
373
        return;
374
375
    d->to = to;
376
    emit toChanged();
377
    if (isComponentComplete()) {
378
        setValue(d->value);
379
        d->updatePosition();
380
    }
381
}
382
383
/*!
384
    \qmlproperty real QtQuick.Controls::Dial::value
385
386
    This property holds the value in the range \c from - \c to. The default
387
    value is \c 0.0.
388
389
    \sa position, live
390
*/
391
qreal CustomQQuickDial::value() const
392
{
393
    Q_D(const CustomQQuickDial);
394
    return d->value;
395
}
396
397
void CustomQQuickDial::setValue(qreal value)
398
{
399
    Q_D(CustomQQuickDial);
400
    if (isComponentComplete())
401
        value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
402
403
    if (qFuzzyCompare(d->value, value))
404
        return;
405
406
    d->value = value;
407
    d->updatePosition();
408
    emit valueChanged();
409
}
410
411
/*!
412
    \qmlproperty real QtQuick.Controls::Dial::position
413
    \readonly
414
415
    This property holds the logical position of the handle.
416
417
    The position is expressed as a fraction of the control's angle range (the
418
    range within which the handle can be moved) in the range \c {0.0 - 1.0}.
419
420
    \sa value, angle
421
*/
422
qreal CustomQQuickDial::position() const
423
{
424
    Q_D(const CustomQQuickDial);
425
    return d->position;
426
}
427
428
/*!
429
    \qmlproperty real QtQuick.Controls::Dial::angle
430
    \readonly
431
432
    This property holds the angle of the handle.
433
434
    The range is from \c -140 degrees to \c 140 degrees.
435
436
    \sa position
437
*/
438
qreal CustomQQuickDial::angle() const
439
{
440
    Q_D(const CustomQQuickDial);
441
    return d->angle;
442
}
443
444
/*!
445
    \qmlproperty real QtQuick.Controls::Dial::stepSize
446
447
    This property holds the step size.
448
449
    The step size determines the amount by which the dial's value
450
    is increased and decreased when interacted with via the keyboard.
451
    For example, a step size of \c 0.2, will result in the dial's
452
    value increasing and decreasing in increments of \c 0.2.
453
454
    The step size is only respected for touch and mouse interaction
455
    when \l snapMode is set to a value other than \c Dial.NoSnap.
456
457
    The default value is \c 0.0, which results in an effective step
458
    size of \c 0.1 for keyboard interaction.
459
460
    \sa snapMode, increase(), decrease()
461
*/
462
qreal CustomQQuickDial::stepSize() const
463
{
464
    Q_D(const CustomQQuickDial);
465
    return d->stepSize;
466
}
467
468
void CustomQQuickDial::setStepSize(qreal step)
469
{
470
    Q_D(CustomQQuickDial);
471
    if (qFuzzyCompare(d->stepSize, step))
472
        return;
473
474
    d->stepSize = step;
475
    emit stepSizeChanged();
476
}
477
478
/*!
479
    \qmlproperty enumeration QtQuick.Controls::Dial::snapMode
480
481
    This property holds the snap mode.
482
483
    The snap mode works with the \l stepSize to allow the handle to snap to
484
    certain points along the dial.
485
486
    Possible values:
487
    \value Dial.NoSnap The dial does not snap (default).
488
    \value Dial.SnapAlways The dial snaps while the handle is dragged.
489
    \value Dial.SnapOnRelease The dial does not snap while being dragged, but only after the handle is released.
490
491
    \sa stepSize
492
*/
493
CustomQQuickDial::SnapMode CustomQQuickDial::snapMode() const
494
{
495
    Q_D(const CustomQQuickDial);
496
    return d->snapMode;
497
}
498
499
void CustomQQuickDial::setSnapMode(SnapMode mode)
500
{
501
    Q_D(CustomQQuickDial);
502
    if (d->snapMode == mode)
503
        return;
504
505
    d->snapMode = mode;
506
    emit snapModeChanged();
507
}
508
509
/*!
510
    \since QtQuick.Controls 2.5 (Qt 5.12)
511
    \qmlproperty enumeration QtQuick.Controls::Dial::inputMode
512
513
    This property holds the input mode.
514
515
    \include qquickdial.qdocinc inputMode
516
517
    The default value is \c Dial.Circular.
518
*/
519
CustomQQuickDial::InputMode CustomQQuickDial::inputMode() const
520
{
521
    Q_D(const CustomQQuickDial);
522
    return d->inputMode;
523
}
524
525
void CustomQQuickDial::setInputMode(CustomQQuickDial::InputMode mode)
526
{
527
    Q_D(CustomQQuickDial);
528
    if (d->inputMode == mode)
529
        return;
530
531
    d->inputMode = mode;
532
    emit inputModeChanged();
533
}
534
535
/*!
536
    \qmlproperty bool QtQuick.Controls::Dial::wrap
537
538
    This property holds whether the dial wraps when dragged.
539
540
    For example, when this property is set to \c true, dragging the dial past
541
    the \l to position will result in the handle being positioned at the
542
    \l from position, and vice versa:
543
544
    \image qtquickcontrols2-dial-wrap.gif
545
546
    When this property is \c false, it's not possible to drag the dial across
547
    the from and to values.
548
549
    \image qtquickcontrols2-dial-no-wrap.gif
550
551
    The default value is \c false.
552
*/
553
bool CustomQQuickDial::wrap() const
554
{
555
    Q_D(const CustomQQuickDial);
556
    return d->wrap;
557
}
558
559
void CustomQQuickDial::setWrap(bool wrap)
560
{
561
    Q_D(CustomQQuickDial);
562
    if (d->wrap == wrap)
563
        return;
564
565
    d->wrap = wrap;
566
    emit wrapChanged();
567
}
568
569
/*!
570
    \qmlproperty bool QtQuick.Controls::Dial::pressed
571
572
    This property holds whether the dial is pressed.
573
574
    The dial will be pressed when either the mouse is pressed over it, or a key
575
    such as \c Qt.Key_Left is held down. If you'd prefer not to have the dial
576
    be pressed upon key presses (due to styling reasons, for example), you can
577
    use the \l {Keys}{Keys attached property}:
578
579
    \code
580
    Dial {
581
        Keys.onLeftPressed: {}
582
    }
583
    \endcode
584
585
    This will result in pressed only being \c true upon mouse presses.
586
*/
587
bool CustomQQuickDial::isPressed() const
588
{
589
    Q_D(const CustomQQuickDial);
590
    return d->pressed;
591
}
592
593
void CustomQQuickDial::setPressed(bool pressed)
594
{
595
    Q_D(CustomQQuickDial);
596
    if (d->pressed == pressed)
597
        return;
598
599
    d->pressed = pressed;
600
    setAccessibleProperty("pressed", pressed);
601
    emit pressedChanged();
602
}
603
604
/*!
605
    \qmlproperty Item QtQuick.Controls::Dial::handle
606
607
    This property holds the handle of the dial.
608
609
    The handle acts as a visual indicator of the position of the dial.
610
611
    \sa {Customizing Dial}
612
*/
613
QQuickItem *CustomQQuickDial::handle() const
614
{
615
    CustomQQuickDialPrivate *d = const_cast<CustomQQuickDialPrivate *>(d_func());
616
    if (!d->handle)
617
        d->executeHandle();
618
    return d->handle;
619
}
620
621
void CustomQQuickDial::setHandle(QQuickItem *handle)
622
{
623
    Q_D(CustomQQuickDial);
624
    if (handle == d->handle)
625
        return;
626
627
    if (!d->handle.isExecuting())
628
        d->cancelHandle();
629
630
    delete d->handle;
631
    d->handle = handle;
632
    if (d->handle && !d->handle->parentItem())
633
        d->handle->setParentItem(this);
634
    if (!d->handle.isExecuting())
635
        emit handleChanged();
636
}
637
638
/*!
639
    \since QtQuick.Controls 2.2 (Qt 5.9)
640
    \qmlproperty bool QtQuick.Controls::Dial::live
641
642
    This property holds whether the dial provides live updates for the \l value
643
    property while the handle is dragged.
644
645
    The default value is \c true.
646
647
    \sa value
648
*/
649
bool CustomQQuickDial::live() const
650
{
651
    Q_D(const CustomQQuickDial);
652
    return d->live;
653
}
654
655
void CustomQQuickDial::setLive(bool live)
656
{
657
    Q_D(CustomQQuickDial);
658
    if (d->live == live)
659
        return;
660
661
    d->live = live;
662
    emit liveChanged();
663
}
664
665
/*!
666
    \qmlmethod void QtQuick.Controls::Dial::increase()
667
668
    Increases the value by \l stepSize, or \c 0.1 if stepSize is not defined.
669
670
    \sa stepSize
671
*/
672
void CustomQQuickDial::increase()
673
{
674
    Q_D(CustomQQuickDial);
675
    qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
676
    setValue(d->value + step);
677
}
678
679
/*!
680
    \qmlmethod void QtQuick.Controls::Dial::decrease()
681
682
    Decreases the value by \l stepSize, or \c 0.1 if stepSize is not defined.
683
684
    \sa stepSize
685
*/
686
void CustomQQuickDial::decrease()
687
{
688
    Q_D(CustomQQuickDial);
689
    qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
690
    setValue(d->value - step);
691
}
692
693
void CustomQQuickDial::keyPressEvent(QKeyEvent *event)
694
{
695
    Q_D(CustomQQuickDial);
696
    const qreal oldValue = d->value;
697
    switch (event->key()) {
698
    case Qt::Key_Left:
699
    case Qt::Key_Down:
700
        setPressed(true);
701
        if (isMirrored())
702
            increase();
703
        else
704
            decrease();
705
        break;
706
707
    case Qt::Key_Right:
708
    case Qt::Key_Up:
709
        setPressed(true);
710
        if (isMirrored())
711
            decrease();
712
        else
713
            increase();
714
        break;
715
716
    case Qt::Key_Home:
717
        setPressed(true);
718
        setValue(isMirrored() ? d->to : d->from);
719
        break;
720
721
    case Qt::Key_End:
722
        setPressed(true);
723
        setValue(isMirrored() ? d->from : d->to);
724
        break;
725
726
    default:
727
        event->ignore();
728
        QQuickControl::keyPressEvent(event);
729
        break;
730
    }
731
    if (!qFuzzyCompare(d->value, oldValue))
732
        emit moved();
733
}
734
735
void CustomQQuickDial::keyReleaseEvent(QKeyEvent *event)
736
{
737
    QQuickControl::keyReleaseEvent(event);
738
    setPressed(false);
739
}
740
741
void CustomQQuickDial::mousePressEvent(QMouseEvent *event)
742
{
743
    Q_D(CustomQQuickDial);
744
    QQuickControl::mousePressEvent(event);
745
    d->handleMove(event->localPos());
746
    setKeepMouseGrab(true);
747
}
748
749
#if QT_CONFIG(quicktemplates2_multitouch)
750
void CustomQQuickDial::touchEvent(QTouchEvent *event)
751
{
752
    Q_D(CustomQQuickDial);
753
    switch (event->type()) {
754
    case QEvent::TouchUpdate:
755
        for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
756
            if (!d->acceptTouch(point))
757
                continue;
758
759
            switch (point.state()) {
760
            case Qt::TouchPointMoved:
761
                if (!keepTouchGrab()) {
762
                    bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().x() - d->pressPoint.x(), Qt::XAxis, &point);
763
                    setKeepTouchGrab(overXDragThreshold);
764
765
                    if (!overXDragThreshold) {
766
                        bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point);
767
                        setKeepTouchGrab(overYDragThreshold);
768
                    }
769
                }
770
                if (keepTouchGrab())
771
                    d->handleMove(point.pos());
772
                break;
773
774
            default:
775
                QQuickControl::touchEvent(event);
776
                break;
777
            }
778
        }
779
        break;
780
781
    default:
782
        QQuickControl::touchEvent(event);
783
        break;
784
    }
785
}
786
#endif
787
788
#if QT_CONFIG(wheelevent)
789
void CustomQQuickDial::wheelEvent(QWheelEvent *event)
790
{
791
    Q_D(CustomQQuickDial);
792
    QQuickControl::wheelEvent(event);
793
    if (d->wheelEnabled) {
794
        const qreal oldValue = d->value;
795
        const QPointF angle = event->angleDelta();
796
        const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / QWheelEvent::DefaultDeltasPerStep;
797
        const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
798
        setValue(oldValue + step * delta);
799
        event->setAccepted(!qFuzzyCompare(d->value, oldValue));
800
    }
801
}
802
#endif
803
804
void CustomQQuickDial::mirrorChange()
805
{
806
    QQuickControl::mirrorChange();
807
    emit angleChanged();
808
}
809
810
void CustomQQuickDial::componentComplete()
811
{
812
    Q_D(CustomQQuickDial);
813
    d->executeHandle(true);
814
    QQuickControl::componentComplete();
815
    setValue(d->value);
816
    d->updatePosition();
817
}
818
819
#if QT_CONFIG(accessibility)
820
void CustomQQuickDial::accessibilityActiveChanged(bool active)
821
{
822
    QQuickControl::accessibilityActiveChanged(active);
823
824
    Q_D(CustomQQuickDial);
825
    if (active)
826
        setAccessibleProperty("pressed", d->pressed);
827
}
828
829
QAccessible::Role CustomQQuickDial::accessibleRole() const
830
{
831
    return QAccessible::Dial;
832
}
833
#endif
834
835
QT_END_NAMESPACE