Qt 4.8
qslider.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 "qslider.h"
43 #ifndef QT_NO_SLIDER
44 #ifndef QT_NO_ACCESSIBILITY
45 #include "qaccessible.h"
46 #endif
47 #include "qapplication.h"
48 #include "qevent.h"
49 #include "qpainter.h"
50 #include "qstyle.h"
51 #include "qstyleoption.h"
52 #include "private/qabstractslider_p.h"
53 #include "qdebug.h"
54 
56 
58 {
60 public:
65  void init();
67  int pixelPosToRangeValue(int pos) const;
68  inline int pick(const QPoint &pt) const;
69 
71  bool updateHoverControl(const QPoint &pos);
74 };
75 
77 {
78  Q_Q(QSlider);
80  tickInterval = 0;
83  q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy)));
86  sp.transpose();
87  q->setSizePolicy(sp);
88  q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
90 }
91 
93 {
94  Q_Q(QSlider);
96  q->initStyleOption(&opt);
98 }
99 
101 {
102  Q_Q(const QSlider);
103  QStyleOptionSlider opt;
104  q->initStyleOption(&opt);
105  QRect gr = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, q);
106  QRect sr = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, q);
107  int sliderMin, sliderMax, sliderLength;
108 
109  if (orientation == Qt::Horizontal) {
110  sliderLength = sr.width();
111  sliderMin = gr.x();
112  sliderMax = gr.right() - sliderLength + 1;
113  } else {
114  sliderLength = sr.height();
115  sliderMin = gr.y();
116  sliderMax = gr.bottom() - sliderLength + 1;
117  }
118  return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin,
119  sliderMax - sliderMin, opt.upsideDown);
120 }
121 
122 inline int QSliderPrivate::pick(const QPoint &pt) const
123 {
124  return orientation == Qt::Horizontal ? pt.x() : pt.y();
125 }
126 
135 {
136  if (!option)
137  return;
138 
139  Q_D(const QSlider);
140  option->initFrom(this);
141  option->subControls = QStyle::SC_None;
143  option->orientation = d->orientation;
144  option->maximum = d->maximum;
145  option->minimum = d->minimum;
146  option->tickPosition = (QSlider::TickPosition)d->tickPosition;
147  option->tickInterval = d->tickInterval;
148  option->upsideDown = (d->orientation == Qt::Horizontal) ?
149  (d->invertedAppearance != (option->direction == Qt::RightToLeft))
150  : (!d->invertedAppearance);
151  option->direction = Qt::LeftToRight; // we use the upsideDown option instead
152  option->sliderPosition = d->position;
153  option->sliderValue = d->value;
154  option->singleStep = d->singleStep;
155  option->pageStep = d->pageStep;
156  if (d->orientation == Qt::Horizontal)
157  option->state |= QStyle::State_Horizontal;
158 }
159 
161 {
162  Q_Q(QSlider);
163  QRect lastHoverRect = hoverRect;
164  QStyle::SubControl lastHoverControl = hoverControl;
165  bool doesHover = q->testAttribute(Qt::WA_Hover);
166  if (lastHoverControl != newHoverControl(pos) && doesHover) {
167  q->update(lastHoverRect);
168  q->update(hoverRect);
169  return true;
170  }
171  return !doesHover;
172 }
173 
175 {
176  Q_Q(QSlider);
177  QStyleOptionSlider opt;
178  q->initStyleOption(&opt);
180  QRect handleRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, q);
181  QRect grooveRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, q);
182  QRect tickmarksRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderTickmarks, q);
183 
184  if (handleRect.contains(pos)) {
185  hoverRect = handleRect;
187  } else if (grooveRect.contains(pos)) {
188  hoverRect = grooveRect;
190  } else if (tickmarksRect.contains(pos)) {
191  hoverRect = tickmarksRect;
193  } else {
194  hoverRect = QRect();
196  }
197 
198  return hoverControl;
199 }
200 
302  : QAbstractSlider(*new QSliderPrivate, parent)
303 {
304  d_func()->orientation = Qt::Vertical;
305  d_func()->init();
306 }
307 
315  : QAbstractSlider(*new QSliderPrivate, parent)
316 {
317  d_func()->orientation = orientation;
318  d_func()->init();
319 }
320 
321 #ifdef QT3_SUPPORT
322 
332 QSlider::QSlider(QWidget *parent, const char *name)
333  : QAbstractSlider(*new QSliderPrivate, parent)
334 {
336  d_func()->orientation = Qt::Vertical;
337  d_func()->init();
338 }
339 
351  : QAbstractSlider(*new QSliderPrivate, parent)
352 {
354  d_func()->orientation = orientation;
355  d_func()->init();
356 }
357 
374 QSlider::QSlider(int minValue, int maxValue, int pageStep, int value, Qt::Orientation orientation,
375  QWidget *parent, const char *name)
376  : QAbstractSlider(*new QSliderPrivate, parent)
377 {
378  Q_D(QSlider);
380  d->minimum = minValue;
381  d->maximum = maxValue;
382  d->pageStep = pageStep;
383  d->position = d->value = value;
384  d->orientation = orientation;
385  d->init();
386 }
387 #endif
388 
393 {
394 }
395 
400 {
401  Q_D(QSlider);
402  QPainter p(this);
403  QStyleOptionSlider opt;
404  initStyleOption(&opt);
405 
407  if (d->tickPosition != NoTicks)
409  if (d->pressedControl) {
410  opt.activeSubControls = d->pressedControl;
412  } else {
413  opt.activeSubControls = d->hoverControl;
414  }
415 
416  style()->drawComplexControl(QStyle::CC_Slider, &opt, &p, this);
417 }
418 
424 {
425  Q_D(QSlider);
426 
427  switch(event->type()) {
428  case QEvent::HoverEnter:
429  case QEvent::HoverLeave:
430  case QEvent::HoverMove:
431  if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
432  d->updateHoverControl(he->pos());
433  break;
434  case QEvent::StyleChange:
436  d->resetLayoutItemMargins();
437  break;
438  default:
439  break;
440  }
441  return QAbstractSlider::event(event);
442 }
443 
448 {
449  Q_D(QSlider);
450  if (d->maximum == d->minimum || (ev->buttons() ^ ev->button())) {
451  ev->ignore();
452  return;
453  }
454 #ifdef QT_KEYPAD_NAVIGATION
455  if (QApplication::keypadNavigationEnabled())
456  setEditFocus(true);
457 #endif
458  ev->accept();
460  QStyleOptionSlider opt;
461  initStyleOption(&opt);
462  const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
463  const QPoint center = sliderRect.center() - sliderRect.topLeft();
464  // to take half of the slider off for the setSliderPosition call we use the center - topLeft
465 
466  setSliderPosition(d->pixelPosToRangeValue(d->pick(ev->pos() - center)));
469  d->pressedControl = QStyle::SC_SliderHandle;
470  update();
471  } else if ((ev->button() & style()->styleHint(QStyle::SH_Slider_PageSetButtons)) == ev->button()) {
472  QStyleOptionSlider opt;
473  initStyleOption(&opt);
474  d->pressedControl = style()->hitTestComplexControl(QStyle::CC_Slider,
475  &opt, ev->pos(), this);
476  SliderAction action = SliderNoAction;
477  if (d->pressedControl == QStyle::SC_SliderGroove) {
478  const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
479  int pressValue = d->pixelPosToRangeValue(d->pick(ev->pos() - sliderRect.center() + sliderRect.topLeft()));
480  d->pressValue = pressValue;
481  if (pressValue > d->value)
482  action = SliderPageStepAdd;
483  else if (pressValue < d->value)
484  action = SliderPageStepSub;
485  if (action) {
486  triggerAction(action);
487  setRepeatAction(action);
488  }
489  }
490  } else {
491  ev->ignore();
492  return;
493  }
494 
495  if (d->pressedControl == QStyle::SC_SliderHandle) {
496  QStyleOptionSlider opt;
497  initStyleOption(&opt);
500  d->clickOffset = d->pick(ev->pos() - sr.topLeft());
501  update(sr);
502  setSliderDown(true);
503  }
504 }
505 
510 {
511  Q_D(QSlider);
512  if (d->pressedControl != QStyle::SC_SliderHandle) {
513  ev->ignore();
514  return;
515  }
516  ev->accept();
517  int newPosition = d->pixelPosToRangeValue(d->pick(ev->pos()) - d->clickOffset);
518  QStyleOptionSlider opt;
519  initStyleOption(&opt);
520  setSliderPosition(newPosition);
521 }
522 
523 
528 {
529  Q_D(QSlider);
530  if (d->pressedControl == QStyle::SC_None || ev->buttons()) {
531  ev->ignore();
532  return;
533  }
534  ev->accept();
535  QStyle::SubControl oldPressed = QStyle::SubControl(d->pressedControl);
536  d->pressedControl = QStyle::SC_None;
538  if (oldPressed == QStyle::SC_SliderHandle)
539  setSliderDown(false);
540  QStyleOptionSlider opt;
541  initStyleOption(&opt);
542  opt.subControls = oldPressed;
543  update(style()->subControlRect(QStyle::CC_Slider, &opt, oldPressed, this));
544 }
545 
550 {
551  Q_D(const QSlider);
552  ensurePolished();
553  const int SliderLength = 84, TickSpace = 5;
554  QStyleOptionSlider opt;
555  initStyleOption(&opt);
556  int thick = style()->pixelMetric(QStyle::PM_SliderThickness, &opt, this);
557  if (d->tickPosition & TicksAbove)
558  thick += TickSpace;
559  if (d->tickPosition & TicksBelow)
560  thick += TickSpace;
561  int w = thick, h = SliderLength;
562  if (d->orientation == Qt::Horizontal) {
563  w = SliderLength;
564  h = thick;
565  }
567 }
568 
573 {
574  Q_D(const QSlider);
575  QSize s = sizeHint();
576  QStyleOptionSlider opt;
577  initStyleOption(&opt);
578  int length = style()->pixelMetric(QStyle::PM_SliderLength, &opt, this);
579  if (d->orientation == Qt::Horizontal)
580  s.setWidth(length);
581  else
582  s.setHeight(length);
583  return s;
584 }
585 
601 {
602  Q_D(QSlider);
603  d->tickPosition = position;
604  d->resetLayoutItemMargins();
605  update();
606  updateGeometry();
607 }
608 
610 {
611  return d_func()->tickPosition;
612 }
613 
650 {
651  d_func()->tickInterval = qMax(0, ts);
652  update();
653 }
654 
655 int QSlider::tickInterval() const
656 {
657  return d_func()->tickInterval;
658 }
659 
685 {
686  QStyleOptionSlider sliderOption;
687  slider->initStyleOption(&sliderOption);
688  return sliderOption;
689 }
690 
691 #endif
692 
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
double d
Definition: qnumeric_p.h:62
int pick(const QPoint &pt) const
Definition: qslider.cpp:122
SubControl
This enum describes the available sub controls.
Definition: qstyle.h:402
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int sliderValue
the value of the slider
Definition: qstyleoption.h:714
QStyle::SubControl hoverControl
Definition: qslider.cpp:72
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
void setTickPosition(TickPosition position)
Definition: qslider.cpp:600
void ensurePolished() const
Ensures that the widget has been polished by QStyle (i.e., has a proper font and palette).
Definition: qwidget.cpp:10024
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
bool event(QEvent *e)
Reimplemented Function
friend Q_GUI_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider)
Returns the style option for slider.
Definition: qslider.cpp:684
virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget=0) const =0
Returns the rectangle containing the specified subControl of the given complex control (with the styl...
static QSize globalStrut()
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const =0
Returns the value of the given pixel metric.
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
QRect hoverRect
Definition: qslider.cpp:73
The QHoverEvent class contains parameters that describe a mouse event.
Definition: qevent.h:125
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
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
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
void triggerAction(SliderAction action)
Triggers a slider action.
QSlider::TickPosition tickPosition
the position of the slider&#39;s tick marks, if any
Definition: qstyleoption.h:710
QSize minimumSizeHint() const
Reimplemented Function
Definition: qslider.cpp:572
TickPosition
This enum specifies where the tick marks are to be drawn relative to the slider&#39;s groove and the hand...
Definition: qslider.h:66
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.
QStyle::SubControl newHoverControl(const QPoint &pos)
Definition: qslider.cpp:174
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
void setLayoutItemMargins(int left, int top, int right, int bottom)
Definition: qwidget.cpp:12860
void mouseReleaseEvent(QMouseEvent *ev)
Reimplemented Function
Definition: qslider.cpp:527
#define Q_D(Class)
Definition: qglobal.h:2482
void mouseMoveEvent(QMouseEvent *ev)
Reimplemented Function
Definition: qslider.cpp:509
QStyle::SubControl pressedControl
Definition: qslider.cpp:61
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
const QPoint & pos() const
Returns the position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:95
QStyle * style() const
Definition: qwidget.cpp:2742
void setObjectName(const QString &name)
Definition: qobject.cpp:1112
#define Q_Q(Class)
Definition: qglobal.h:2483
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
void setTickInterval(int ti)
Definition: qslider.cpp:649
bool upsideDown
the slider control orientation
Definition: qstyleoption.h:712
int value() const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int tickInterval
Definition: qslider.cpp:62
QSize sizeHint() const
Reimplemented Function
Definition: qslider.cpp:549
void initFrom(const QWidget *w)
Definition: qstyleoption.h:99
const char * name
TickPosition tickPosition() const
Qt::Orientation orientation() const
int pixelPosToRangeValue(int pos) const
Definition: qslider.cpp:100
int sliderPosition
the position of the slider handle
Definition: qstyleoption.h:713
The QSlider widget provides a vertical or horizontal slider.
Definition: qslider.h:57
virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget=0) const =0
Draws the given control using the provided painter with the style options specified by option...
int tickInterval() const
Qt::MouseButton button() const
Returns the button that caused the event.
Definition: qevent.h:101
void setSliderDown(bool)
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
Q_CORE_EXPORT QTextStream & center(QTextStream &s)
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=0) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
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 right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
QSlider(QWidget *parent=0)
Constructs a vertical slider with the given parent.
Definition: qslider.cpp:301
int minimum
the minimum value for the slider
Definition: qstyleoption.h:708
void init()
Definition: qslider.cpp:76
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
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)
FocusPolicy
Definition: qnamespace.h:181
Qt::LayoutDirection direction
the text layout direction that should be used when drawing text in the control
Definition: qstyleoption.h:89
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
The QAbstractSlider class provides an integer value within a range.
void resetLayoutItemMargins()
Definition: qslider.cpp:92
virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *widget=0) const =0
Returns the sub control at the given position in the given complex control (with the style options sp...
void transpose()
Definition: qsizepolicy.h:229
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
Qt::Orientation orientation
the slider&#39;s orientation (horizontal or vertical)
Definition: qstyleoption.h:707
QObject * parent
Definition: qobject.h:92
void initStyleOption(QStyleOptionSlider *option) const
Initialize option with the values from this QSlider.
Definition: qslider.cpp:134
void mousePressEvent(QMouseEvent *ev)
Reimplemented Function
Definition: qslider.cpp:447
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
QSlider::TickPosition tickPosition
Definition: qslider.cpp:63
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
void paintEvent(QPaintEvent *ev)
Reimplemented Function
Definition: qslider.cpp:399
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 updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
Definition: qwidget.cpp:10372
bool updateHoverControl(const QPoint &pos)
Definition: qslider.cpp:160
Qt::Orientation orientation
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
Orientation
Definition: qnamespace.h:174
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
int pageStep() const
static int sliderValueFromPosition(int min, int max, int pos, int space, bool upsideDown=false)
Converts the given pixel position to a logical value.
Definition: qstyle.cpp:2222
void setRepeatAction(SliderAction action, int thresholdTime=500, int repeatTime=50)
Sets action action to be triggered repetitively in intervals of repeatTime, after an initial delay of...
QStyle::SubControls subControls
This variable holds a bitwise OR of the sub-controls to be drawn for the complex control.
Definition: qstyleoption.h:693
~QSlider()
Destroys this slider.
Definition: qslider.cpp:392
Qt::Orientation orientation
the orientation of the slider
bool event(QEvent *event)
Reimplemented Function
Definition: qslider.cpp:423
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288