Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdial.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 "qdial.h"
5
6#include <qapplication.h>
7#include <qbitmap.h>
8#include <qcolor.h>
9#include <qevent.h>
10#include <qpainter.h>
11#include <qpolygon.h>
12#include <qregion.h>
13#include <qstyle.h>
14#include <qstylepainter.h>
15#include <qstyleoption.h>
16#include <qslider.h>
17#include <private/qabstractslider_p.h>
18#include <private/qmath_p.h>
19#if QT_CONFIG(accessibility)
20#include "qaccessible.h"
21#endif
22#include <qmath.h>
23
25
27{
28 Q_DECLARE_PUBLIC(QDial)
29public:
31 {
32 wrapping = false;
33 tracking = true;
34 doNotEmit = false;
35 target = qreal(3.7);
36 }
37
42
43 int valueFromPoint(const QPoint &) const;
44 double angle(const QPoint &, const QPoint &) const;
45 void init();
46 virtual int bound(int val) const override;
47};
48
50{
51 Q_Q(QDial);
52 showNotches = false;
53 q->setFocusPolicy(Qt::WheelFocus);
54}
55
57{
58 if (wrapping) {
59 if ((val >= minimum) && (val <= maximum))
60 return val;
61 val = minimum + ((val - minimum) % (maximum - minimum));
62 if (val < minimum)
63 val += maximum - minimum;
64 return val;
65 } else {
67 }
68}
69
77void QDial::initStyleOption(QStyleOptionSlider *option) const
78{
79 if (!option)
80 return;
81
82 Q_D(const QDial);
83 option->initFrom(this);
84 option->minimum = d->minimum;
85 option->maximum = d->maximum;
86 option->sliderPosition = d->position;
87 option->sliderValue = d->value;
88 option->singleStep = d->singleStep;
89 option->pageStep = d->pageStep;
90 option->upsideDown = !d->invertedAppearance;
91 option->notchTarget = d->target;
92 option->dialWrapping = d->wrapping;
93 option->subControls = QStyle::SC_All;
94 option->activeSubControls = QStyle::SC_None;
95 if (!d->showNotches) {
96 option->subControls &= ~QStyle::SC_DialTickmarks;
97 option->tickPosition = QSlider::TicksAbove;
98 } else {
99 option->tickPosition = QSlider::NoTicks;
100 }
101 option->tickInterval = notchSize();
102}
103
105{
106 Q_Q(const QDial);
107 double yy = q->height()/2.0 - p.y();
108 double xx = p.x() - q->width()/2.0;
109 double a = (xx || yy) ? std::atan2(yy, xx) : 0;
110
111 if (a < Q_PI / -2)
112 a = a + Q_PI * 2;
113
114 int dist = 0;
115 int minv = minimum, maxv = maximum;
116
117 if (minimum < 0) {
118 dist = -minimum;
119 minv = 0;
120 maxv = maximum + dist;
121 }
122
123 int r = maxv - minv;
124 int v;
125 if (wrapping)
126 v = (int)(0.5 + minv + r * (Q_PI * 3 / 2 - a) / (2 * Q_PI));
127 else
128 v = (int)(0.5 + minv + r* (Q_PI * 4 / 3 - a) / (Q_PI * 10 / 6));
129
130 if (dist > 0)
131 v -= dist;
132
133 return !invertedAppearance ? bound(v) : maximum - bound(v);
134}
135
203{
204 Q_D(QDial);
205 d->init();
206}
207
212{
213}
214
217{
219}
220
226{
227 QStylePainter p(this);
228 QStyleOptionSlider option;
230 p.drawComplexControl(QStyle::CC_Dial, option);
231}
232
238{
239 Q_D(QDial);
240 if (d->maximum == d->minimum ||
241 (e->button() != Qt::LeftButton) ||
242 (e->buttons() ^ e->button())) {
243 e->ignore();
244 return;
245 }
246 e->accept();
247 setSliderPosition(d->valueFromPoint(e->position().toPoint()));
248 // ### This isn't quite right,
249 // we should be doing a hit test and only setting this if it's
250 // the actual dial thingie (similar to what QSlider does), but we have no
251 // subControls for QDial.
252 setSliderDown(true);
253}
254
255
261{
262 Q_D(QDial);
263 if (e->buttons() & (~e->button()) ||
264 (e->button() != Qt::LeftButton)) {
265 e->ignore();
266 return;
267 }
268 e->accept();
269 setValue(d->valueFromPoint(e->position().toPoint()));
270 setSliderDown(false);
271}
272
273
279{
280 Q_D(QDial);
281 if (!(e->buttons() & Qt::LeftButton)) {
282 e->ignore();
283 return;
284 }
285 e->accept();
286 d->doNotEmit = true;
287 setSliderPosition(d->valueFromPoint(e->position().toPoint()));
288 d->doNotEmit = false;
289}
290
291
297{
299}
300
302{
303 Q_D(QDial);
304 if (d->wrapping == enable)
305 return;
306 d->wrapping = enable;
307 update();
308}
309
310
326bool QDial::wrapping() const
327{
328 Q_D(const QDial);
329 return d->wrapping;
330}
331
332
345{
346 Q_D(const QDial);
347 // radius of the arc
348 qreal r = qMin(width(), height())/2.0;
349 // length of the whole arc
350 int l = qRound(r * (d->wrapping ? 6.0 : 5.0) * Q_PI / 6.0);
351 // length of the arc from minValue() to minValue()+pageStep()
352 if (d->maximum > d->minimum + d->pageStep)
353 l = qRound(l * d->pageStep / double(d->maximum - d->minimum));
354 // length of a singleStep arc
355 l = qMax(l * d->singleStep / (d->pageStep ? d->pageStep : 1), 1);
356 // how many times singleStep can be draw in d->target pixels
357 l = qMax(qRound(d->target / l), 1);
358 // we want notchSize() to be a non-zero multiple of singleStep()
359 return d->singleStep * l;
360}
361
363{
364 Q_D(QDial);
365 d->target = target;
366 update();
367}
368
381{
382 Q_D(const QDial);
383 return d->target;
384}
385
386
387void QDial::setNotchesVisible(bool visible)
388{
389 Q_D(QDial);
390 d->showNotches = visible;
391 update();
392}
393
405{
406 Q_D(const QDial);
407 return d->showNotches;
408}
409
415{
416 return QSize(50, 50);
417}
418
424{
425 return QSize(100, 100);
426}
427
432{
434}
435
437
438#include "moc_qdial.cpp"
virtual int bound(int val) const
The QAbstractSlider class provides an integer value within a range.
virtual void sliderChange(SliderChange change)
Reimplement this virtual function to track slider changes such as \l SliderRangeChange,...
bool event(QEvent *e) override
\reimp
void setSliderPosition(int)
SliderChange
\value SliderRangeChange \value SliderOrientationChange \value SliderStepsChange \value SliderValueCh...
uint wrapping
Definition qdial.cpp:40
uint doNotEmit
Definition qdial.cpp:41
virtual int bound(int val) const override
Definition qdial.cpp:56
void init()
Definition qdial.cpp:49
qreal target
Definition qdial.cpp:38
uint showNotches
Definition qdial.cpp:39
double angle(const QPoint &, const QPoint &) const
int valueFromPoint(const QPoint &) const
Definition qdial.cpp:104
The QDial class provides a rounded range control (like a speedometer or potentiometer).
Definition qdial.h:20
void mousePressEvent(QMouseEvent *me) override
\reimp
Definition qdial.cpp:237
void setNotchesVisible(bool visible)
Definition qdial.cpp:387
bool notchesVisible
whether the notches are shown
Definition qdial.h:26
bool wrapping
whether wrapping is enabled
Definition qdial.h:23
QDial(QWidget *parent=nullptr)
Constructs a dial.
Definition qdial.cpp:201
bool event(QEvent *e) override
\reimp
Definition qdial.cpp:431
void mouseMoveEvent(QMouseEvent *me) override
\reimp
Definition qdial.cpp:278
void sliderChange(SliderChange change) override
\reimp
Definition qdial.cpp:296
void setNotchTarget(double target)
Definition qdial.cpp:362
void setWrapping(bool on)
Definition qdial.cpp:301
void resizeEvent(QResizeEvent *re) override
\reimp
Definition qdial.cpp:216
void paintEvent(QPaintEvent *pe) override
\reimp
Definition qdial.cpp:225
int notchSize
the current notch size
Definition qdial.h:24
~QDial()
Destroys the dial.
Definition qdial.cpp:211
void mouseReleaseEvent(QMouseEvent *me) override
\reimp
Definition qdial.cpp:260
QSize minimumSizeHint() const override
\reimp
Definition qdial.cpp:414
virtual void initStyleOption(QStyleOptionSlider *option) const
Initialize option with the values from this QDial.
Definition qdial.cpp:77
QSize sizeHint() const override
\reimp
Definition qdial.cpp:423
qreal notchTarget
the target number of pixels between notches
Definition qdial.h:25
\inmodule QtCore
Definition qcoreevent.h:45
\inmodule QtGui
Definition qevent.h:195
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:485
\inmodule QtCore\reentrant
Definition qpoint.h:23
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:547
\inmodule QtCore
Definition qsize.h:25
@ TicksAbove
Definition qslider.h:27
@ NoTicks
Definition qslider.h:26
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
@ CC_Dial
Definition qstyle.h:338
@ SC_All
Definition qstyle.h:400
@ SC_None
Definition qstyle.h:348
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
void update()
Updates the widget unless updates are disabled or the widget is hidden.
virtual void resizeEvent(QResizeEvent *event)
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
Definition qwidget.cpp:9868
bool visible
whether the widget is visible
Definition qwidget.h:144
double e
Combined button and popup list for selecting options.
@ LeftButton
Definition qnamespace.h:57
@ WheelFocus
Definition qnamespace.h:110
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
static QT_BEGIN_NAMESPACE const qreal Q_PI
Definition qmath_p.h:24
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLenum target
GLboolean enable
GLuint GLfloat * val
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
std::uniform_real_distribution dist(1, 2.5)
[2]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent