qwt_abstract_slider.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include <qevent.h>
00011 #include <qdatetime.h>
00012 #include "qwt_abstract_slider.h"
00013 #include "qwt_math.h"
00014 
00015 #ifndef WHEEL_DELTA
00016 #define WHEEL_DELTA 120
00017 #endif
00018 
00019 class QwtAbstractSlider::PrivateData
00020 {
00021 public:
00022     PrivateData():
00023         scrollMode(ScrNone),
00024         mouseOffset(0.0),
00025         tracking(true),
00026         tmrID(0),
00027         updTime(150),
00028         mass(0.0),
00029         readOnly(false)
00030     {
00031     }
00032 
00033     int scrollMode;
00034     double mouseOffset;
00035     int direction;
00036     int tracking;
00037 
00038     int tmrID;
00039     int updTime;
00040     int timerTick;
00041     QTime time;
00042     double speed;
00043     double mass;
00044     Qt::Orientation orientation;
00045     bool readOnly;
00046 };
00047 
00054 QwtAbstractSlider::QwtAbstractSlider(
00055         Qt::Orientation orientation, QWidget *parent): 
00056     QWidget(parent, NULL)
00057 {
00058     d_data = new QwtAbstractSlider::PrivateData;
00059     d_data->orientation = orientation;
00060 
00061 #if QT_VERSION >= 0x040000
00062     using namespace Qt;
00063 #endif
00064     setFocusPolicy(TabFocus);
00065 }
00066 
00068 QwtAbstractSlider::~QwtAbstractSlider()
00069 {
00070     if(d_data->tmrID) 
00071         killTimer(d_data->tmrID);
00072 
00073     delete d_data;
00074 }
00075 
00085 void QwtAbstractSlider::setReadOnly(bool readOnly)
00086 {
00087     d_data->readOnly = readOnly;
00088     update();
00089 }
00090 
00098 bool QwtAbstractSlider::isReadOnly() const
00099 {
00100     return d_data->readOnly;
00101 }
00102 
00108 void QwtAbstractSlider::setOrientation(Qt::Orientation o)
00109 {
00110     d_data->orientation = o;
00111 }
00112 
00117 Qt::Orientation QwtAbstractSlider::orientation() const
00118 {
00119     return d_data->orientation;
00120 }
00121 
00123 
00124 void QwtAbstractSlider::stopMoving() 
00125 {
00126     if(d_data->tmrID)
00127     {
00128         killTimer(d_data->tmrID);
00129         d_data->tmrID = 0;
00130     }
00131 }
00132 
00138 void QwtAbstractSlider::setUpdateTime(int t) 
00139 {
00140     if (t < 50) 
00141         t = 50;
00142     d_data->updTime = t;
00143 }
00144 
00145 
00147 void QwtAbstractSlider::mousePressEvent(QMouseEvent *e) 
00148 {
00149     if ( isReadOnly() )
00150     {
00151         e->ignore();
00152         return;
00153     }
00154     if ( !isValid() )
00155         return;
00156 
00157     const QPoint &p = e->pos();
00158 
00159     d_data->timerTick = 0;
00160 
00161     getScrollMode(p, d_data->scrollMode, d_data->direction);
00162     stopMoving();
00163     
00164     switch(d_data->scrollMode)
00165     {
00166         case ScrPage:
00167         case ScrTimer:
00168             d_data->mouseOffset = 0;
00169             d_data->tmrID = startTimer(qwtMax(250, 2 * d_data->updTime));
00170             break;
00171         
00172         case ScrMouse:
00173             d_data->time.start();
00174             d_data->speed = 0;
00175             d_data->mouseOffset = getValue(p) - value();
00176             emit sliderPressed();
00177             break;
00178         
00179         default:
00180             d_data->mouseOffset = 0;
00181             d_data->direction = 0;
00182             break;
00183     }
00184 }
00185 
00186 
00188 void QwtAbstractSlider::buttonReleased()
00189 {
00190     if ((!d_data->tracking) || (value() != prevValue()))
00191         emit valueChanged(value());
00192 }
00193 
00194 
00196 void QwtAbstractSlider::mouseReleaseEvent(QMouseEvent *e)
00197 {
00198     if ( isReadOnly() )
00199     {
00200         e->ignore();
00201         return;
00202     }
00203     if ( !isValid() )
00204         return;
00205 
00206     const double inc = step();
00207     
00208     switch(d_data->scrollMode) 
00209     {
00210         case ScrMouse:
00211         {
00212             setPosition(e->pos());
00213             d_data->direction = 0;
00214             d_data->mouseOffset = 0;
00215             if (d_data->mass > 0.0) 
00216             {
00217                 const int ms = d_data->time.elapsed();
00218                 if ((fabs(d_data->speed) >  0.0) && (ms < 50))
00219                     d_data->tmrID = startTimer(d_data->updTime);
00220             }
00221             else
00222             {
00223                 d_data->scrollMode = ScrNone;
00224                 buttonReleased();
00225             }
00226             emit sliderReleased();
00227             
00228             break;
00229         }
00230 
00231         case ScrDirect:
00232         {
00233             setPosition(e->pos());
00234             d_data->direction = 0;
00235             d_data->mouseOffset = 0;
00236             d_data->scrollMode = ScrNone;
00237             buttonReleased();
00238             break;
00239         }
00240 
00241         case ScrPage:
00242         {
00243             stopMoving();
00244             if (!d_data->timerTick)
00245                 QwtDoubleRange::incPages(d_data->direction);
00246             d_data->timerTick = 0;
00247             buttonReleased();
00248             d_data->scrollMode = ScrNone;
00249             break;
00250         }
00251 
00252         case ScrTimer:
00253         {
00254             stopMoving();
00255             if (!d_data->timerTick)
00256                 QwtDoubleRange::fitValue(value() + double(d_data->direction) * inc);
00257             d_data->timerTick = 0;
00258             buttonReleased();
00259             d_data->scrollMode = ScrNone;
00260             break;
00261         }
00262 
00263         default:
00264         {
00265             d_data->scrollMode = ScrNone;
00266             buttonReleased();
00267         }
00268     }
00269 }
00270 
00271 
00276 void QwtAbstractSlider::setPosition(const QPoint &p) 
00277 {
00278     QwtDoubleRange::fitValue(getValue(p) - d_data->mouseOffset);
00279 }
00280 
00281 
00296 void QwtAbstractSlider::setTracking(bool enable)
00297 {
00298     d_data->tracking = enable;
00299 }
00300 
00305 void QwtAbstractSlider::mouseMoveEvent(QMouseEvent *e)
00306 {
00307     if ( isReadOnly() )
00308     {
00309         e->ignore();
00310         return;
00311     }
00312 
00313     if ( !isValid() )
00314         return;
00315 
00316     if (d_data->scrollMode == ScrMouse )
00317     {
00318         setPosition(e->pos());
00319         if (d_data->mass > 0.0) 
00320         {
00321             double ms = double(d_data->time.elapsed());
00322             if (ms < 1.0) 
00323                 ms = 1.0;
00324             d_data->speed = (exactValue() - exactPrevValue()) / ms;
00325             d_data->time.start();
00326         }
00327         if (value() != prevValue())
00328             emit sliderMoved(value());
00329     }
00330 }
00331 
00336 void QwtAbstractSlider::wheelEvent(QWheelEvent *e)
00337 {
00338     if ( isReadOnly() )
00339     {
00340         e->ignore();
00341         return;
00342     }
00343 
00344     if ( !isValid() )
00345         return;
00346 
00347     int mode = ScrNone, direction = 0;
00348 
00349     // Give derived classes a chance to say ScrNone
00350     getScrollMode(e->pos(), mode, direction);
00351     if ( mode != ScrNone )
00352     {
00353         const int inc = e->delta() / WHEEL_DELTA;
00354         QwtDoubleRange::incPages(inc);
00355         if (value() != prevValue())
00356             emit sliderMoved(value());
00357     }
00358 }
00359 
00371 void QwtAbstractSlider::keyPressEvent(QKeyEvent *e)
00372 {
00373     if ( isReadOnly() )
00374     {
00375         e->ignore();
00376         return;
00377     }
00378 
00379     if ( !isValid() )
00380         return;
00381 
00382     int increment = 0;
00383     switch ( e->key() ) 
00384     {
00385         case Qt::Key_Down:
00386             if ( orientation() == Qt::Vertical )
00387                 increment = -1;
00388             break;
00389         case Qt::Key_Up:
00390             if ( orientation() == Qt::Vertical )
00391                 increment = 1;
00392             break;
00393         case Qt::Key_Left:
00394             if ( orientation() == Qt::Horizontal )
00395                 increment = -1;
00396             break;
00397         case Qt::Key_Right:
00398             if ( orientation() == Qt::Horizontal )
00399                 increment = 1;
00400             break;
00401         default:;
00402             e->ignore();
00403     }
00404 
00405     if ( increment != 0 )
00406     {
00407         QwtDoubleRange::incValue(increment);
00408         if (value() != prevValue())
00409             emit sliderMoved(value());
00410     }
00411 }
00412 
00417 void QwtAbstractSlider::timerEvent(QTimerEvent *)
00418 {
00419     const double inc = step();
00420 
00421     switch (d_data->scrollMode)
00422     {
00423         case ScrMouse:
00424         {
00425             if (d_data->mass > 0.0)
00426             {
00427                 d_data->speed *= exp( - double(d_data->updTime) * 0.001 / d_data->mass );
00428                 const double newval = 
00429                     exactValue() + d_data->speed * double(d_data->updTime);
00430                 QwtDoubleRange::fitValue(newval);
00431                 // stop if d_data->speed < one step per second
00432                 if (fabs(d_data->speed) < 0.001 * fabs(step()))
00433                 {
00434                     d_data->speed = 0;
00435                     stopMoving();
00436                     buttonReleased();
00437                 }
00438 
00439             }
00440             else
00441                stopMoving();
00442             break;
00443         }
00444 
00445         case ScrPage:
00446         {
00447             QwtDoubleRange::incPages(d_data->direction);
00448             if (!d_data->timerTick) 
00449             {
00450                 killTimer(d_data->tmrID);
00451                 d_data->tmrID = startTimer(d_data->updTime);
00452             }
00453             break;
00454         }
00455         case ScrTimer:
00456         {
00457             QwtDoubleRange::fitValue(value() +  double(d_data->direction) * inc);
00458             if (!d_data->timerTick) 
00459             {
00460                 killTimer(d_data->tmrID);
00461                 d_data->tmrID = startTimer(d_data->updTime);
00462             }
00463             break;
00464         }
00465         default:
00466         {
00467             stopMoving();
00468             break;
00469         }
00470     }
00471 
00472     d_data->timerTick = 1;
00473 }
00474 
00475 
00484 void QwtAbstractSlider::valueChange() 
00485 {
00486     if (d_data->tracking)
00487        emit valueChanged(value());  
00488 }
00489 
00507 void QwtAbstractSlider::setMass(double val)
00508 {
00509     if (val < 0.001)
00510        d_data->mass = 0.0;
00511     else if (val > 100.0)
00512        d_data->mass = 100.0;
00513     else
00514        d_data->mass = val;
00515 }
00516 
00521 double QwtAbstractSlider::mass() const
00522 {   
00523     return d_data->mass; 
00524 }
00525 
00526 
00535 void QwtAbstractSlider::setValue(double val)
00536 {
00537     if (d_data->scrollMode == ScrMouse) 
00538         stopMoving();
00539     QwtDoubleRange::setValue(val);
00540 }
00541 
00542 
00550 void QwtAbstractSlider::fitValue(double value)
00551 {
00552     if (d_data->scrollMode == ScrMouse) 
00553         stopMoving();
00554     QwtDoubleRange::fitValue(value);
00555 }
00556 
00562 void QwtAbstractSlider::incValue(int steps)
00563 {
00564     if (d_data->scrollMode == ScrMouse) 
00565         stopMoving();
00566     QwtDoubleRange::incValue(steps);
00567 }
00568 
00569 void QwtAbstractSlider::setMouseOffset(double offset)
00570 {
00571     d_data->mouseOffset = offset;
00572 } 
00573 
00574 double QwtAbstractSlider::mouseOffset() const
00575 {
00576     return d_data->mouseOffset;
00577 }
00578 
00579 int QwtAbstractSlider::scrollMode() const
00580 {
00581     return d_data->scrollMode;
00582 }

Generated on Mon Feb 26 21:22:36 2007 for Qwt User's Guide by  doxygen 1.4.6