Go to the documentation of this file.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
00150 void QwtAbstractSlider::mousePressEvent(QMouseEvent *e)
00151 {
00152 if ( isReadOnly() )
00153 {
00154 e->ignore();
00155 return;
00156 }
00157 if ( !isValid() )
00158 return;
00159
00160 const QPoint &p = e->pos();
00161
00162 d_data->timerTick = 0;
00163
00164 getScrollMode(p, d_data->scrollMode, d_data->direction);
00165 stopMoving();
00166
00167 switch(d_data->scrollMode)
00168 {
00169 case ScrPage:
00170 case ScrTimer:
00171 d_data->mouseOffset = 0;
00172 d_data->tmrID = startTimer(qwtMax(250, 2 * d_data->updTime));
00173 break;
00174
00175 case ScrMouse:
00176 d_data->time.start();
00177 d_data->speed = 0;
00178 d_data->mouseOffset = getValue(p) - value();
00179 emit sliderPressed();
00180 break;
00181
00182 default:
00183 d_data->mouseOffset = 0;
00184 d_data->direction = 0;
00185 break;
00186 }
00187 }
00188
00189
00191 void QwtAbstractSlider::buttonReleased()
00192 {
00193 if ((!d_data->tracking) || (value() != prevValue()))
00194 emit valueChanged(value());
00195 }
00196
00197
00202 void QwtAbstractSlider::mouseReleaseEvent(QMouseEvent *e)
00203 {
00204 if ( isReadOnly() )
00205 {
00206 e->ignore();
00207 return;
00208 }
00209 if ( !isValid() )
00210 return;
00211
00212 const double inc = step();
00213
00214 switch(d_data->scrollMode)
00215 {
00216 case ScrMouse:
00217 {
00218 setPosition(e->pos());
00219 d_data->direction = 0;
00220 d_data->mouseOffset = 0;
00221 if (d_data->mass > 0.0)
00222 {
00223 const int ms = d_data->time.elapsed();
00224 if ((fabs(d_data->speed) > 0.0) && (ms < 50))
00225 d_data->tmrID = startTimer(d_data->updTime);
00226 }
00227 else
00228 {
00229 d_data->scrollMode = ScrNone;
00230 buttonReleased();
00231 }
00232 emit sliderReleased();
00233
00234 break;
00235 }
00236
00237 case ScrDirect:
00238 {
00239 setPosition(e->pos());
00240 d_data->direction = 0;
00241 d_data->mouseOffset = 0;
00242 d_data->scrollMode = ScrNone;
00243 buttonReleased();
00244 break;
00245 }
00246
00247 case ScrPage:
00248 {
00249 stopMoving();
00250 if (!d_data->timerTick)
00251 QwtDoubleRange::incPages(d_data->direction);
00252 d_data->timerTick = 0;
00253 buttonReleased();
00254 d_data->scrollMode = ScrNone;
00255 break;
00256 }
00257
00258 case ScrTimer:
00259 {
00260 stopMoving();
00261 if (!d_data->timerTick)
00262 QwtDoubleRange::fitValue(value() + double(d_data->direction) * inc);
00263 d_data->timerTick = 0;
00264 buttonReleased();
00265 d_data->scrollMode = ScrNone;
00266 break;
00267 }
00268
00269 default:
00270 {
00271 d_data->scrollMode = ScrNone;
00272 buttonReleased();
00273 }
00274 }
00275 }
00276
00277
00282 void QwtAbstractSlider::setPosition(const QPoint &p)
00283 {
00284 QwtDoubleRange::fitValue(getValue(p) - d_data->mouseOffset);
00285 }
00286
00287
00302 void QwtAbstractSlider::setTracking(bool enable)
00303 {
00304 d_data->tracking = enable;
00305 }
00306
00311 void QwtAbstractSlider::mouseMoveEvent(QMouseEvent *e)
00312 {
00313 if ( isReadOnly() )
00314 {
00315 e->ignore();
00316 return;
00317 }
00318
00319 if ( !isValid() )
00320 return;
00321
00322 if (d_data->scrollMode == ScrMouse )
00323 {
00324 setPosition(e->pos());
00325 if (d_data->mass > 0.0)
00326 {
00327 double ms = double(d_data->time.elapsed());
00328 if (ms < 1.0)
00329 ms = 1.0;
00330 d_data->speed = (exactValue() - exactPrevValue()) / ms;
00331 d_data->time.start();
00332 }
00333 if (value() != prevValue())
00334 emit sliderMoved(value());
00335 }
00336 }
00337
00342 void QwtAbstractSlider::wheelEvent(QWheelEvent *e)
00343 {
00344 if ( isReadOnly() )
00345 {
00346 e->ignore();
00347 return;
00348 }
00349
00350 if ( !isValid() )
00351 return;
00352
00353 int mode = ScrNone, direction = 0;
00354
00355
00356 getScrollMode(e->pos(), mode, direction);
00357 if ( mode != ScrNone )
00358 {
00359 const int inc = e->delta() / WHEEL_DELTA;
00360 QwtDoubleRange::incPages(inc);
00361 if (value() != prevValue())
00362 emit sliderMoved(value());
00363 }
00364 }
00365
00377 void QwtAbstractSlider::keyPressEvent(QKeyEvent *e)
00378 {
00379 if ( isReadOnly() )
00380 {
00381 e->ignore();
00382 return;
00383 }
00384
00385 if ( !isValid() )
00386 return;
00387
00388 int increment = 0;
00389 switch ( e->key() )
00390 {
00391 case Qt::Key_Down:
00392 if ( orientation() == Qt::Vertical )
00393 increment = -1;
00394 break;
00395 case Qt::Key_Up:
00396 if ( orientation() == Qt::Vertical )
00397 increment = 1;
00398 break;
00399 case Qt::Key_Left:
00400 if ( orientation() == Qt::Horizontal )
00401 increment = -1;
00402 break;
00403 case Qt::Key_Right:
00404 if ( orientation() == Qt::Horizontal )
00405 increment = 1;
00406 break;
00407 default:;
00408 e->ignore();
00409 }
00410
00411 if ( increment != 0 )
00412 {
00413 QwtDoubleRange::incValue(increment);
00414 if (value() != prevValue())
00415 emit sliderMoved(value());
00416 }
00417 }
00418
00423 void QwtAbstractSlider::timerEvent(QTimerEvent *)
00424 {
00425 const double inc = step();
00426
00427 switch (d_data->scrollMode)
00428 {
00429 case ScrMouse:
00430 {
00431 if (d_data->mass > 0.0)
00432 {
00433 d_data->speed *= exp( - double(d_data->updTime) * 0.001 / d_data->mass );
00434 const double newval =
00435 exactValue() + d_data->speed * double(d_data->updTime);
00436 QwtDoubleRange::fitValue(newval);
00437
00438 if (fabs(d_data->speed) < 0.001 * fabs(step()))
00439 {
00440 d_data->speed = 0;
00441 stopMoving();
00442 buttonReleased();
00443 }
00444
00445 }
00446 else
00447 stopMoving();
00448 break;
00449 }
00450
00451 case ScrPage:
00452 {
00453 QwtDoubleRange::incPages(d_data->direction);
00454 if (!d_data->timerTick)
00455 {
00456 killTimer(d_data->tmrID);
00457 d_data->tmrID = startTimer(d_data->updTime);
00458 }
00459 break;
00460 }
00461 case ScrTimer:
00462 {
00463 QwtDoubleRange::fitValue(value() + double(d_data->direction) * inc);
00464 if (!d_data->timerTick)
00465 {
00466 killTimer(d_data->tmrID);
00467 d_data->tmrID = startTimer(d_data->updTime);
00468 }
00469 break;
00470 }
00471 default:
00472 {
00473 stopMoving();
00474 break;
00475 }
00476 }
00477
00478 d_data->timerTick = 1;
00479 }
00480
00481
00490 void QwtAbstractSlider::valueChange()
00491 {
00492 if (d_data->tracking)
00493 emit valueChanged(value());
00494 }
00495
00513 void QwtAbstractSlider::setMass(double val)
00514 {
00515 if (val < 0.001)
00516 d_data->mass = 0.0;
00517 else if (val > 100.0)
00518 d_data->mass = 100.0;
00519 else
00520 d_data->mass = val;
00521 }
00522
00527 double QwtAbstractSlider::mass() const
00528 {
00529 return d_data->mass;
00530 }
00531
00532
00541 void QwtAbstractSlider::setValue(double val)
00542 {
00543 if (d_data->scrollMode == ScrMouse)
00544 stopMoving();
00545 QwtDoubleRange::setValue(val);
00546 }
00547
00548
00556 void QwtAbstractSlider::fitValue(double value)
00557 {
00558 if (d_data->scrollMode == ScrMouse)
00559 stopMoving();
00560 QwtDoubleRange::fitValue(value);
00561 }
00562
00568 void QwtAbstractSlider::incValue(int steps)
00569 {
00570 if (d_data->scrollMode == ScrMouse)
00571 stopMoving();
00572 QwtDoubleRange::incValue(steps);
00573 }
00574
00575 void QwtAbstractSlider::setMouseOffset(double offset)
00576 {
00577 d_data->mouseOffset = offset;
00578 }
00579
00580 double QwtAbstractSlider::mouseOffset() const
00581 {
00582 return d_data->mouseOffset;
00583 }
00584
00585 int QwtAbstractSlider::scrollMode() const
00586 {
00587 return d_data->scrollMode;
00588 }