src/gui/widgets/qabstractslider.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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); // re-bound
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) { // was threshold time, use repeat time next time
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); // value will be updated by triggerAction()
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         // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird.
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         // fall through...
00770     default:
00771         QWidget::changeEvent(ev);
00772     }
00773 }
00774 
00778 bool QAbstractSlider::event(QEvent *e)
00779 {
00780     return QWidget::event(e);
00781 }
00782 

Generated on Thu Mar 15 11:56:42 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1