212 \value SliderStepsChange |
209 \value SliderStepsChange |
213 \value SliderValueChange |
210 \value SliderValueChange |
214 */ |
211 */ |
215 |
212 |
216 QAbstractSliderPrivate::QAbstractSliderPrivate() |
213 QAbstractSliderPrivate::QAbstractSliderPrivate() |
217 : minimum(0), maximum(99), singleStep(1), pageStep(10), |
214 : minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1), |
218 value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true), |
215 singleStep(1), offset_accumulated(0), tracking(true), |
219 blocktracking(false), pressed(false), |
216 blocktracking(false), pressed(false), |
220 invertedAppearance(false), invertedControls(false), |
217 invertedAppearance(false), invertedControls(false), |
221 orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction) |
218 orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction) |
222 #ifdef QT_KEYPAD_NAVIGATION |
219 #ifdef QT_KEYPAD_NAVIGATION |
223 , isAutoRepeating(false) |
220 , isAutoRepeating(false) |
686 void QAbstractSlider::sliderChange(SliderChange) |
683 void QAbstractSlider::sliderChange(SliderChange) |
687 { |
684 { |
688 update(); |
685 update(); |
689 } |
686 } |
690 |
687 |
|
688 bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta) |
|
689 { |
|
690 Q_Q(QAbstractSlider); |
|
691 int stepsToScroll = 0; |
|
692 // in Qt scrolling to the right gives negative values. |
|
693 if (orientation == Qt::Horizontal) |
|
694 delta = -delta; |
|
695 qreal offset = qreal(delta) / 120; |
|
696 |
|
697 if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) { |
|
698 // Scroll one page regardless of delta: |
|
699 stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep); |
|
700 offset_accumulated = 0; |
|
701 } else { |
|
702 // Calculate how many lines to scroll. Depending on what delta is (and |
|
703 // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can |
|
704 // only scroll whole lines, so we keep the reminder until next event. |
|
705 qreal stepsToScrollF = |
|
706 #ifndef QT_NO_WHEELEVENT |
|
707 QApplication::wheelScrollLines() * |
|
708 #endif |
|
709 offset * effectiveSingleStep(); |
|
710 // Check if wheel changed direction since last event: |
|
711 if (offset_accumulated != 0 && (offset / offset_accumulated) < 0) |
|
712 offset_accumulated = 0; |
|
713 |
|
714 offset_accumulated += stepsToScrollF; |
|
715 stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep); |
|
716 offset_accumulated -= int(offset_accumulated); |
|
717 if (stepsToScroll == 0) |
|
718 return false; |
|
719 } |
|
720 |
|
721 if (invertedControls) |
|
722 stepsToScroll = -stepsToScroll; |
|
723 |
|
724 int prevValue = value; |
|
725 position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() |
|
726 q->triggerAction(QAbstractSlider::SliderMove); |
|
727 |
|
728 if (prevValue == value) { |
|
729 offset_accumulated = 0; |
|
730 return false; |
|
731 } |
|
732 return true; |
|
733 } |
691 |
734 |
692 /*! |
735 /*! |
693 \reimp |
736 \reimp |
694 */ |
737 */ |
695 #ifndef QT_NO_WHEELEVENT |
738 #ifndef QT_NO_WHEELEVENT |
696 void QAbstractSlider::wheelEvent(QWheelEvent * e) |
739 void QAbstractSlider::wheelEvent(QWheelEvent * e) |
697 { |
740 { |
698 Q_D(QAbstractSlider); |
741 Q_D(QAbstractSlider); |
699 e->ignore(); |
742 e->ignore(); |
700 |
743 int delta = e->delta(); |
701 int stepsToScroll = 0; |
744 if (d->scrollByDelta(e->orientation(), e->modifiers(), delta)) |
702 qreal offset = qreal(e->delta()) / 120; |
|
703 |
|
704 if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) { |
|
705 // Scroll one page regardless of delta: |
|
706 stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep); |
|
707 d->offset_accumulated = 0; |
|
708 } else { |
|
709 // Calculate how many lines to scroll. Depending on what delta is (and |
|
710 // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can |
|
711 // only scroll whole lines, so we keep the reminder until next event. |
|
712 qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep(); |
|
713 // Check if wheel changed direction since last event: |
|
714 if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0) |
|
715 d->offset_accumulated = 0; |
|
716 |
|
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; |
|
722 } |
|
723 |
|
724 if (d->invertedControls) |
|
725 stepsToScroll = -stepsToScroll; |
|
726 |
|
727 int prevValue = d->value; |
|
728 d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() |
|
729 triggerAction(SliderMove); |
|
730 |
|
731 if (prevValue == d->value) |
|
732 d->offset_accumulated = 0; |
|
733 else |
|
734 e->accept(); |
745 e->accept(); |
735 } |
746 } |
736 #endif |
747 |
737 #ifdef QT_KEYPAD_NAVIGATION |
748 #endif |
738 /*! |
749 |
739 \internal |
|
740 |
|
741 Tells us if it there is currently a reachable widget by keypad navigation in |
|
742 a certain \a orientation. |
|
743 If no navigation is possible, occuring key events in that \a orientation may |
|
744 be used to interact with the value in the focussed widget, even though it |
|
745 currently has not the editFocus. |
|
746 |
|
747 \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus() |
|
748 */ |
|
749 inline static bool canKeypadNavigate(Qt::Orientation orientation) |
|
750 { |
|
751 return orientation == Qt::Horizontal? |
|
752 (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast) |
|
753 || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest)) |
|
754 :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth) |
|
755 || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth)); |
|
756 } |
|
757 /*! |
|
758 \internal |
|
759 |
|
760 Checks, if the \a widget is inside a QTabWidget. If is is inside |
|
761 one, left/right key events will be used to switch between tabs in keypad |
|
762 navigation. If there is no QTabWidget, the horizontal key events can be used to |
|
763 interact with the value in the focussed widget, even though it currently has |
|
764 not the editFocus. |
|
765 |
|
766 \sa QWidget::hasEditFocus() |
|
767 */ |
|
768 inline static bool inTabWidget(QWidget *widget) |
|
769 { |
|
770 for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget()) |
|
771 if (qobject_cast<const QTabWidget*>(tabWidget)) |
|
772 return true; |
|
773 return false; |
|
774 } |
|
775 #endif // QT_KEYPAD_NAVIGATION |
|
776 /*! |
750 /*! |
777 \reimp |
751 \reimp |
778 */ |
752 */ |
779 void QAbstractSlider::keyPressEvent(QKeyEvent *ev) |
753 void QAbstractSlider::keyPressEvent(QKeyEvent *ev) |
780 { |
754 { |