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
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
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
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 }