| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 | 
							- /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 
-  * Qwt Widget Library
 
-  * Copyright (C) 1997   Josef Wilgen
 
-  * Copyright (C) 2002   Uwe Rathmann
 
-  *
 
-  * This library is free software; you can redistribute it and/or
 
-  * modify it under the terms of the Qwt License, Version 1.0
 
-  *****************************************************************************/
 
- #include "qwt_abstract_slider.h"
 
- #include "qwt_math.h"
 
- #include <qevent.h>
 
- #include <qdatetime.h>
 
- #if QT_VERSION < 0x040601
 
- #define qFabs(x) ::fabs(x)
 
- #define qExp(x) ::exp(x)
 
- #endif
 
- class QwtAbstractSlider::PrivateData
 
- {
 
- public:
 
-     PrivateData():
 
-         scrollMode( ScrNone ),
 
-         mouseOffset( 0.0 ),
 
-         tracking( true ),
 
-         tmrID( 0 ),
 
-         updTime( 150 ),
 
-         mass( 0.0 ),
 
-         readOnly( false )
 
-     {
 
-     }
 
-     int scrollMode;
 
-     double mouseOffset;
 
-     int direction;
 
-     int tracking;
 
-     int tmrID;
 
-     int updTime;
 
-     int timerTick;
 
-     QTime time;
 
-     double speed;
 
-     double mass;
 
-     Qt::Orientation orientation;
 
-     bool readOnly;
 
- };
 
- /*!
 
-    \brief Constructor
 
-    \param orientation Orientation
 
-    \param parent Parent widget
 
- */
 
- QwtAbstractSlider::QwtAbstractSlider(
 
-         Qt::Orientation orientation, QWidget *parent ):
 
-     QWidget( parent, NULL )
 
- {
 
-     d_data = new QwtAbstractSlider::PrivateData;
 
-     d_data->orientation = orientation;
 
-     setFocusPolicy( Qt::TabFocus );
 
- }
 
- //! Destructor
 
- QwtAbstractSlider::~QwtAbstractSlider()
 
- {
 
-     if ( d_data->tmrID )
 
-         killTimer( d_data->tmrID );
 
-     delete d_data;
 
- }
 
- /*!
 
-   En/Disable read only mode
 
-   In read only mode the slider can't be controlled by mouse
 
-   or keyboard.
 
-   \param readOnly Enables in case of true
 
-   \sa isReadOnly()
 
- */
 
- void QwtAbstractSlider::setReadOnly( bool readOnly )
 
- {
 
-     d_data->readOnly = readOnly;
 
-     update();
 
- }
 
- /*!
 
-   In read only mode the slider can't be controlled by mouse
 
-   or keyboard.
 
-   \return true if read only
 
-   \sa setReadOnly()
 
- */
 
- bool QwtAbstractSlider::isReadOnly() const
 
- {
 
-     return d_data->readOnly;
 
- }
 
- /*!
 
-   \brief Set the orientation.
 
-   \param o Orientation. Allowed values are
 
-            Qt::Horizontal and Qt::Vertical.
 
- */
 
- void QwtAbstractSlider::setOrientation( Qt::Orientation o )
 
- {
 
-     d_data->orientation = o;
 
- }
 
- /*!
 
-   \return Orientation
 
-   \sa setOrientation()
 
- */
 
- Qt::Orientation QwtAbstractSlider::orientation() const
 
- {
 
-     return d_data->orientation;
 
- }
 
- //! Stop updating if automatic scrolling is active
 
- void QwtAbstractSlider::stopMoving()
 
- {
 
-     if ( d_data->tmrID )
 
-     {
 
-         killTimer( d_data->tmrID );
 
-         d_data->tmrID = 0;
 
-     }
 
- }
 
- /*!
 
-   \brief Specify the update interval for automatic scrolling
 
-   \param t update interval in milliseconds
 
-   \sa getScrollMode()
 
- */
 
- void QwtAbstractSlider::setUpdateTime( int t )
 
- {
 
-     if ( t < 50 )
 
-         t = 50;
 
-     d_data->updTime = t;
 
- }
 
- /*!
 
-    Mouse press event handler
 
-    \param e Mouse event
 
- */
 
- void QwtAbstractSlider::mousePressEvent( QMouseEvent *e )
 
- {
 
-     if ( isReadOnly() )
 
-     {
 
-         e->ignore();
 
-         return;
 
-     }
 
-     if ( !isValid() )
 
-         return;
 
-     const QPoint &p = e->pos();
 
-     d_data->timerTick = 0;
 
-     getScrollMode( p, d_data->scrollMode, d_data->direction );
 
-     stopMoving();
 
-     switch ( d_data->scrollMode )
 
-     {
 
-         case ScrPage:
 
-         case ScrTimer:
 
-             d_data->mouseOffset = 0;
 
-             d_data->tmrID = startTimer( qMax( 250, 2 * d_data->updTime ) );
 
-             break;
 
-         case ScrMouse:
 
-             d_data->time.start();
 
-             d_data->speed = 0;
 
-             d_data->mouseOffset = getValue( p ) - value();
 
-             Q_EMIT sliderPressed();
 
-             break;
 
-         default:
 
-             d_data->mouseOffset = 0;
 
-             d_data->direction = 0;
 
-             break;
 
-     }
 
- }
 
- //! Emits a valueChanged() signal if necessary
 
- void QwtAbstractSlider::buttonReleased()
 
- {
 
-     if ( ( !d_data->tracking ) || ( value() != prevValue() ) )
 
-         Q_EMIT valueChanged( value() );
 
- }
 
- /*!
 
-    Mouse Release Event handler
 
-    \param e Mouse event
 
- */
 
- void QwtAbstractSlider::mouseReleaseEvent( QMouseEvent *e )
 
- {
 
-     if ( isReadOnly() )
 
-     {
 
-         e->ignore();
 
-         return;
 
-     }
 
-     if ( !isValid() )
 
-         return;
 
-     const double inc = step();
 
-     switch ( d_data->scrollMode )
 
-     {
 
-         case ScrMouse:
 
-         {
 
-             setPosition( e->pos() );
 
-             d_data->direction = 0;
 
-             d_data->mouseOffset = 0;
 
-             if ( d_data->mass > 0.0 )
 
-             {
 
-                 const int ms = d_data->time.elapsed();
 
-                 if ( ( qFabs( d_data->speed ) >  0.0 ) && ( ms < 50 ) )
 
-                     d_data->tmrID = startTimer( d_data->updTime );
 
-             }
 
-             else
 
-             {
 
-                 d_data->scrollMode = ScrNone;
 
-                 buttonReleased();
 
-             }
 
-             Q_EMIT sliderReleased();
 
-             break;
 
-         }
 
-         case ScrDirect:
 
-         {
 
-             setPosition( e->pos() );
 
-             d_data->direction = 0;
 
-             d_data->mouseOffset = 0;
 
-             d_data->scrollMode = ScrNone;
 
-             buttonReleased();
 
-             break;
 
-         }
 
-         case ScrPage:
 
-         {
 
-             stopMoving();
 
-             if ( !d_data->timerTick )
 
-                 QwtDoubleRange::incPages( d_data->direction );
 
-             d_data->timerTick = 0;
 
-             buttonReleased();
 
-             d_data->scrollMode = ScrNone;
 
-             break;
 
-         }
 
-         case ScrTimer:
 
-         {
 
-             stopMoving();
 
-             if ( !d_data->timerTick )
 
-                 QwtDoubleRange::fitValue( value() + double( d_data->direction ) * inc );
 
-             d_data->timerTick = 0;
 
-             buttonReleased();
 
-             d_data->scrollMode = ScrNone;
 
-             break;
 
-         }
 
-         default:
 
-         {
 
-             d_data->scrollMode = ScrNone;
 
-             buttonReleased();
 
-         }
 
-     }
 
- }
 
- /*!
 
-   Move the slider to a specified point, adjust the value
 
-   and emit signals if necessary.
 
- */
 
- void QwtAbstractSlider::setPosition( const QPoint &p )
 
- {
 
-     QwtDoubleRange::fitValue( getValue( p ) - d_data->mouseOffset );
 
- }
 
- /*!
 
-   \brief Enables or disables tracking.
 
-   If tracking is enabled, the slider emits a
 
-   valueChanged() signal whenever its value
 
-   changes (the default behaviour). If tracking
 
-   is disabled, the value changed() signal will only
 
-   be emitted if:<ul>
 
-   <li>the user releases the mouse
 
-       button and the value has changed or
 
-   <li>at the end of automatic scrolling.</ul>
 
-   Tracking is enabled by default.
 
-   \param enable \c true (enable) or \c false (disable) tracking.
 
- */
 
- void QwtAbstractSlider::setTracking( bool enable )
 
- {
 
-     d_data->tracking = enable;
 
- }
 
- /*!
 
-    Mouse Move Event handler
 
-    \param e Mouse event
 
- */
 
- void QwtAbstractSlider::mouseMoveEvent( QMouseEvent *e )
 
- {
 
-     if ( isReadOnly() )
 
-     {
 
-         e->ignore();
 
-         return;
 
-     }
 
-     if ( !isValid() )
 
-         return;
 
-     if ( d_data->scrollMode == ScrMouse )
 
-     {
 
-         setPosition( e->pos() );
 
-         if ( d_data->mass > 0.0 )
 
-         {
 
-             double ms = double( d_data->time.elapsed() );
 
-             if ( ms < 1.0 )
 
-                 ms = 1.0;
 
-             d_data->speed = ( exactValue() - exactPrevValue() ) / ms;
 
-             d_data->time.start();
 
-         }
 
-         if ( value() != prevValue() )
 
-             Q_EMIT sliderMoved( value() );
 
-     }
 
- }
 
- /*!
 
-    Wheel Event handler
 
-    \param e Whell event
 
- */
 
- void QwtAbstractSlider::wheelEvent( QWheelEvent *e )
 
- {
 
-     if ( isReadOnly() )
 
-     {
 
-         e->ignore();
 
-         return;
 
-     }
 
-     if ( !isValid() )
 
-         return;
 
-     int mode = ScrNone, direction = 0;
 
-     // Give derived classes a chance to say ScrNone
 
-     getScrollMode( e->pos(), mode, direction );
 
-     if ( mode != ScrNone )
 
-     {
 
-         // Most mouse types work in steps of 15 degrees, in which case
 
-         // the delta value is a multiple of 120
 
-         const int inc = e->delta() / 120;
 
-         QwtDoubleRange::incPages( inc );
 
-         if ( value() != prevValue() )
 
-             Q_EMIT sliderMoved( value() );
 
-     }
 
- }
 
- /*!
 
-   Handles key events
 
-   - Key_Down, KeyLeft\n
 
-     Decrement by 1
 
-   - Key_Up, Key_Right\n
 
-     Increment by 1
 
-   \param e Key event
 
-   \sa isReadOnly()
 
- */
 
- void QwtAbstractSlider::keyPressEvent( QKeyEvent *e )
 
- {
 
-     if ( isReadOnly() )
 
-     {
 
-         e->ignore();
 
-         return;
 
-     }
 
-     if ( !isValid() )
 
-         return;
 
-     int increment = 0;
 
-     switch ( e->key() )
 
-     {
 
-         case Qt::Key_Down:
 
-             if ( orientation() == Qt::Vertical )
 
-                 increment = -1;
 
-             break;
 
-         case Qt::Key_Up:
 
-             if ( orientation() == Qt::Vertical )
 
-                 increment = 1;
 
-             break;
 
-         case Qt::Key_Left:
 
-             if ( orientation() == Qt::Horizontal )
 
-                 increment = -1;
 
-             break;
 
-         case Qt::Key_Right:
 
-             if ( orientation() == Qt::Horizontal )
 
-                 increment = 1;
 
-             break;
 
-         default:;
 
-             e->ignore();
 
-     }
 
-     if ( increment != 0 )
 
-     {
 
-         QwtDoubleRange::incValue( increment );
 
-         if ( value() != prevValue() )
 
-             Q_EMIT sliderMoved( value() );
 
-     }
 
- }
 
- /*!
 
-    Qt timer event
 
-    \param e Timer event
 
- */
 
- void QwtAbstractSlider::timerEvent( QTimerEvent * )
 
- {
 
-     const double inc = step();
 
-     switch ( d_data->scrollMode )
 
-     {
 
-         case ScrMouse:
 
-         {
 
-             if ( d_data->mass > 0.0 )
 
-             {
 
-                 d_data->speed *= qExp( - double( d_data->updTime ) * 0.001 / d_data->mass );
 
-                 const double newval =
 
-                     exactValue() + d_data->speed * double( d_data->updTime );
 
-                 QwtDoubleRange::fitValue( newval );
 
-                 // stop if d_data->speed < one step per second
 
-                 if ( qFabs( d_data->speed ) < 0.001 * qFabs( step() ) )
 
-                 {
 
-                     d_data->speed = 0;
 
-                     stopMoving();
 
-                     buttonReleased();
 
-                 }
 
-             }
 
-             else
 
-                 stopMoving();
 
-             break;
 
-         }
 
-         case ScrPage:
 
-         {
 
-             QwtDoubleRange::incPages( d_data->direction );
 
-             if ( !d_data->timerTick )
 
-             {
 
-                 killTimer( d_data->tmrID );
 
-                 d_data->tmrID = startTimer( d_data->updTime );
 
-             }
 
-             break;
 
-         }
 
-         case ScrTimer:
 
-         {
 
-             QwtDoubleRange::fitValue( value() +  double( d_data->direction ) * inc );
 
-             if ( !d_data->timerTick )
 
-             {
 
-                 killTimer( d_data->tmrID );
 
-                 d_data->tmrID = startTimer( d_data->updTime );
 
-             }
 
-             break;
 
-         }
 
-         default:
 
-         {
 
-             stopMoving();
 
-             break;
 
-         }
 
-     }
 
-     d_data->timerTick = 1;
 
- }
 
- /*!
 
-   Notify change of value
 
-   This function can be reimplemented by derived classes
 
-   in order to keep track of changes, i.e. repaint the widget.
 
-   The default implementation emits a valueChanged() signal
 
-   if tracking is enabled.
 
- */
 
- void QwtAbstractSlider::valueChange()
 
- {
 
-     if ( d_data->tracking )
 
-         Q_EMIT valueChanged( value() );
 
- }
 
- /*!
 
-   \brief Set the slider's mass for flywheel effect.
 
-   If the slider's mass is greater then 0, it will continue
 
-   to move after the mouse button has been released. Its speed
 
-   decreases with time at a rate depending on the slider's mass.
 
-   A large mass means that it will continue to move for a
 
-   long time.
 
-   Derived widgets may overload this function to make it public.
 
-   \param val New mass in kg
 
-   \bug If the mass is smaller than 1g, it is set to zero.
 
-        The maximal mass is limited to 100kg.
 
-   \sa mass()
 
- */
 
- void QwtAbstractSlider::setMass( double val )
 
- {
 
-     if ( val < 0.001 )
 
-         d_data->mass = 0.0;
 
-     else if ( val > 100.0 )
 
-         d_data->mass = 100.0;
 
-     else
 
-         d_data->mass = val;
 
- }
 
- /*!
 
-     \return mass
 
-     \sa setMass()
 
- */
 
- double QwtAbstractSlider::mass() const
 
- {
 
-     return d_data->mass;
 
- }
 
- /*!
 
-   \brief Move the slider to a specified value
 
-   This function can be used to move the slider to a value
 
-   which is not an integer multiple of the step size.
 
-   \param val new value
 
-   \sa fitValue()
 
- */
 
- void QwtAbstractSlider::setValue( double val )
 
- {
 
-     if ( d_data->scrollMode == ScrMouse )
 
-         stopMoving();
 
-     QwtDoubleRange::setValue( val );
 
- }
 
- /*!
 
-   \brief Set the slider's value to the nearest integer multiple
 
-          of the step size.
 
-    \param value Value
 
-    \sa setValue(), incValue()
 
- */
 
- void QwtAbstractSlider::fitValue( double value )
 
- {
 
-     if ( d_data->scrollMode == ScrMouse )
 
-         stopMoving();
 
-     QwtDoubleRange::fitValue( value );
 
- }
 
- /*!
 
-   \brief Increment the value by a specified number of steps
 
-   \param steps number of steps
 
-   \sa setValue()
 
- */
 
- void QwtAbstractSlider::incValue( int steps )
 
- {
 
-     if ( d_data->scrollMode == ScrMouse )
 
-         stopMoving();
 
-     QwtDoubleRange::incValue( steps );
 
- }
 
- /*!
 
-   \sa mouseOffset()
 
- */
 
- void QwtAbstractSlider::setMouseOffset( double offset )
 
- {
 
-     d_data->mouseOffset = offset;
 
- }
 
- /*!
 
-   \sa setMouseOffset()
 
- */
 
- double QwtAbstractSlider::mouseOffset() const
 
- {
 
-     return d_data->mouseOffset;
 
- }
 
- //! sa ScrollMode
 
- int QwtAbstractSlider::scrollMode() const
 
- {
 
-     return d_data->scrollMode;
 
- }
 
 
  |