00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qapplication.h>
00025 #include "qabstractslider.h"
00026 #include "qevent.h"
00027 #include "qabstractslider_p.h"
00028 #include "qdebug.h"
00029 #ifndef QT_NO_ACCESSIBILITY
00030 #include "qaccessible.h"
00031 #endif
00032 #include <limits.h>
00033
00193 QAbstractSliderPrivate::QAbstractSliderPrivate()
00194 : minimum(0), maximum(99), singleStep(1), pageStep(10),
00195 value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false),
00196 invertedAppearance(false), invertedControls(false),
00197 orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
00198 {
00199 }
00200
00201 QAbstractSliderPrivate::~QAbstractSliderPrivate()
00202 {
00203 }
00204
00213 void QAbstractSlider::setRange(int min, int max)
00214 {
00215 Q_D(QAbstractSlider);
00216 int oldMin = d->minimum;
00217 int oldMax = d->maximum;
00218 d->minimum = min;
00219 d->maximum = qMax(min, max);
00220 if (oldMin != d->minimum || oldMax != d->maximum) {
00221 sliderChange(SliderRangeChange);
00222 emit rangeChanged(d->minimum, d->maximum);
00223 setValue(d->value);
00224 }
00225 }
00226
00227
00228 void QAbstractSliderPrivate::setSteps(int single, int page)
00229 {
00230 Q_Q(QAbstractSlider);
00231 singleStep = qAbs(single);
00232 pageStep = qAbs(page);
00233 q->sliderChange(QAbstractSlider::SliderStepsChange);
00234 }
00235
00245 QAbstractSlider::QAbstractSlider(QWidget *parent)
00246 :QWidget(*new QAbstractSliderPrivate, parent, 0)
00247 {
00248 }
00249
00251 QAbstractSlider::QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent)
00252 :QWidget(dd, parent, 0)
00253 {
00254 }
00255
00259 QAbstractSlider::~QAbstractSlider()
00260 {
00261 }
00262
00270 void QAbstractSlider::setOrientation(Qt::Orientation orientation)
00271 {
00272 Q_D(QAbstractSlider);
00273 if (d->orientation == orientation)
00274 return;
00275
00276 d->orientation = orientation;
00277 if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
00278 QSizePolicy sp = sizePolicy();
00279 sp.transpose();
00280 setSizePolicy(sp);
00281 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00282 }
00283 update();
00284 updateGeometry();
00285 }
00286
00287 Qt::Orientation QAbstractSlider::orientation() const
00288 {
00289 Q_D(const QAbstractSlider);
00290 return d->orientation;
00291 }
00292
00293
00304 void QAbstractSlider::setMinimum(int min)
00305 {
00306 Q_D(QAbstractSlider);
00307 setRange(min, qMax(d->maximum, min));
00308 }
00309
00310 int QAbstractSlider::minimum() const
00311 {
00312 Q_D(const QAbstractSlider);
00313 return d->minimum;
00314 }
00315
00316
00328 void QAbstractSlider::setMaximum(int max)
00329 {
00330 Q_D(QAbstractSlider);
00331 setRange(qMin(d->minimum, max), max);
00332 }
00333
00334 int QAbstractSlider::maximum() const
00335 {
00336 Q_D(const QAbstractSlider);
00337 return d->maximum;
00338 }
00339
00340
00341
00353 void QAbstractSlider::setSingleStep(int step)
00354 {
00355 Q_D(QAbstractSlider);
00356 d->setSteps(step, d->pageStep);
00357 }
00358
00359 int QAbstractSlider::singleStep() const
00360 {
00361 Q_D(const QAbstractSlider);
00362 return d->singleStep;
00363 }
00364
00365
00376 void QAbstractSlider::setPageStep(int step)
00377 {
00378 Q_D(QAbstractSlider);
00379 d->setSteps(d->singleStep, step);
00380 }
00381
00382 int QAbstractSlider::pageStep() const
00383 {
00384 Q_D(const QAbstractSlider);
00385 return d->pageStep;
00386 }
00387
00399 void QAbstractSlider::setTracking(bool enable)
00400 {
00401 Q_D(QAbstractSlider);
00402 d->tracking = enable;
00403 }
00404
00405 bool QAbstractSlider::hasTracking() const
00406 {
00407 Q_D(const QAbstractSlider);
00408 return d->tracking;
00409 }
00410
00411
00423 void QAbstractSlider::setSliderDown(bool down)
00424 {
00425 Q_D(QAbstractSlider);
00426 bool doEmit = d->pressed != down;
00427
00428 d->pressed = down;
00429
00430 if (doEmit) {
00431 if (down)
00432 emit sliderPressed();
00433 else
00434 emit sliderReleased();
00435 }
00436
00437 if (!down && d->position != d->value)
00438 triggerAction(SliderMove);
00439 }
00440
00441 bool QAbstractSlider::isSliderDown() const
00442 {
00443 Q_D(const QAbstractSlider);
00444 return d->pressed;
00445 }
00446
00447
00454 void QAbstractSlider::setSliderPosition(int position)
00455 {
00456 Q_D(QAbstractSlider);
00457 position = d->bound(position);
00458 if (position == d->position)
00459 return;
00460 d->position = position;
00461 if (!d->tracking)
00462 update();
00463 if (d->pressed)
00464 emit sliderMoved(position);
00465 if (d->tracking && !d->blocktracking)
00466 triggerAction(SliderMove);
00467 }
00468
00469 int QAbstractSlider::sliderPosition() const
00470 {
00471 Q_D(const QAbstractSlider);
00472 return d->position;
00473 }
00474
00475
00487 int QAbstractSlider::value() const
00488 {
00489 Q_D(const QAbstractSlider);
00490 return d->value;
00491 }
00492
00493 void QAbstractSlider::setValue(int value)
00494 {
00495 Q_D(QAbstractSlider);
00496 value = d->bound(value);
00497 if (d->value == value && d->position == value)
00498 return;
00499 d->value = value;
00500 if (d->position != value) {
00501 d->position = value;
00502 if (d->pressed)
00503 emit sliderMoved((d->position = value));
00504 }
00505 #ifndef QT_NO_ACCESSIBILITY
00506 QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
00507 #endif
00508 sliderChange(SliderValueChange);
00509 emit valueChanged(value);
00510 }
00511
00521 bool QAbstractSlider::invertedAppearance() const
00522 {
00523 Q_D(const QAbstractSlider);
00524 return d->invertedAppearance;
00525 }
00526
00527 void QAbstractSlider::setInvertedAppearance(bool invert)
00528 {
00529 Q_D(QAbstractSlider);
00530 d->invertedAppearance = invert;
00531 update();
00532 }
00533
00534
00545 bool QAbstractSlider::invertedControls() const
00546 {
00547 Q_D(const QAbstractSlider);
00548 return d->invertedControls;
00549 }
00550
00551 void QAbstractSlider::setInvertedControls(bool invert)
00552 {
00553 Q_D(QAbstractSlider);
00554 d->invertedControls = invert;
00555 }
00556
00564 void QAbstractSlider::triggerAction(SliderAction action)
00565 {
00566 Q_D(QAbstractSlider);
00567 d->blocktracking = true;
00568 switch (action) {
00569 case SliderSingleStepAdd:
00570 setSliderPosition(d->value + d->singleStep);
00571 break;
00572 case SliderSingleStepSub:
00573 setSliderPosition(d->value - d->singleStep);
00574 break;
00575 case SliderPageStepAdd:
00576 setSliderPosition(d->value + d->pageStep);
00577 break;
00578 case SliderPageStepSub:
00579 setSliderPosition(d->value - d->pageStep);
00580 break;
00581 case SliderToMinimum:
00582 setSliderPosition(d->minimum);
00583 break;
00584 case SliderToMaximum:
00585 setSliderPosition(d->maximum);
00586 break;
00587 case SliderMove:
00588 case SliderNoAction:
00589 break;
00590 };
00591 emit actionTriggered(action);
00592 d->blocktracking = false;
00593 setValue(d->position);
00594 }
00595
00601 void QAbstractSlider::setRepeatAction(SliderAction action, int thresholdTime, int repeatTime)
00602 {
00603 Q_D(QAbstractSlider);
00604 if ((d->repeatAction = action) == SliderNoAction) {
00605 d->repeatActionTimer.stop();
00606 } else {
00607 d->repeatActionTime = repeatTime;
00608 d->repeatActionTimer.start(thresholdTime, this);
00609 }
00610 }
00611
00616 QAbstractSlider::SliderAction QAbstractSlider::repeatAction() const
00617 {
00618 Q_D(const QAbstractSlider);
00619 return d->repeatAction;
00620 }
00621
00624 void QAbstractSlider::timerEvent(QTimerEvent *e)
00625 {
00626 Q_D(QAbstractSlider);
00627 if (e->timerId() == d->repeatActionTimer.timerId()) {
00628 if (d->repeatActionTime) {
00629 d->repeatActionTimer.start(d->repeatActionTime, this);
00630 d->repeatActionTime = 0;
00631 }
00632 if (d->repeatAction == SliderPageStepAdd)
00633 d->setAdjustedSliderPosition(d->value + d->pageStep);
00634 else if (d->repeatAction == SliderPageStepSub)
00635 d->setAdjustedSliderPosition(d->value - d->pageStep);
00636 else
00637 triggerAction(d->repeatAction);
00638 }
00639 }
00640
00648 void QAbstractSlider::sliderChange(SliderChange)
00649 {
00650 update();
00651 }
00652
00653
00657 #ifndef QT_NO_WHEELEVENT
00658 void QAbstractSlider::wheelEvent(QWheelEvent * e)
00659 {
00660 Q_D(QAbstractSlider);
00661 e->ignore();
00662 if (e->orientation() != d->orientation && !rect().contains(e->pos()))
00663 return;
00664
00665 static qreal offset = 0;
00666 static QAbstractSlider *offset_owner = 0;
00667 if (offset_owner != this){
00668 offset_owner = this;
00669 offset = 0;
00670 }
00671
00672 int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep);
00673 if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
00674 step = d->pageStep;
00675 offset += e->delta() * step / 120;
00676 if (d->invertedControls)
00677 offset = -offset;
00678
00679 if (qAbs(offset) < 1)
00680 return;
00681
00682 int prevValue = d->value;
00683 d->position = d->value + int(offset);
00684 triggerAction(SliderMove);
00685 if (prevValue == d->value) {
00686 offset = 0;
00687 } else {
00688 offset -= int(offset);
00689 e->accept();
00690 }
00691 }
00692 #endif
00693
00696 void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
00697 {
00698 Q_D(QAbstractSlider);
00699 SliderAction action = SliderNoAction;
00700 switch (ev->key()) {
00701
00702
00703 case Qt::Key_Left:
00704 #ifdef QT_KEYPAD_NAVIGATION
00705 if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
00706 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
00707 else
00708 #endif
00709 action = !d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd;
00710 break;
00711 case Qt::Key_Right:
00712 #ifdef QT_KEYPAD_NAVIGATION
00713 if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
00714 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
00715 else
00716 #endif
00717 action = !d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub;
00718 break;
00719 case Qt::Key_Up:
00720 #ifdef QT_KEYPAD_NAVIGATION
00721 if (QApplication::keypadNavigationEnabled()) {
00722 ev->ignore();
00723 break;
00724 }
00725 #endif
00726 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
00727 break;
00728 case Qt::Key_Down:
00729 #ifdef QT_KEYPAD_NAVIGATION
00730 if (QApplication::keypadNavigationEnabled()) {
00731 ev->ignore();
00732 break;
00733 }
00734 #endif
00735 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
00736 break;
00737 case Qt::Key_PageUp:
00738 action = d->invertedControls ? SliderPageStepSub : SliderPageStepAdd;
00739 break;
00740 case Qt::Key_PageDown:
00741 action = d->invertedControls ? SliderPageStepAdd : SliderPageStepSub;
00742 break;
00743 case Qt::Key_Home:
00744 action = SliderToMinimum;
00745 break;
00746 case Qt::Key_End:
00747 action = SliderToMaximum;
00748 break;
00749 default:
00750 ev->ignore();
00751 break;
00752 }
00753 if (action)
00754 triggerAction(action);
00755 }
00756
00760 void QAbstractSlider::changeEvent(QEvent *ev)
00761 {
00762 Q_D(QAbstractSlider);
00763 switch (ev->type()) {
00764 case QEvent::EnabledChange:
00765 if (!isEnabled()) {
00766 d->repeatActionTimer.stop();
00767 setSliderDown(false);
00768 }
00769
00770 default:
00771 QWidget::changeEvent(ev);
00772 }
00773 }
00774
00778 bool QAbstractSlider::event(QEvent *e)
00779 {
00780 return QWidget::event(e);
00781 }
00782