Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/widgets/qabstractslider.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848#include "qaccessible.h"
    4949#endif
     50
     51
     52
    5053#include <limits.h>
    5154
     
    213216QAbstractSliderPrivate::QAbstractSliderPrivate()
    214217    : minimum(0), maximum(99), singleStep(1), pageStep(10),
    215       value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false),
     218      value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
     219      blocktracking(false), pressed(false),
    216220      invertedAppearance(false), invertedControls(false),
    217221      orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
     222
     223
     224
     225
    218226{
    219227}
     
    367375    abstract sliders provides and typically corresponds to the user
    368376    pressing an arrow key.
     377
     378
     379
    369380
    370381    \sa pageStep
     
    595606    switch (action) {
    596607    case SliderSingleStepAdd:
    597         setSliderPosition(d->overflowSafeAdd(d->singleStep));
     608        setSliderPosition(d->overflowSafeAdd(d->));
    598609        break;
    599610    case SliderSingleStepSub:
    600         setSliderPosition(d->overflowSafeAdd(-d->singleStep));
     611        setSliderPosition(d->overflowSafeAdd(-d->));
    601612        break;
    602613    case SliderPageStepAdd:
     
    687698    Q_D(QAbstractSlider);
    688699    e->ignore();
    689     if (e->orientation() != d->orientation && !rect().contains(e->pos()))
    690         return;
    691 
    692     static qreal offset = 0;
    693     static QAbstractSlider *offset_owner = 0;
    694     if (offset_owner != this){
    695         offset_owner = this;
    696         offset = 0;
    697     }
    698 
    699     // On Mac/Cocoa, always scroll one step. The mouse wheel acceleration
    700     // is higher than on other systems, so this works well in practice.
    701 #ifdef QT_MAC_USE_COCOA
    702     int step = 1;
    703 #else
    704     int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep);
     700
     701    int stepsToScroll = 0;
     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();
     735}
    705736#endif
    706     if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
    707         step = d->pageStep;
    708     int currentOffset = qRound(qreal(e->delta()) * step / 120);
    709     if (currentOffset == 0)
    710         currentOffset = (e->delta() < 0 ? -1 : 1);
    711     offset += currentOffset;
    712 
    713     if (d->invertedControls)
    714         offset = -offset;
    715 
    716     int prevValue = d->value;
    717     d->position = d->overflowSafeAdd(int(offset)); // value will be updated by triggerAction()
    718 
    719     triggerAction(SliderMove);
    720     if (prevValue == d->value) {
    721         offset = 0;
    722     } else {
    723         offset -= int(offset);
    724         e->accept();
    725     }
    726 }
     737#ifdef QT_KEYPAD_NAVIGATION
     738/*!
     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*/
     749inline 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*/
     768inline 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/*!
     777    \reimp
     778*/
     779void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
     780{
     781    Q_D(QAbstractSlider);
     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
    727813#endif
    728 /*!
    729     \reimp
    730 */
    731 void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
    732 {
    733     Q_D(QAbstractSlider);
    734     SliderAction action = SliderNoAction;
     814
    735815    switch (ev->key()) {
    736816#ifdef QT_KEYPAD_NAVIGATION
     
    753833        case Qt::Key_Left:
    754834#ifdef QT_KEYPAD_NAVIGATION
    755             if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
     835            // In QApplication::KeypadNavigationDirectional, we want to change the slider
     836            // value if there is no left/right navigation possible and if this slider is not
     837            // inside a tab widget.
     838            if (QApplication::keypadNavigationEnabled()
     839                    && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     840                    || d->orientation == Qt::Vertical
     841                    || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
    756842                ev->ignore();
    757843                return;
     
    768854        case Qt::Key_Right:
    769855#ifdef QT_KEYPAD_NAVIGATION
    770             if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
     856            // Same logic as in Qt::Key_Left
     857            if (QApplication::keypadNavigationEnabled()
     858                    && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     859                    || d->orientation == Qt::Vertical
     860                    || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
    771861                ev->ignore();
    772862                return;
     
    783873        case Qt::Key_Up:
    784874#ifdef QT_KEYPAD_NAVIGATION
    785             if (QApplication::keypadNavigationEnabled()) {
     875            // In QApplication::KeypadNavigationDirectional, we want to change the slider
     876            // value if there is no up/down navigation possible.
     877            if (QApplication::keypadNavigationEnabled()
     878                    && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     879                    || d->orientation == Qt::Horizontal
     880                    || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
    786881                ev->ignore();
    787882                break;
     
    792887        case Qt::Key_Down:
    793888#ifdef QT_KEYPAD_NAVIGATION
    794             if (QApplication::keypadNavigationEnabled()) {
     889            // Same logic as in Qt::Key_Up
     890            if (QApplication::keypadNavigationEnabled()
     891                    && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
     892                    || d->orientation == Qt::Horizontal
     893                    || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
    795894                ev->ignore();
    796895                break;
Note: See TracChangeset for help on using the changeset viewer.