src/gui/widgets/qabstractslider.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
child 18 2f34d5167611
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   217     : minimum(0), maximum(99), singleStep(1), pageStep(10),
   217     : minimum(0), maximum(99), singleStep(1), pageStep(10),
   218       value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
   218       value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
   219       blocktracking(false), pressed(false),
   219       blocktracking(false), pressed(false),
   220       invertedAppearance(false), invertedControls(false),
   220       invertedAppearance(false), invertedControls(false),
   221       orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
   221       orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
       
   222 #ifdef QT_KEYPAD_NAVIGATION
       
   223       , isAutoRepeating(false)
       
   224       , repeatMultiplier(1)
       
   225 #endif
   222 {
   226 {
   223 }
   227 }
   224 
   228 
   225 QAbstractSliderPrivate::~QAbstractSliderPrivate()
   229 QAbstractSliderPrivate::~QAbstractSliderPrivate()
   226 {
   230 {
   368     \brief the single step.
   372     \brief the single step.
   369 
   373 
   370     The smaller of two natural steps that an
   374     The smaller of two natural steps that an
   371     abstract sliders provides and typically corresponds to the user
   375     abstract sliders provides and typically corresponds to the user
   372     pressing an arrow key.
   376     pressing an arrow key.
       
   377 
       
   378     If the property is modified during an auto repeating key event, behavior
       
   379     is undefined.
   373 
   380 
   374     \sa pageStep
   381     \sa pageStep
   375 */
   382 */
   376 
   383 
   377 void QAbstractSlider::setSingleStep(int step)
   384 void QAbstractSlider::setSingleStep(int step)
   596 {
   603 {
   597     Q_D(QAbstractSlider);
   604     Q_D(QAbstractSlider);
   598     d->blocktracking = true;
   605     d->blocktracking = true;
   599     switch (action) {
   606     switch (action) {
   600     case SliderSingleStepAdd:
   607     case SliderSingleStepAdd:
   601         setSliderPosition(d->overflowSafeAdd(d->singleStep));
   608         setSliderPosition(d->overflowSafeAdd(d->effectiveSingleStep()));
   602         break;
   609         break;
   603     case SliderSingleStepSub:
   610     case SliderSingleStepSub:
   604         setSliderPosition(d->overflowSafeAdd(-d->singleStep));
   611         setSliderPosition(d->overflowSafeAdd(-d->effectiveSingleStep()));
   605         break;
   612         break;
   606     case SliderPageStepAdd:
   613     case SliderPageStepAdd:
   607         setSliderPosition(d->overflowSafeAdd(d->pageStep));
   614         setSliderPosition(d->overflowSafeAdd(d->pageStep));
   608         break;
   615         break;
   609     case SliderPageStepSub:
   616     case SliderPageStepSub:
   688 #ifndef QT_NO_WHEELEVENT
   695 #ifndef QT_NO_WHEELEVENT
   689 void QAbstractSlider::wheelEvent(QWheelEvent * e)
   696 void QAbstractSlider::wheelEvent(QWheelEvent * e)
   690 {
   697 {
   691     Q_D(QAbstractSlider);
   698     Q_D(QAbstractSlider);
   692     e->ignore();
   699     e->ignore();
   693     if (e->orientation() != d->orientation && !rect().contains(e->pos()))
   700 
   694         return;
   701     int stepsToScroll = 0;
   695 
   702     qreal offset = qreal(e->delta()) / 120;
   696     qreal currentOffset = qreal(e->delta()) / 120;
   703 
   697     d->offset_accumulated += currentOffset;
       
   698     if (int(d->offset_accumulated) == 0) {
       
   699         // QAbstractSlider works on integer values. So if the accumulated
       
   700         // offset is less than +/- 1, we need to wait until we get more
       
   701         // wheel events (this means that the wheel resolution is higher than 
       
   702         // 15 degrees, e.g. when using mac mighty mouse/trackpad):
       
   703         return;
       
   704     }
       
   705 
       
   706     int stepsToScroll;
       
   707     if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
   704     if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
   708         stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep;
   705         // Scroll one page regardless of delta:
       
   706         stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep);
       
   707         d->offset_accumulated = 0;
   709     } else {
   708     } else {
   710         // Calculate the number of steps to scroll (per 15 degrees of rotate):
   709         // Calculate how many lines to scroll. Depending on what delta is (and 
   711 #ifdef Q_OS_MAC
   710         // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
   712         // On mac, since mouse wheel scrolling is accelerated and
   711         // only scroll whole lines, so we keep the reminder until next event.
   713         // fine tuned by the OS, we skip applying acceleration:
   712         qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep();
   714         stepsToScroll = int(d->offset_accumulated);
   713         // Check if wheel changed direction since last event:
   715 #else
   714         if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0)
   716         stepsToScroll = int(d->offset_accumulated) * QApplication::wheelScrollLines() * d->singleStep;
   715             d->offset_accumulated = 0;
   717 #endif
   716 
   718         stepsToScroll = qBound(-d->pageStep, stepsToScroll, d->pageStep);
   717         d->offset_accumulated += stepsToScrollF;
       
   718         stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep);
       
   719         d->offset_accumulated -= int(d->offset_accumulated);
       
   720         if (stepsToScroll == 0)
       
   721             return;
   719     }
   722     }
   720 
   723 
   721     if (d->invertedControls)
   724     if (d->invertedControls)
   722         stepsToScroll = -stepsToScroll;
   725         stepsToScroll = -stepsToScroll;
   723 
   726 
   724     int prevValue = d->value;
   727     int prevValue = d->value;
   725     d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
   728     d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
   726     triggerAction(SliderMove);
   729     triggerAction(SliderMove);
   727 
   730 
   728     if (prevValue == d->value) {
   731     if (prevValue == d->value)
   729         d->offset_accumulated = 0;
   732         d->offset_accumulated = 0;
   730     } else {
   733     else
   731         d->offset_accumulated -= int(d->offset_accumulated);
       
   732         e->accept();
   734         e->accept();
   733     }
       
   734 }
   735 }
   735 #endif
   736 #endif
   736 #ifdef QT_KEYPAD_NAVIGATION
   737 #ifdef QT_KEYPAD_NAVIGATION
   737 /*!
   738 /*!
   738     \internal
   739     \internal
   777 */
   778 */
   778 void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
   779 void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
   779 {
   780 {
   780     Q_D(QAbstractSlider);
   781     Q_D(QAbstractSlider);
   781     SliderAction action = SliderNoAction;
   782     SliderAction action = SliderNoAction;
       
   783 #ifdef QT_KEYPAD_NAVIGATION
       
   784     if (ev->isAutoRepeat()) {
       
   785         if (d->firstRepeat.isNull())
       
   786             d->firstRepeat = QTime::currentTime();
       
   787         else if (1 == d->repeatMultiplier) {
       
   788             // This is the interval in milli seconds which one key repetition
       
   789             // takes.
       
   790             const int repeatMSecs = d->firstRepeat.msecsTo(QTime::currentTime());
       
   791 
       
   792             /**
       
   793              * The time it takes to currently navigate the whole slider.
       
   794              */
       
   795             const qreal currentTimeElapse = (qreal(maximum()) / singleStep()) * repeatMSecs;
       
   796 
       
   797             /**
       
   798              * This is an arbitrarily determined constant in msecs that
       
   799              * specifies how long time it should take to navigate from the
       
   800              * start to the end(excluding starting key auto repeat).
       
   801              */
       
   802             const int SliderRepeatElapse = 2500;
       
   803 
       
   804             d->repeatMultiplier = currentTimeElapse / SliderRepeatElapse;
       
   805         }
       
   806 
       
   807     }
       
   808     else if (!d->firstRepeat.isNull()) {
       
   809         d->firstRepeat = QTime();
       
   810         d->repeatMultiplier = 1;
       
   811     }
       
   812 
       
   813 #endif
       
   814 
   782     switch (ev->key()) {
   815     switch (ev->key()) {
   783 #ifdef QT_KEYPAD_NAVIGATION
   816 #ifdef QT_KEYPAD_NAVIGATION
   784         case Qt::Key_Select:
   817         case Qt::Key_Select:
   785             if (QApplication::keypadNavigationEnabled())
   818             if (QApplication::keypadNavigationEnabled())
   786                 setEditFocus(!hasEditFocus());
   819                 setEditFocus(!hasEditFocus());