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 { |
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()); |