From e855b199319c932f2e9500235775f961bc32e41a Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 2 Feb 2010 16:12:34 +0100 Subject: Fixes scrolling horizontally with a mouse wheel over sliders. When scrolling horizontally over sliders the slider should go to the right, which means the value of the slider should increase. However in Qt scrolling with a mouse wheel horizontally means the delta value is negative, which is wrong. So changed the delta to be inversed. Reviewed-by: Richard Moe Gustavsen --- src/gui/widgets/qabstractslider.cpp | 67 ++++++++++++++++++++++--------------- src/gui/widgets/qabstractslider_p.h | 1 + src/gui/widgets/qscrollbar.cpp | 16 +++++++++ 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 2874647..f119a4f 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -688,51 +688,64 @@ void QAbstractSlider::sliderChange(SliderChange) update(); } - -/*! - \reimp -*/ -#ifndef QT_NO_WHEELEVENT -void QAbstractSlider::wheelEvent(QWheelEvent * e) +bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta) { - Q_D(QAbstractSlider); - e->ignore(); - + Q_Q(QAbstractSlider); int stepsToScroll = 0; - qreal offset = qreal(e->delta()) / 120; + // in Qt scrolling to the right gives negative values. + if (orientation == Qt::Horizontal) + delta = -delta; + qreal offset = qreal(delta) / 120; - if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) { + if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) { // Scroll one page regardless of delta: - stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep); - d->offset_accumulated = 0; + stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep); + offset_accumulated = 0; } else { // Calculate how many lines to scroll. Depending on what delta is (and // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can // only scroll whole lines, so we keep the reminder until next event. - qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep(); + qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * effectiveSingleStep(); // Check if wheel changed direction since last event: - if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0) - d->offset_accumulated = 0; + if (offset_accumulated != 0 && (offset / offset_accumulated) < 0) + offset_accumulated = 0; - d->offset_accumulated += stepsToScrollF; - stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep); - d->offset_accumulated -= int(d->offset_accumulated); + offset_accumulated += stepsToScrollF; + stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep); + offset_accumulated -= int(offset_accumulated); if (stepsToScroll == 0) - return; + return false; } - if (d->invertedControls) + if (invertedControls) stepsToScroll = -stepsToScroll; - int prevValue = d->value; - d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() - triggerAction(SliderMove); + int prevValue = value; + position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() + q->triggerAction(QAbstractSlider::SliderMove); - if (prevValue == d->value) - d->offset_accumulated = 0; - else + if (prevValue == value) { + offset_accumulated = 0; + return false; + } + return true; +} + +/*! + \reimp +*/ +#ifndef QT_NO_WHEELEVENT +void QAbstractSlider::wheelEvent(QWheelEvent * e) +{ + Q_D(QAbstractSlider); + e->ignore(); + if (e->orientation() != d->orientation && !rect().contains(e->pos())) + return; + int delta = e->delta(); + if (d->scrollByDelta(e->orientation(), e->modifiers(), delta)) e->accept(); } + #endif #ifdef QT_KEYPAD_NAVIGATION /*! diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h index 6cde468..6e6ff6e 100644 --- a/src/gui/widgets/qabstractslider_p.h +++ b/src/gui/widgets/qabstractslider_p.h @@ -138,6 +138,7 @@ public: } q->triggerAction(repeatAction); } + bool scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta); }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp index 73ce122..3eed3a9 100644 --- a/src/gui/widgets/qscrollbar.cpp +++ b/src/gui/widgets/qscrollbar.cpp @@ -521,6 +521,22 @@ bool QScrollBar::event(QEvent *event) if (const QHoverEvent *he = static_cast(event)) d_func()->updateHoverControl(he->pos()); break; + case QEvent::Wheel: { + // override wheel event without adding virtual function override + QWheelEvent *ev = static_cast(event); + int delta = ev->delta(); + // scrollbar is a special case - in vertical mode it reaches minimum + // value in the upper position, however QSlider's minimum value is on + // the bottom. So we need to invert a value, but since the scrollbar is + // inverted by default, we need to inverse the delta value for the + // horizontal orientation. + if (ev->orientation() == Qt::Horizontal) + delta = -delta; + Q_D(QScrollBar); + if (d->scrollByDelta(ev->orientation(), ev->modifiers(), delta)) + event->accept(); + return true; + } default: break; } -- cgit v0.12