Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

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 
00049 QwtAbstractSlider::QwtAbstractSlider(Qt::Orientation orient, QWidget *parent): 
00050     QWidget(parent, NULL)
00051 {
00052     d_data = new QwtAbstractSlider::PrivateData;
00053     d_data->orientation = orient;
00054 
00055 #if QT_VERSION >= 0x040000
00056     using namespace Qt;
00057 #endif
00058     setFocusPolicy(TabFocus);
00059 }
00060 
00062 QwtAbstractSlider::~QwtAbstractSlider()
00063 {
00064     if(d_data->tmrID) 
00065         killTimer(d_data->tmrID);
00066 
00067     delete d_data;
00068 }
00069 
00079 void QwtAbstractSlider::setReadOnly(bool readOnly)
00080 {
00081     d_data->readOnly = readOnly;
00082     update();
00083 }
00084 
00092 bool QwtAbstractSlider::isReadOnly() const
00093 {
00094     return d_data->readOnly;
00095 }
00096 
00102 void QwtAbstractSlider::setOrientation(Qt::Orientation o)
00103 {
00104     d_data->orientation = o;
00105 }
00106 
00111 Qt::Orientation QwtAbstractSlider::orientation() const
00112 {
00113     return d_data->orientation;
00114 }
00115 
00117 
00118 void QwtAbstractSlider::stopMoving() 
00119 {
00120     if(d_data->tmrID)
00121     {
00122         killTimer(d_data->tmrID);
00123         d_data->tmrID = 0;
00124     }
00125 }
00126 
00132 void QwtAbstractSlider::setUpdateTime(int t) 
00133 {
00134     if (t < 50) 
00135         t = 50;
00136     d_data->updTime = t;
00137 }
00138 
00139 
00141 void QwtAbstractSlider::mousePressEvent(QMouseEvent *e) 
00142 {
00143     if ( isReadOnly() )
00144     {
00145         e->ignore();
00146         return;
00147     }
00148     if ( !isValid() )
00149         return;
00150 
00151     const QPoint &p = e->pos();
00152 
00153     d_data->timerTick = 0;
00154 
00155     getScrollMode(p, d_data->scrollMode, d_data->direction);
00156     stopMoving();
00157     
00158     switch(d_data->scrollMode)
00159     {
00160         case ScrPage:
00161         case ScrTimer:
00162             d_data->mouseOffset = 0;
00163             d_data->tmrID = startTimer(qwtMax(250, 2 * d_data->updTime));
00164             break;
00165         
00166         case ScrMouse:
00167             d_data->time.start();
00168             d_data->speed = 0;
00169             d_data->mouseOffset = getValue(p) - value();
00170             emit sliderPressed();
00171             break;
00172         
00173         default:
00174             d_data->mouseOffset = 0;
00175             d_data->direction = 0;
00176             break;
00177     }
00178 }
00179 
00180 
00182 void QwtAbstractSlider::buttonReleased()
00183 {
00184     if ((!d_data->tracking) || (value() != prevValue()))
00185         emit valueChanged(value());
00186 }
00187 
00188 
00190 void QwtAbstractSlider::mouseReleaseEvent(QMouseEvent *e)
00191 {
00192     if ( isReadOnly() )
00193     {
00194         e->ignore();
00195         return;
00196     }
00197     if ( !isValid() )
00198         return;
00199 
00200     const double inc = step();
00201     
00202     switch(d_data->scrollMode) 
00203     {
00204         case ScrMouse:
00205         {
00206             setPosition(e->pos());
00207             d_data->direction = 0;
00208             d_data->mouseOffset = 0;
00209             if (d_data->mass > 0.0) 
00210             {
00211                 const int ms = d_data->time.elapsed();
00212                 if ((fabs(d_data->speed) >  0.0) && (ms < 50))
00213                     d_data->tmrID = startTimer(d_data->updTime);
00214             }
00215             else
00216             {
00217                 d_data->scrollMode = ScrNone;
00218                 buttonReleased();
00219             }
00220             emit sliderReleased();
00221             
00222             break;
00223         }
00224 
00225         case ScrDirect:
00226         {
00227             setPosition(e->pos());
00228             d_data->direction = 0;
00229             d_data->mouseOffset = 0;
00230             d_data->scrollMode = ScrNone;
00231             buttonReleased();
00232             break;
00233         }
00234 
00235         case ScrPage:
00236         {
00237             stopMoving();
00238             if (!d_data->timerTick)
00239                 QwtDoubleRange::incPages(d_data->direction);
00240             d_data->timerTick = 0;
00241             buttonReleased();
00242             d_data->scrollMode = ScrNone;
00243             break;
00244         }
00245 
00246         case ScrTimer:
00247         {
00248             stopMoving();
00249             if (!d_data->timerTick)
00250                 QwtDoubleRange::fitValue(value() + double(d_data->direction) * inc);
00251             d_data->timerTick = 0;
00252             buttonReleased();
00253             d_data->scrollMode = ScrNone;
00254             break;
00255         }
00256 
00257         default:
00258         {
00259             d_data->scrollMode = ScrNone;
00260             buttonReleased();
00261         }
00262     }
00263 }
00264 
00265 
00270 void QwtAbstractSlider::setPosition(const QPoint &p) 
00271 {
00272     QwtDoubleRange::fitValue(getValue(p) - d_data->mouseOffset);
00273 }
00274 
00275 
00290 void QwtAbstractSlider::setTracking(bool enable)
00291 {
00292     d_data->tracking = enable;
00293 }
00294 
00296 void QwtAbstractSlider::mouseMoveEvent(QMouseEvent *e)
00297 {
00298     if ( isReadOnly() )
00299     {
00300         e->ignore();
00301         return;
00302     }
00303 
00304     if ( !isValid() )
00305         return;
00306 
00307     if (d_data->scrollMode == ScrMouse )
00308     {
00309         setPosition(e->pos());
00310         if (d_data->mass > 0.0) 
00311         {
00312             double ms = double(d_data->time.elapsed());
00313             if (ms < 1.0) 
00314                 ms = 1.0;
00315             d_data->speed = (exactValue() - exactPrevValue()) / ms;
00316             d_data->time.start();
00317         }
00318         if (value() != prevValue())
00319             emit sliderMoved(value());
00320     }
00321 }
00322 
00324 void QwtAbstractSlider::wheelEvent(QWheelEvent *e)
00325 {
00326     if ( isReadOnly() )
00327     {
00328         e->ignore();
00329         return;
00330     }
00331 
00332     if ( !isValid() )
00333         return;
00334 
00335     int mode = ScrNone, direction = 0;
00336 
00337     // Give derived classes a chance to say ScrNone
00338     getScrollMode(e->pos(), mode, direction);
00339     if ( mode != ScrNone )
00340     {
00341         const int inc = e->delta() / WHEEL_DELTA;
00342         QwtDoubleRange::incPages(inc);
00343         if (value() != prevValue())
00344             emit sliderMoved(value());
00345     }
00346 }
00347 
00359 void QwtAbstractSlider::keyPressEvent(QKeyEvent *e)
00360 {
00361     if ( isReadOnly() )
00362     {
00363         e->ignore();
00364         return;
00365     }
00366 
00367     if ( !isValid() )
00368         return;
00369 
00370     int increment = 0;
00371     switch ( e->key() ) 
00372     {
00373         case Qt::Key_Down:
00374             if ( orientation() == Qt::Vertical )
00375                 increment = -1;
00376             break;
00377         case Qt::Key_Up:
00378             if ( orientation() == Qt::Vertical )
00379                 increment = 1;
00380             break;
00381         case Qt::Key_Left:
00382             if ( orientation() == Qt::Horizontal )
00383                 increment = -1;
00384             break;
00385         case Qt::Key_Right:
00386             if ( orientation() == Qt::Horizontal )
00387                 increment = 1;
00388             break;
00389         default:;
00390             e->ignore();
00391     }
00392 
00393     if ( increment != 0 )
00394     {
00395         QwtDoubleRange::incValue(increment);
00396         if (value() != prevValue())
00397             emit sliderMoved(value());
00398     }
00399 }
00400 
00402 void QwtAbstractSlider::timerEvent(QTimerEvent *)
00403 {
00404     const double inc = step();
00405 
00406     switch (d_data->scrollMode)
00407     {
00408         case ScrMouse:
00409         {
00410             if (d_data->mass > 0.0)
00411             {
00412                 d_data->speed *= exp( - double(d_data->updTime) * 0.001 / d_data->mass );
00413                 const double newval = 
00414                     exactValue() + d_data->speed * double(d_data->updTime);
00415                 QwtDoubleRange::fitValue(newval);
00416                 // stop if d_data->speed < one step per second
00417                 if (fabs(d_data->speed) < 0.001 * fabs(step()))
00418                 {
00419                     d_data->speed = 0;
00420                     stopMoving();
00421                     buttonReleased();
00422                 }
00423 
00424             }
00425             else
00426                stopMoving();
00427             break;
00428         }
00429 
00430         case ScrPage:
00431         {
00432             QwtDoubleRange::incPages(d_data->direction);
00433             if (!d_data->timerTick) 
00434             {
00435                 killTimer(d_data->tmrID);
00436                 d_data->tmrID = startTimer(d_data->updTime);
00437             }
00438             break;
00439         }
00440         case ScrTimer:
00441         {
00442             QwtDoubleRange::fitValue(value() +  double(d_data->direction) * inc);
00443             if (!d_data->timerTick) 
00444             {
00445                 killTimer(d_data->tmrID);
00446                 d_data->tmrID = startTimer(d_data->updTime);
00447             }
00448             break;
00449         }
00450         default:
00451         {
00452             stopMoving();
00453             break;
00454         }
00455     }
00456 
00457     d_data->timerTick = 1;
00458 }
00459 
00460 
00469 void QwtAbstractSlider::valueChange() 
00470 {
00471     if (d_data->tracking)
00472        emit valueChanged(value());  
00473 }
00474 
00492 void QwtAbstractSlider::setMass(double val)
00493 {
00494     if (val < 0.001)
00495        d_data->mass = 0.0;
00496     else if (val > 100.0)
00497        d_data->mass = 100.0;
00498     else
00499        d_data->mass = val;
00500 }
00501 
00506 double QwtAbstractSlider::mass() const
00507 {   
00508     return d_data->mass; 
00509 }
00510 
00511 
00520 void QwtAbstractSlider::setValue(double val)
00521 {
00522     if (d_data->scrollMode == ScrMouse) 
00523         stopMoving();
00524     QwtDoubleRange::setValue(val);
00525 }
00526 
00527 
00533 void QwtAbstractSlider::fitValue(double val)
00534 {
00535     if (d_data->scrollMode == ScrMouse) 
00536         stopMoving();
00537     QwtDoubleRange::fitValue(val);
00538 }
00539 
00540 
00545 void QwtAbstractSlider::incValue(int steps)
00546 {
00547     if (d_data->scrollMode == ScrMouse) 
00548         stopMoving();
00549     QwtDoubleRange::incValue(steps);
00550 }
00551 
00552 void QwtAbstractSlider::setMouseOffset(double offset)
00553 {
00554     d_data->mouseOffset = offset;
00555 } 
00556 
00557 double QwtAbstractSlider::mouseOffset() const
00558 {
00559     return d_data->mouseOffset;
00560 }
00561 
00562 int QwtAbstractSlider::scrollMode() const
00563 {
00564     return d_data->scrollMode;
00565 }

Generated on Mon Jan 30 22:16:25 2006 for Qwt User's Guide by  doxygen 1.4.4