Qt 4.8
qdial.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdial.h"
43 
44 #ifndef QT_NO_DIAL
45 
46 #include <qapplication.h>
47 #include <qbitmap.h>
48 #include <qcolor.h>
49 #include <qevent.h>
50 #include <qpainter.h>
51 #include <qpolygon.h>
52 #include <qregion.h>
53 #include <qstyle.h>
54 #include <qstylepainter.h>
55 #include <qstyleoption.h>
56 #include <qslider.h>
57 #include <private/qabstractslider_p.h>
58 #include <private/qmath_p.h>
59 #ifndef QT_NO_ACCESSIBILITY
60 #include "qaccessible.h"
61 #endif
62 #include <qmath.h>
63 
65 
67 {
69 public:
71  {
72  wrapping = false;
73  tracking = true;
74  doNotEmit = false;
75  target = qreal(3.7);
76  }
77 
82 
83  int valueFromPoint(const QPoint &) const;
84  double angle(const QPoint &, const QPoint &) const;
85  void init();
86  virtual int bound(int val) const;
87 };
88 
90 {
91  Q_Q(QDial);
92  showNotches = false;
93  q->setFocusPolicy(Qt::WheelFocus);
94 #ifdef QT3_SUPPORT
95  QObject::connect(q, SIGNAL(sliderPressed()), q, SIGNAL(dialPressed()));
96  QObject::connect(q, SIGNAL(sliderMoved(int)), q, SIGNAL(dialMoved(int)));
97  QObject::connect(q, SIGNAL(sliderReleased()), q, SIGNAL(dialReleased()));
98 #endif
99 }
100 
101 int QDialPrivate::bound(int val) const
102 {
103  if (wrapping) {
104  if ((val >= minimum) && (val <= maximum))
105  return val;
106  val = minimum + ((val - minimum) % (maximum - minimum));
107  if (val < minimum)
108  val += maximum - minimum;
109  return val;
110  } else {
111  return QAbstractSliderPrivate::bound(val);
112  }
113 }
114 
123 {
124  if (!option)
125  return;
126 
127  Q_D(const QDial);
128  option->initFrom(this);
129  option->minimum = d->minimum;
130  option->maximum = d->maximum;
131  option->sliderPosition = d->position;
132  option->sliderValue = d->value;
133  option->singleStep = d->singleStep;
134  option->pageStep = d->pageStep;
135  option->upsideDown = !d->invertedAppearance;
136  option->notchTarget = d->target;
137  option->dialWrapping = d->wrapping;
138  option->subControls = QStyle::SC_All;
140  if (!d->showNotches) {
141  option->subControls &= ~QStyle::SC_DialTickmarks;
143  } else {
144  option->tickPosition = QSlider::NoTicks;
145  }
146  option->tickInterval = notchSize();
147 }
148 
150 {
151  Q_Q(const QDial);
152  double yy = (double)q->height()/2.0 - p.y();
153  double xx = (double)p.x() - q->width()/2.0;
154  double a = (xx || yy) ? qAtan2(yy, xx) : 0;
155 
156  if (a < Q_PI / -2)
157  a = a + Q_PI * 2;
158 
159  int dist = 0;
160  int minv = minimum, maxv = maximum;
161 
162  if (minimum < 0) {
163  dist = -minimum;
164  minv = 0;
165  maxv = maximum + dist;
166  }
167 
168  int r = maxv - minv;
169  int v;
170  if (wrapping)
171  v = (int)(0.5 + minv + r * (Q_PI * 3 / 2 - a) / (2 * Q_PI));
172  else
173  v = (int)(0.5 + minv + r* (Q_PI * 4 / 3 - a) / (Q_PI * 10 / 6));
174 
175  if (dist > 0)
176  v -= dist;
177 
178  return !invertedAppearance ? bound(v) : maximum - bound(v);
179 }
180 
259  : QAbstractSlider(*new QDialPrivate, parent)
260 {
261  Q_D(QDial);
262  d->init();
263 }
264 
265 #ifdef QT3_SUPPORT
266 
270 QDial::QDial(QWidget *parent, const char *name)
271  : QAbstractSlider(*new QDialPrivate, parent)
272 {
273  Q_D(QDial);
275  d->init();
276 }
277 
282 QDial::QDial(int minValue, int maxValue, int pageStep, int value,
283  QWidget *parent, const char *name)
284  : QAbstractSlider(*new QDialPrivate, parent)
285 {
286  Q_D(QDial);
288  d->minimum = minValue;
289  d->maximum = maxValue;
290  d->pageStep = pageStep;
291  d->position = d->value = value;
292  d->init();
293 }
294 #endif
295 
299 {
300 }
301 
304 {
306 }
307 
313 {
314  QStylePainter p(this);
315  QStyleOptionSlider option;
316  initStyleOption(&option);
318 }
319 
325 {
326  Q_D(QDial);
327  if (d->maximum == d->minimum ||
328  (e->button() != Qt::LeftButton) ||
329  (e->buttons() ^ e->button())) {
330  e->ignore();
331  return;
332  }
333  e->accept();
334  setSliderPosition(d->valueFromPoint(e->pos()));
335  // ### This isn't quite right,
336  // we should be doing a hit test and only setting this if it's
337  // the actual dial thingie (similar to what QSlider does), but we have no
338  // subControls for QDial.
339  setSliderDown(true);
340 }
341 
342 
348 {
349  Q_D(QDial);
350  if (e->buttons() & (~e->button()) ||
351  (e->button() != Qt::LeftButton)) {
352  e->ignore();
353  return;
354  }
355  e->accept();
356  setValue(d->valueFromPoint(e->pos()));
357  setSliderDown(false);
358 }
359 
360 
366 {
367  Q_D(QDial);
368  if (!(e->buttons() & Qt::LeftButton)) {
369  e->ignore();
370  return;
371  }
372  e->accept();
373  d->doNotEmit = true;
374  setSliderPosition(d->valueFromPoint(e->pos()));
375  d->doNotEmit = false;
376 }
377 
378 
384 {
386 }
387 
388 void QDial::setWrapping(bool enable)
389 {
390  Q_D(QDial);
391  if (d->wrapping == enable)
392  return;
393  d->wrapping = enable;
394  update();
395 }
396 
397 
416 bool QDial::wrapping() const
417 {
418  Q_D(const QDial);
419  return d->wrapping;
420 }
421 
422 
439 int QDial::notchSize() const
440 {
441  Q_D(const QDial);
442  // radius of the arc
443  int r = qMin(width(), height())/2;
444  // length of the whole arc
445  int l = (int)(r * (d->wrapping ? 6 : 5) * Q_PI / 6);
446  // length of the arc from minValue() to minValue()+pageStep()
447  if (d->maximum > d->minimum + d->pageStep)
448  l = (int)(0.5 + l * d->pageStep / (d->maximum - d->minimum));
449  // length of a singleStep arc
450  l = l * d->singleStep / (d->pageStep ? d->pageStep : 1);
451  if (l < 1)
452  l = 1;
453  // how many times singleStep can be draw in d->target pixels
454  l = (int)(0.5 + d->target / l);
455  // we want notchSize() to be a non-zero multiple of lineStep()
456  if (!l)
457  l = 1;
458  return d->singleStep * l;
459 }
460 
461 void QDial::setNotchTarget(double target)
462 {
463  Q_D(QDial);
464  d->target = target;
465  update();
466 }
467 
483 {
484  Q_D(const QDial);
485  return d->target;
486 }
487 
488 
490 {
491  Q_D(QDial);
492  d->showNotches = visible;
493  update();
494 }
495 
509 bool QDial::notchesVisible() const
510 {
511  Q_D(const QDial);
512  return d->showNotches;
513 }
514 
520 {
521  return QSize(50, 50);
522 }
523 
529 {
530  return QSize(100, 100).expandedTo(QApplication::globalStrut());
531 }
532 
537 {
538  return QAbstractSlider::event(e);
539 }
540 
569 
570 #endif // QT_NO_DIAL
qreal notchTarget
the number of pixel between notches
Definition: qstyleoption.h:717
double d
Definition: qnumeric_p.h:62
void setNotchTarget(double target)
Definition: qdial.cpp:461
double qreal
Definition: qglobal.h:1193
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int sliderValue
the value of the slider
Definition: qstyleoption.h:714
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
bool wrapping() const
virtual void sliderChange(SliderChange change)
Reimplement this virtual function to track slider changes such as SliderRangeChange ...
int notchSize() const
void mouseMoveEvent(QMouseEvent *me)
Reimplemented Function
Definition: qdial.cpp:365
bool event(QEvent *e)
Reimplemented Function
static QSize globalStrut()
void paintEvent(QPaintEvent *pe)
Reimplemented Function
Definition: qdial.cpp:312
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
virtual int bound(int val) const
Definition: qdial.cpp:101
int tickInterval
the interval that should be drawn between tick marks
Definition: qstyleoption.h:711
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
virtual void resizeEvent(QResizeEvent *)
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
Definition: qwidget.cpp:9587
QSlider::TickPosition tickPosition
the position of the slider&#39;s tick marks, if any
Definition: qstyleoption.h:710
long ASN1_INTEGER_get ASN1_INTEGER * a
QStyle::SubControls activeSubControls
This variable holds a bitwise OR of the sub-controls that are active for the complex control...
Definition: qstyleoption.h:694
QAbstractSlider(QWidget *parent=0)
Constructs an abstract slider.
QSize minimumSizeHint() const
Reimplemented Function
Definition: qdial.cpp:519
QDialPrivate()
Definition: qdial.cpp:70
#define Q_D(Class)
Definition: qglobal.h:2482
int height() const
void setNotchesVisible(bool visible)
Definition: qdial.cpp:489
const QPoint & pos() const
Returns the position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:95
uint doNotEmit
Definition: qdial.cpp:81
void setObjectName(const QString &name)
Definition: qobject.cpp:1112
#define Q_Q(Class)
Definition: qglobal.h:2483
bool dialWrapping
whether the dial should wrap or not
Definition: qstyleoption.h:718
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
#define SIGNAL(a)
Definition: qobjectdefs.h:227
bool upsideDown
the slider control orientation
Definition: qstyleoption.h:712
int value() const
double angle(const QPoint &, const QPoint &) const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
uint showNotches
Definition: qdial.cpp:79
bool visible
whether the widget is visible
Definition: qwidget.h:191
void mousePressEvent(QMouseEvent *me)
Reimplemented Function
Definition: qdial.cpp:324
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
int width() const
uint wrapping
Definition: qdial.cpp:80
void initFrom(const QWidget *w)
Definition: qstyleoption.h:99
const char * name
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
unsigned int uint
Definition: qglobal.h:996
bool notchesVisible() const
qreal qAtan2(qreal x, qreal y)
Definition: qmath.h:189
void sliderChange(SliderChange change)
Reimplemented Function
Definition: qdial.cpp:383
int sliderPosition
the position of the slider handle
Definition: qstyleoption.h:713
void setWrapping(bool on)
Definition: qdial.cpp:388
qreal notchTarget() const
Qt::MouseButton button() const
Returns the button that caused the event.
Definition: qevent.h:101
void setSliderDown(bool)
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
~QDial()
Destroys the dial.
Definition: qdial.cpp:298
int valueFromPoint(const QPoint &) const
Definition: qdial.cpp:149
int maximum
the maximum value for the slider
Definition: qstyleoption.h:709
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
Definition: qevent.h:102
int minimum
the minimum value for the slider
Definition: qstyleoption.h:708
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void setSliderPosition(int)
void mouseReleaseEvent(QMouseEvent *me)
Reimplemented Function
Definition: qdial.cpp:347
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI...
Definition: qstyle.h:68
The QAbstractSlider class provides an integer value within a range.
void resizeEvent(QResizeEvent *re)
Reimplemented Function
Definition: qdial.cpp:303
QFactoryLoader * l
The QDial class provides a rounded range control (like a speedometer or potentiometer).
Definition: qdial.h:59
virtual int bound(int val) const
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
QObject * parent
Definition: qobject.h:92
void initStyleOption(QStyleOptionSlider *option) const
Initialize option with the values from this QDial.
Definition: qdial.cpp:122
QDial(QWidget *parent=0)
Constructs a dial.
Definition: qdial.cpp:258
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget...
Definition: qstylepainter.h:55
The QStyleOptionSlider class is used to describe the parameters needed for drawing a slider...
Definition: qstyleoption.h:701
int pageStep
the size of the page step of the slider
Definition: qstyleoption.h:716
void ignore()
Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
Definition: qcoreevent.h:310
void accept()
Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
Definition: qcoreevent.h:309
int singleStep
the size of the single step of the slider
Definition: qstyleoption.h:715
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt)
Use the widget&#39;s style to draw a complex control cc specified by the QStyleOptionComplex option...
Definition: qstylepainter.h:92
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
QSize sizeHint() const
Reimplemented Function
Definition: qdial.cpp:528
qreal target
Definition: qdial.cpp:78
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
int pageStep() const
void init()
Definition: qdial.cpp:89
QStyle::SubControls subControls
This variable holds a bitwise OR of the sub-controls to be drawn for the complex control.
Definition: qstyleoption.h:693
bool event(QEvent *e)
Reimplemented Function
Definition: qdial.cpp:536
static const qreal Q_PI
Definition: qmath_p.h:61