1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
10 #include "qwt_wheel.h"
12 #include "qwt_painter.h"
14 #include <qdrawutil.h>
17 #include <qstyleoption.h>
18 #include <qapplication.h>
19 #include <qdatetime.h>
21 #if QT_VERSION < 0x040601
22 #define qFabs(x) ::fabs(x)
23 #define qFastSin(x) ::sin(x)
24 #define qExp(x) ::exp(x)
27 class QwtWheel::PrivateData
31 orientation( Qt::Horizontal
),
35 wheelBorderWidth( 2 ),
41 pendingValueChanged( false ),
52 stepAlignment( true ),
59 Qt::Orientation orientation
;
71 bool pendingValueChanged
; // when not tracking
76 // for the flying wheel effect
97 QwtWheel::QwtWheel( QWidget
*parent
):
100 d_data
= new PrivateData
;
102 setFocusPolicy( Qt::StrongFocus
);
103 setSizePolicy( QSizePolicy::Preferred
, QSizePolicy::Fixed
);
104 setAttribute( Qt::WA_WState_OwnSizePolicy
, false );
108 QwtWheel::~QwtWheel()
114 \brief En/Disable tracking
116 If tracking is enabled (the default), the wheel emits the valueChanged()
117 signal while the wheel is moving. If tracking is disabled, the wheel
118 emits the valueChanged() signal only when the wheel movement is terminated.
120 The wheelMoved() signal is emitted regardless id tracking is enabled or not.
125 void QwtWheel::setTracking( bool enable
)
127 d_data
->tracking
= enable
;
131 \return True, when tracking is enabled
132 \sa setTracking(), valueChanged(), wheelMoved()
134 bool QwtWheel::isTracking() const
136 return d_data
->tracking
;
140 \brief Specify the update interval when the wheel is flying
142 Default and minimum value is 50 ms.
144 \param interval Interval in milliseconds
145 \sa updateInterval(), setMass(), setTracking()
147 void QwtWheel::setUpdateInterval( int interval
)
149 d_data
->updateInterval
= qMax( interval
, 50 );
153 \return Update interval when the wheel is flying
154 \sa setUpdateInterval(), mass(), isTracking()
156 int QwtWheel::updateInterval() const
158 return d_data
->updateInterval
;
162 \brief Mouse press event handler
164 Start movement of the wheel.
166 \param event Mouse event
168 void QwtWheel::mousePressEvent( QMouseEvent
*event
)
172 d_data
->isScrolling
= wheelRect().contains( event
->pos() );
174 if ( d_data
->isScrolling
)
176 d_data
->time
.start();
178 d_data
->mouseValue
= valueAt( event
->pos() );
179 d_data
->mouseOffset
= d_data
->mouseValue
- d_data
->value
;
180 d_data
->pendingValueChanged
= false;
182 Q_EMIT
wheelPressed();
187 \brief Mouse Move Event handler
189 Turn the wheel according to the mouse position
191 \param event Mouse event
193 void QwtWheel::mouseMoveEvent( QMouseEvent
*event
)
195 if ( !d_data
->isScrolling
)
198 double mouseValue
= valueAt( event
->pos() );
200 if ( d_data
->mass
> 0.0 )
202 double ms
= d_data
->time
.restart();
204 // the interval when mouse move events are posted are somehow
205 // random. To avoid unrealistic speed values we limit ms
207 ms
= qMax( ms
, 5.0 );
209 d_data
->speed
= ( mouseValue
- d_data
->mouseValue
) / ms
;
212 d_data
->mouseValue
= mouseValue
;
214 double value
= boundedValue( mouseValue
- d_data
->mouseOffset
);
215 if ( d_data
->stepAlignment
)
216 value
= alignedValue( value
);
218 if ( value
!= d_data
->value
)
220 d_data
->value
= value
;
224 Q_EMIT
wheelMoved( d_data
->value
);
226 if ( d_data
->tracking
)
227 Q_EMIT
valueChanged( d_data
->value
);
229 d_data
->pendingValueChanged
= true;
234 \brief Mouse Release Event handler
236 When the wheel has no mass the movement of the wheel stops, otherwise
239 \param event Mouse event
242 void QwtWheel::mouseReleaseEvent( QMouseEvent
*event
)
246 if ( !d_data
->isScrolling
)
249 d_data
->isScrolling
= false;
251 bool startFlying
= false;
253 if ( d_data
->mass
> 0.0 )
255 const int ms
= d_data
->time
.elapsed();
256 if ( ( qFabs( d_data
->speed
) > 0.0 ) && ( ms
< 50 ) )
262 d_data
->flyingValue
=
263 boundedValue( d_data
->mouseValue
- d_data
->mouseOffset
);
265 d_data
->timerId
= startTimer( d_data
->updateInterval
);
269 if ( d_data
->pendingValueChanged
)
270 Q_EMIT
valueChanged( d_data
->value
);
273 d_data
->pendingValueChanged
= false;
274 d_data
->mouseOffset
= 0.0;
276 Q_EMIT
wheelReleased();
280 \brief Qt timer event
282 The flying wheel effect is implemented using a timer
284 \param event Timer event
288 void QwtWheel::timerEvent( QTimerEvent
*event
)
290 if ( event
->timerId() != d_data
->timerId
)
292 QWidget::timerEvent( event
);
296 d_data
->speed
*= qExp( -d_data
->updateInterval
* 0.001 / d_data
->mass
);
298 d_data
->flyingValue
+= d_data
->speed
* d_data
->updateInterval
;
299 d_data
->flyingValue
= boundedValue( d_data
->flyingValue
);
301 double value
= d_data
->flyingValue
;
302 if ( d_data
->stepAlignment
)
303 value
= alignedValue( value
);
305 if ( qFabs( d_data
->speed
) < 0.001 * d_data
->singleStep
)
307 // stop if d_data->speed < one step per second
311 if ( value
!= d_data
->value
)
313 d_data
->value
= value
;
316 if ( d_data
->tracking
|| d_data
->timerId
== 0 )
317 Q_EMIT
valueChanged( d_data
->value
);
323 \brief Handle wheel events
325 In/Decrement the value
327 \param event Wheel event
329 void QwtWheel::wheelEvent( QWheelEvent
*event
)
331 if ( !wheelRect().contains( event
->pos() ) )
337 if ( d_data
->isScrolling
)
342 double increment
= 0.0;
344 if ( ( event
->modifiers() & Qt::ControlModifier
) ||
345 ( event
->modifiers() & Qt::ShiftModifier
) )
347 // one page regardless of delta
348 increment
= d_data
->singleStep
* d_data
->pageStepCount
;
349 if ( event
->delta() < 0 )
350 increment
= -increment
;
354 const int numSteps
= event
->delta() / 120;
355 increment
= d_data
->singleStep
* numSteps
;
358 if ( d_data
->orientation
== Qt::Vertical
&& d_data
->inverted
)
359 increment
= -increment
;
361 double value
= boundedValue( d_data
->value
+ increment
);
363 if ( d_data
->stepAlignment
)
364 value
= alignedValue( value
);
366 if ( value
!= d_data
->value
)
368 d_data
->value
= value
;
371 Q_EMIT
valueChanged( d_data
->value
);
372 Q_EMIT
wheelMoved( d_data
->value
);
386 In case of a horizontal or not inverted vertical wheel the value
387 will be incremented by the step size. For an inverted vertical wheel
388 the value will be decremented by the step size.
391 In case of a horizontal or not inverted vertical wheel the value
392 will be decremented by the step size. For an inverted vertical wheel
393 the value will be incremented by the step size.
396 The value will be incremented by pageStepSize() * singleStepSize().
399 The value will be decremented by pageStepSize() * singleStepSize().
401 \param event Key event
403 void QwtWheel::keyPressEvent( QKeyEvent
*event
)
405 if ( d_data
->isScrolling
)
407 // don't interfere mouse scrolling
411 double value
= d_data
->value
;
412 double increment
= 0.0;
414 switch ( event
->key() )
418 if ( d_data
->orientation
== Qt::Vertical
&& d_data
->inverted
)
419 increment
= d_data
->singleStep
;
421 increment
= -d_data
->singleStep
;
427 if ( d_data
->orientation
== Qt::Vertical
&& d_data
->inverted
)
428 increment
= -d_data
->singleStep
;
430 increment
= d_data
->singleStep
;
436 if ( d_data
->orientation
== Qt::Horizontal
)
438 if ( d_data
->inverted
)
439 increment
= d_data
->singleStep
;
441 increment
= -d_data
->singleStep
;
447 if ( d_data
->orientation
== Qt::Horizontal
)
449 if ( d_data
->inverted
)
450 increment
= -d_data
->singleStep
;
452 increment
= d_data
->singleStep
;
458 increment
= d_data
->pageStepCount
* d_data
->singleStep
;
461 case Qt::Key_PageDown
:
463 increment
= -d_data
->pageStepCount
* d_data
->singleStep
;
468 value
= d_data
->minimum
;
473 value
= d_data
->maximum
;
482 if ( event
->isAccepted() )
485 if ( increment
!= 0.0 )
487 value
= boundedValue( d_data
->value
+ increment
);
489 if ( d_data
->stepAlignment
)
490 value
= alignedValue( value
);
493 if ( value
!= d_data
->value
)
495 d_data
->value
= value
;
498 Q_EMIT
valueChanged( d_data
->value
);
499 Q_EMIT
wheelMoved( d_data
->value
);
504 \brief Adjust the number of grooves in the wheel's surface.
506 The number of grooves is limited to 6 <= count <= 50.
507 Values outside this range will be clipped.
508 The default value is 10.
510 \param count Number of grooves per 360 degrees
513 void QwtWheel::setTickCount( int count
)
515 count
= qBound( 6, count
, 50 );
517 if ( count
!= d_data
->tickCount
)
519 d_data
->tickCount
= qBound( 6, count
, 50 );
525 \return Number of grooves in the wheel's surface.
528 int QwtWheel::tickCount() const
530 return d_data
->tickCount
;
534 \brief Set the wheel border width of the wheel.
536 The wheel border must not be smaller than 1
537 and is limited in dependence on the wheel's size.
538 Values outside the allowed range will be clipped.
540 The wheel border defaults to 2.
542 \param borderWidth Border width
545 void QwtWheel::setWheelBorderWidth( int borderWidth
)
547 const int d
= qMin( width(), height() ) / 3;
548 borderWidth
= qMin( borderWidth
, d
);
549 d_data
->wheelBorderWidth
= qMax( borderWidth
, 1 );
554 \return Wheel border width
555 \sa setWheelBorderWidth()
557 int QwtWheel::wheelBorderWidth() const
559 return d_data
->wheelBorderWidth
;
563 \brief Set the border width
565 The border defaults to 2.
567 \param width Border width
570 void QwtWheel::setBorderWidth( int width
)
572 d_data
->borderWidth
= qMax( width
, 0 );
580 int QwtWheel::borderWidth() const
582 return d_data
->borderWidth
;
586 \return Rectangle of the wheel without the outer border
588 QRect
QwtWheel::wheelRect() const
590 const int bw
= d_data
->borderWidth
;
591 return contentsRect().adjusted( bw
, bw
, -bw
, -bw
);
595 \brief Set the total angle which the wheel can be turned.
597 One full turn of the wheel corresponds to an angle of
598 360 degrees. A total angle of n*360 degrees means
599 that the wheel has to be turned n times around its axis
600 to get from the minimum value to the maximum value.
602 The default setting of the total angle is 360 degrees.
604 \param angle total angle in degrees
607 void QwtWheel::setTotalAngle( double angle
)
612 d_data
->totalAngle
= angle
;
617 \return Total angle which the wheel can be turned.
620 double QwtWheel::totalAngle() const
622 return d_data
->totalAngle
;
626 \brief Set the wheel's orientation.
628 The default orientation is Qt::Horizontal.
630 \param orientation Qt::Horizontal or Qt::Vertical.
633 void QwtWheel::setOrientation( Qt::Orientation orientation
)
635 if ( d_data
->orientation
== orientation
)
638 if ( !testAttribute( Qt::WA_WState_OwnSizePolicy
) )
640 QSizePolicy sp
= sizePolicy();
644 setAttribute( Qt::WA_WState_OwnSizePolicy
, false );
647 d_data
->orientation
= orientation
;
655 Qt::Orientation
QwtWheel::orientation() const
657 return d_data
->orientation
;
661 \brief Specify the visible portion of the wheel.
663 You may use this function for fine-tuning the appearance of
664 the wheel. The default value is 175 degrees. The value is
665 limited from 10 to 175 degrees.
667 \param angle Visible angle in degrees
668 \sa viewAngle(), setTotalAngle()
670 void QwtWheel::setViewAngle( double angle
)
672 d_data
->viewAngle
= qBound( 10.0, angle
, 175.0 );
677 \return Visible portion of the wheel
678 \sa setViewAngle(), totalAngle()
680 double QwtWheel::viewAngle() const
682 return d_data
->viewAngle
;
686 Determine the value corresponding to a specified point
689 \return Value corresponding to pos
691 double QwtWheel::valueAt( const QPoint
&pos
) const
693 const QRectF rect
= wheelRect();
696 if ( d_data
->orientation
== Qt::Vertical
)
699 dx
= rect
.top() - pos
.y();
704 dx
= pos
.x() - rect
.left();
710 if ( d_data
->inverted
)
715 // w pixels is an arc of viewAngle degrees,
716 // so we convert change in pixels to change in angle
717 const double ang
= dx
* d_data
->viewAngle
/ w
;
719 // value range maps to totalAngle degrees,
720 // so convert the change in angle to a change in value
721 const double val
= ang
* ( maximum() - minimum() ) / d_data
->totalAngle
;
727 \brief Qt Paint Event
728 \param event Paint event
730 void QwtWheel::paintEvent( QPaintEvent
*event
)
732 QPainter
painter( this );
733 painter
.setClipRegion( event
->region() );
737 style()->drawPrimitive(QStyle::PE_Widget
, &opt
, &painter
, this);
739 qDrawShadePanel( &painter
,
740 contentsRect(), palette(), true, d_data
->borderWidth
);
742 drawWheelBackground( &painter
, wheelRect() );
743 drawTicks( &painter
, wheelRect() );
746 QwtPainter::drawFocusRect( &painter
, this );
750 Draw the Wheel's background gradient
752 \param painter Painter
753 \param rect Geometry for the wheel
755 void QwtWheel::drawWheelBackground(
756 QPainter
*painter
, const QRectF
&rect
)
760 QPalette pal
= palette();
762 // draw shaded background
763 QLinearGradient
gradient( rect
.topLeft(),
764 ( d_data
->orientation
== Qt::Horizontal
) ? rect
.topRight() : rect
.bottomLeft() );
765 gradient
.setColorAt( 0.0, pal
.color( QPalette::Button
) );
766 gradient
.setColorAt( 0.2, pal
.color( QPalette::Midlight
) );
767 gradient
.setColorAt( 0.7, pal
.color( QPalette::Mid
) );
768 gradient
.setColorAt( 1.0, pal
.color( QPalette::Dark
) );
770 painter
->fillRect( rect
, gradient
);
772 // draw internal border
774 const QPen
lightPen( palette().color( QPalette::Light
),
775 d_data
->wheelBorderWidth
, Qt::SolidLine
, Qt::FlatCap
);
776 const QPen
darkPen( pal
.color( QPalette::Dark
),
777 d_data
->wheelBorderWidth
, Qt::SolidLine
, Qt::FlatCap
);
779 const double bw2
= 0.5 * d_data
->wheelBorderWidth
;
781 if ( d_data
->orientation
== Qt::Horizontal
)
783 painter
->setPen( lightPen
);
784 painter
->drawLine( QPointF( rect
.left(), rect
.top() + bw2
),
785 QPointF( rect
.right(), rect
.top() + bw2
) );
787 painter
->setPen( darkPen
);
788 painter
->drawLine( QPointF( rect
.left(), rect
.bottom() - bw2
),
789 QPointF( rect
.right(), rect
.bottom() - bw2
) );
793 painter
->setPen( lightPen
);
794 painter
->drawLine( QPointF( rect
.left() + bw2
, rect
.top() ),
795 QPointF( rect
.left() + bw2
, rect
.bottom() ) );
797 painter
->setPen( darkPen
);
798 painter
->drawLine( QPointF( rect
.right() - bw2
, rect
.top() ),
799 QPointF( rect
.right() - bw2
, rect
.bottom() ) );
806 Draw the Wheel's ticks
808 \param painter Painter
809 \param rect Geometry for the wheel
811 void QwtWheel::drawTicks( QPainter
*painter
, const QRectF
&rect
)
813 const double range
= d_data
->maximum
- d_data
->minimum
;
815 if ( range
== 0.0 || d_data
->totalAngle
== 0.0 )
820 const QPen
lightPen( palette().color( QPalette::Light
),
821 0, Qt::SolidLine
, Qt::FlatCap
);
822 const QPen
darkPen( palette().color( QPalette::Dark
),
823 0, Qt::SolidLine
, Qt::FlatCap
);
825 const double cnvFactor
= qAbs( d_data
->totalAngle
/ range
);
826 const double halfIntv
= 0.5 * d_data
->viewAngle
/ cnvFactor
;
827 const double loValue
= value() - halfIntv
;
828 const double hiValue
= value() + halfIntv
;
829 const double tickWidth
= 360.0 / double( d_data
->tickCount
) / cnvFactor
;
830 const double sinArc
= qFastSin( d_data
->viewAngle
* M_PI
/ 360.0 );
832 if ( d_data
->orientation
== Qt::Horizontal
)
834 const double radius
= rect
.width() * 0.5;
836 double l1
= rect
.top() + d_data
->wheelBorderWidth
;
837 double l2
= rect
.bottom() - d_data
->wheelBorderWidth
- 1;
839 // draw one point over the border if border > 1
840 if ( d_data
->wheelBorderWidth
> 1 )
846 const double maxpos
= rect
.right() - 2;
847 const double minpos
= rect
.left() + 2;
850 for ( double tickValue
= ::ceil( loValue
/ tickWidth
) * tickWidth
;
851 tickValue
< hiValue
; tickValue
+= tickWidth
)
853 const double angle
= qwtRadians( tickValue
- value() );
854 const double s
= qFastSin( angle
* cnvFactor
);
856 const double off
= radius
* ( sinArc
+ s
) / sinArc
;
859 if ( d_data
->inverted
)
860 tickPos
= rect
.left() + off
;
862 tickPos
= rect
.right() - off
;
864 if ( ( tickPos
<= maxpos
) && ( tickPos
> minpos
) )
866 painter
->setPen( darkPen
);
867 painter
->drawLine( QPointF( tickPos
- 1 , l1
),
868 QPointF( tickPos
- 1, l2
) );
869 painter
->setPen( lightPen
);
870 painter
->drawLine( QPointF( tickPos
, l1
),
871 QPointF( tickPos
, l2
) );
877 const double radius
= rect
.height() * 0.5;
879 double l1
= rect
.left() + d_data
->wheelBorderWidth
;
880 double l2
= rect
.right() - d_data
->wheelBorderWidth
- 1;
882 if ( d_data
->wheelBorderWidth
> 1 )
888 const double maxpos
= rect
.bottom() - 2;
889 const double minpos
= rect
.top() + 2;
891 for ( double tickValue
= ::ceil( loValue
/ tickWidth
) * tickWidth
;
892 tickValue
< hiValue
; tickValue
+= tickWidth
)
894 const double angle
= qwtRadians( tickValue
- value() );
895 const double s
= qFastSin( angle
* cnvFactor
);
897 const double off
= radius
* ( sinArc
+ s
) / sinArc
;
901 if ( d_data
->inverted
)
902 tickPos
= rect
.bottom() - off
;
904 tickPos
= rect
.top() + off
;
906 if ( ( tickPos
<= maxpos
) && ( tickPos
> minpos
) )
908 painter
->setPen( darkPen
);
909 painter
->drawLine( QPointF( l1
, tickPos
- 1 ),
910 QPointF( l2
, tickPos
- 1 ) );
911 painter
->setPen( lightPen
);
912 painter
->drawLine( QPointF( l1
, tickPos
),
913 QPointF( l2
, tickPos
) );
920 \brief Set the width of the wheel
922 Corresponds to the wheel height for horizontal orientation,
923 and the wheel width for vertical orientation.
925 \param width the wheel's width
928 void QwtWheel::setWheelWidth( int width
)
930 d_data
->wheelWidth
= width
;
935 \return Width of the wheel
938 int QwtWheel::wheelWidth() const
940 return d_data
->wheelWidth
;
946 QSize
QwtWheel::sizeHint() const
948 const QSize hint
= minimumSizeHint();
949 return hint
.expandedTo( QApplication::globalStrut() );
953 \return Minimum size hint
954 \warning The return value is based on the wheel width.
956 QSize
QwtWheel::minimumSizeHint() const
958 QSize
sz( 3 * d_data
->wheelWidth
+ 2 * d_data
->borderWidth
,
959 d_data
->wheelWidth
+ 2 * d_data
->borderWidth
);
960 if ( d_data
->orientation
!= Qt::Horizontal
)
967 \brief Set the step size of the counter
969 A value <= 0.0 disables stepping
971 \param stepSize Single step size
972 \sa singleStep(), setPageStepCount()
974 void QwtWheel::setSingleStep( double stepSize
)
976 d_data
->singleStep
= qMax( stepSize
, 0.0 );
980 \return Single step size
983 double QwtWheel::singleStep() const
985 return d_data
->singleStep
;
989 \brief En/Disable step alignment
991 When step alignment is enabled value changes initiated by
992 user input ( mouse, keyboard, wheel ) are aligned to
993 the multiples of the single step.
996 \sa stepAlignment(), setSingleStep()
998 void QwtWheel::setStepAlignment( bool on
)
1000 if ( on
!= d_data
->stepAlignment
)
1002 d_data
->stepAlignment
= on
;
1007 \return True, when the step alignment is enabled
1008 \sa setStepAlignment(), singleStep()
1010 bool QwtWheel::stepAlignment() const
1012 return d_data
->stepAlignment
;
1016 \brief Set the page step count
1018 pageStepCount is a multiplicator for the single step size
1019 that typically corresponds to the user pressing PageUp or PageDown.
1021 A value of 0 disables page stepping.
1023 The default value is 1.
1025 \param count Multiplicator for the single step size
1026 \sa pageStepCount(), setSingleStep()
1028 void QwtWheel::setPageStepCount( int count
)
1030 d_data
->pageStepCount
= qMax( 0, count
);
1034 \return Page step count
1035 \sa setPageStepCount(), singleStep()
1037 int QwtWheel::pageStepCount() const
1039 return d_data
->pageStepCount
;
1043 \brief Set the minimum and maximum values
1045 The maximum is adjusted if necessary to ensure that the range remains valid.
1046 The value might be modified to be inside of the range.
1048 \param min Minimum value
1049 \param max Maximum value
1051 \sa minimum(), maximum()
1053 void QwtWheel::setRange( double min
, double max
)
1055 max
= qMax( min
, max
);
1057 if ( d_data
->minimum
== min
&& d_data
->maximum
== max
)
1060 d_data
->minimum
= min
;
1061 d_data
->maximum
= max
;
1063 if ( d_data
->value
< min
|| d_data
->value
> max
)
1065 d_data
->value
= qBound( min
, d_data
->value
, max
);
1068 Q_EMIT
valueChanged( d_data
->value
);
1072 Set the minimum value of the range
1074 \param value Minimum value
1075 \sa setRange(), setMaximum(), minimum()
1077 \note The maximum is adjusted if necessary to ensure that the range remains valid.
1079 void QwtWheel::setMinimum( double value
)
1081 setRange( value
, maximum() );
1085 \return The minimum of the range
1086 \sa setRange(), setMinimum(), maximum()
1088 double QwtWheel::minimum() const
1090 return d_data
->minimum
;
1094 Set the maximum value of the range
1096 \param value Maximum value
1097 \sa setRange(), setMinimum(), maximum()
1099 void QwtWheel::setMaximum( double value
)
1101 setRange( minimum(), value
);
1105 \return The maximum of the range
1106 \sa setRange(), setMaximum(), minimum()
1108 double QwtWheel::maximum() const
1110 return d_data
->maximum
;
1114 \brief Set a new value without adjusting to the step raster
1116 \param value New value
1118 \sa value(), valueChanged()
1119 \warning The value is clipped when it lies outside the range.
1121 void QwtWheel::setValue( double value
)
1124 d_data
->isScrolling
= false;
1126 value
= qBound( d_data
->minimum
, value
, d_data
->maximum
);
1128 if ( d_data
->value
!= value
)
1130 d_data
->value
= value
;
1133 Q_EMIT
valueChanged( d_data
->value
);
1138 \return Current value of the wheel
1139 \sa setValue(), valueChanged()
1141 double QwtWheel::value() const
1143 return d_data
->value
;
1147 \brief En/Disable inverted appearance
1149 An inverted wheel increases its values in the opposite direction.
1150 The direction of an inverted horizontal wheel will be from right to left
1151 an inverted vertical wheel will increase from bottom to top.
1153 \param on En/Disable inverted appearance
1157 void QwtWheel::setInverted( bool on
)
1159 if ( d_data
->inverted
!= on
)
1161 d_data
->inverted
= on
;
1167 \return True, when the wheel is inverted
1170 bool QwtWheel::isInverted() const
1172 return d_data
->inverted
;
1176 \brief En/Disable wrapping
1178 If wrapping is true stepping up from maximum() value will take
1179 you to the minimum() value and vice versa.
1181 \param on En/Disable wrapping
1184 void QwtWheel::setWrapping( bool on
)
1186 d_data
->wrapping
= on
;
1190 \return True, when wrapping is set
1193 bool QwtWheel::wrapping() const
1195 return d_data
->wrapping
;
1199 \brief Set the slider's mass for flywheel effect.
1201 If the slider's mass is greater then 0, it will continue
1202 to move after the mouse button has been released. Its speed
1203 decreases with time at a rate depending on the slider's mass.
1204 A large mass means that it will continue to move for a
1207 Derived widgets may overload this function to make it public.
1209 \param mass New mass in kg
1211 \bug If the mass is smaller than 1g, it is set to zero.
1212 The maximal mass is limited to 100kg.
1215 void QwtWheel::setMass( double mass
)
1223 d_data
->mass
= qMin( 100.0, mass
);
1226 if ( d_data
->mass
<= 0.0 )
1234 double QwtWheel::mass() const
1236 return d_data
->mass
;
1239 //! Stop the flying movement of the wheel
1240 void QwtWheel::stopFlying()
1242 if ( d_data
->timerId
!= 0 )
1244 killTimer( d_data
->timerId
);
1245 d_data
->timerId
= 0;
1246 d_data
->speed
= 0.0;
1250 double QwtWheel::boundedValue( double value
) const
1252 const double range
= d_data
->maximum
- d_data
->minimum
;
1254 if ( d_data
->wrapping
&& range
>= 0.0 )
1256 if ( value
< d_data
->minimum
)
1258 value
+= ::ceil( ( d_data
->minimum
- value
) / range
) * range
;
1260 else if ( value
> d_data
->maximum
)
1262 value
-= ::ceil( ( value
- d_data
->maximum
) / range
) * range
;
1267 value
= qBound( d_data
->minimum
, value
, d_data
->maximum
);
1273 double QwtWheel::alignedValue( double value
) const
1275 const double stepSize
= d_data
->singleStep
;
1277 if ( stepSize
> 0.0 )
1279 value
= d_data
->minimum
+
1280 qRound( ( value
- d_data
->minimum
) / stepSize
) * stepSize
;
1282 if ( stepSize
> 1e-12 )
1284 if ( qFuzzyCompare( value
+ 1.0, 1.0 ) )
1286 // correct rounding error if value = 0
1289 else if ( qFuzzyCompare( value
, d_data
->maximum
) )
1291 // correct rounding error at the border
1292 value
= d_data
->maximum
;