00001
00002
00003
00004
00005
00006
00007
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
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
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 }