diff options
author | J-P Nurmi <jpnurmi@digia.com> | 2012-10-30 13:47:20 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-11-02 19:49:22 +0100 |
commit | 3c2bfbff5f4c836de32628710ab7701b0db083f7 (patch) | |
tree | 4e6c262f6cbaa4978bcf47b239423fe305af50bb /src/widgets/widgets | |
parent | 020196d16b6c25e16bf80483f08e0007a27eab13 (diff) |
Mac: refactor scrollbar animations
Get rid of QWidget-centric QMacStyle::eventFilter() and implement the
fade out animations for scrollbars using QNumberStyleAnimation-based
QFadeOutAnimation.
Change-Id: I2000fa50d46b153e981ceafc12a53932a196382e
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Diffstat (limited to 'src/widgets/widgets')
-rw-r--r-- | src/widgets/widgets/qabstractscrollarea.cpp | 41 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractscrollarea.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractscrollarea_p.h | 3 | ||||
-rw-r--r-- | src/widgets/widgets/qscrollarea.cpp | 2 | ||||
-rw-r--r-- | src/widgets/widgets/qscrollbar.cpp | 56 | ||||
-rw-r--r-- | src/widgets/widgets/qscrollbar.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qscrollbar_p.h | 89 | ||||
-rw-r--r-- | src/widgets/widgets/widgets.pri | 1 |
8 files changed, 170 insertions, 24 deletions
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 8aa5534366..3c21d767be 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -57,6 +57,7 @@ #include <QDebug> #include "qabstractscrollarea_p.h" +#include "qscrollbar_p.h" #include <qwidget.h> #include <private/qapplication_p.h> @@ -183,6 +184,7 @@ QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt: layout->setMargin(0); layout->setSpacing(0); layout->addWidget(scrollBar); + layout->setSizeConstraint(QLayout::SetMaximumSize); } /*! \internal @@ -266,6 +268,8 @@ void QAbstractScrollAreaPrivate::replaceScrollBar(QScrollBar *scrollBar, scrollBar->setSliderPosition(oldBar->sliderPosition()); scrollBar->setTracking(oldBar->hasTracking()); scrollBar->setValue(oldBar->value()); + scrollBar->installEventFilter(q); + oldBar->removeEventFilter(q); delete oldBar; QObject::connect(scrollBar, SIGNAL(valueChanged(int)), @@ -286,6 +290,7 @@ void QAbstractScrollAreaPrivate::init() hbar = scrollBarContainers[Qt::Horizontal]->scrollBar; hbar->setRange(0,0); scrollBarContainers[Qt::Horizontal]->setVisible(false); + hbar->installEventFilter(q); QObject::connect(hbar, SIGNAL(valueChanged(int)), q, SLOT(_q_hslide(int))); QObject::connect(hbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection); scrollBarContainers[Qt::Vertical] = new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q); @@ -293,6 +298,7 @@ void QAbstractScrollAreaPrivate::init() vbar = scrollBarContainers[Qt::Vertical]->scrollBar; vbar->setRange(0,0); scrollBarContainers[Qt::Vertical]->setVisible(false); + vbar->installEventFilter(q); QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int))); QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection); viewportFilter.reset(new QAbstractScrollAreaFilter(this)); @@ -323,10 +329,10 @@ void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn - || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); + || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())); bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn - || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); + || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())); QStyleOption opt(0); opt.init(q); @@ -648,6 +654,7 @@ void QAbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy) d->layoutChildren(); if (oldPolicy != d->vbarpolicy) d->scrollBarPolicyChanged(Qt::Vertical, d->vbarpolicy); + d->setScrollBarTransient(d->vbar, policy == Qt::ScrollBarAsNeeded); } @@ -709,6 +716,7 @@ void QAbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy polic d->layoutChildren(); if (oldPolicy != d->hbarpolicy) d->scrollBarPolicyChanged(Qt::Horizontal, d->hbarpolicy); + d->setScrollBarTransient(d->hbar, policy == Qt::ScrollBarAsNeeded); } /*! @@ -921,6 +929,20 @@ void QAbstractScrollArea::setViewportMargins(const QMargins &margins) margins.right(), margins.bottom()); } +/*! \internal */ +bool QAbstractScrollArea::eventFilter(QObject *o, QEvent *e) +{ + Q_D(QAbstractScrollArea); + if ((o == d->hbar || o == d->vbar) && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverLeave)) { + Qt::ScrollBarPolicy policy = o == d->hbar ? d->vbarpolicy : d->hbarpolicy; + if (policy == Qt::ScrollBarAsNeeded) { + QScrollBar *sibling = o == d->hbar ? d->vbar : d->hbar; + d->setScrollBarTransient(sibling, e->type() == QEvent::HoverLeave); + } + } + return QFrame::eventFilter(o, e); +} + /*! \fn bool QAbstractScrollArea::event(QEvent *event) @@ -1421,12 +1443,26 @@ bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos ) return true; } +void QAbstractScrollAreaPrivate::flashScrollBars() +{ + if (hbarpolicy == Qt::ScrollBarAsNeeded) + hbar->d_func()->flash(); + if (vbarpolicy == Qt::ScrollBarAsNeeded) + vbar->d_func()->flash(); +} + +void QAbstractScrollAreaPrivate::setScrollBarTransient(QScrollBar *scrollBar, bool transient) +{ + scrollBar->d_func()->setTransient(transient); +} + void QAbstractScrollAreaPrivate::_q_hslide(int x) { Q_Q(QAbstractScrollArea); int dx = xoffset - x; xoffset = x; q->scrollContentsBy(dx, 0); + flashScrollBars(); } void QAbstractScrollAreaPrivate::_q_vslide(int y) @@ -1435,6 +1471,7 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y) int dy = yoffset - y; yoffset = y; q->scrollContentsBy(0, dy); + flashScrollBars(); } void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars() diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h index 560df9dcae..5ac140241e 100644 --- a/src/widgets/widgets/qabstractscrollarea.h +++ b/src/widgets/widgets/qabstractscrollarea.h @@ -96,6 +96,7 @@ protected: void setViewportMargins(int left, int top, int right, int bottom); void setViewportMargins(const QMargins &margins); + bool eventFilter(QObject *, QEvent *); bool event(QEvent *); virtual bool viewportEvent(QEvent *); diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h index d77d97e03f..7e2ca741b1 100644 --- a/src/widgets/widgets/qabstractscrollarea_p.h +++ b/src/widgets/widgets/qabstractscrollarea_p.h @@ -92,6 +92,9 @@ public: virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} bool canStartScrollingAt( const QPoint &startPos ); + void flashScrollBars(); + void setScrollBarTransient(QScrollBar *scrollBar, bool transient); + void _q_hslide(int); void _q_vslide(int); void _q_showOrHideScrollBars(); diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp index be7ce10c8c..576f77a7b7 100644 --- a/src/widgets/widgets/qscrollarea.cpp +++ b/src/widgets/widgets/qscrollarea.cpp @@ -331,7 +331,7 @@ bool QScrollArea::eventFilter(QObject *o, QEvent *e) if (o == d->widget && e->type() == QEvent::Resize) d->updateScrollBars(); - return false; + return QAbstractScrollArea::eventFilter(o, e); } /*! diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp index aa45b4f54e..199aaf93de 100644 --- a/src/widgets/widgets/qscrollbar.cpp +++ b/src/widgets/widgets/qscrollbar.cpp @@ -55,7 +55,7 @@ #include "qaccessible.h" #endif #include <limits.h> -#include "qabstractslider_p.h" +#include "qscrollbar_p.h" QT_BEGIN_NAMESPACE @@ -201,26 +201,6 @@ QT_BEGIN_NAMESPACE \sa QScrollArea, QSlider, QDial, QSpinBox, {fowler}{GUI Design Handbook: Scroll Bar}, {Sliders Example} */ -class QScrollBarPrivate : public QAbstractSliderPrivate -{ - Q_DECLARE_PUBLIC(QScrollBar) -public: - QStyle::SubControl pressedControl; - bool pointerOutsidePressedControl; - - int clickOffset, snapBackPosition; - - void activateControl(uint control, int threshold = 500); - void stopRepeatAction(); - int pixelPosToRangeValue(int pos) const; - void init(); - bool updateHoverControl(const QPoint &pos); - QStyle::SubControl newHoverControl(const QPoint &pos); - - QStyle::SubControl hoverControl; - QRect hoverRect; -}; - bool QScrollBarPrivate::updateHoverControl(const QPoint &pos) { Q_Q(QScrollBar); @@ -249,6 +229,29 @@ QStyle::SubControl QScrollBarPrivate::newHoverControl(const QPoint &pos) return hoverControl; } +void QScrollBarPrivate::setTransient(bool value) +{ + Q_Q(QScrollBar); + if (transient != value) { + transient = value; + if (transient) { + if (q->isVisible() && q->style()->styleHint(QStyle::SH_ScrollBar_Transient)) + q->update(); + } else if (!q->isVisible()) { + q->show(); + } + } +} + +void QScrollBarPrivate::flash() +{ + Q_Q(QScrollBar); + if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient)) { + flashed = true; + q->show(); + } +} + void QScrollBarPrivate::activateControl(uint control, int threshold) { QAbstractSlider::SliderAction action = QAbstractSlider::SliderNoAction; @@ -322,6 +325,8 @@ void QScrollBar::initStyleOption(QStyleOptionSlider *option) const option->upsideDown = d->invertedAppearance; if (d->orientation == Qt::Horizontal) option->state |= QStyle::State_Horizontal; + if (d->flashed || !d->transient) + option->state |= QStyle::State_On; } @@ -379,6 +384,8 @@ void QScrollBarPrivate::init() invertedControls = true; pressedControl = hoverControl = QStyle::SC_None; pointerOutsidePressedControl = false; + transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient); + flashed = false; q->setFocusPolicy(Qt::NoFocus); QSizePolicy sp(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::Slider); if (orientation == Qt::Vertical) @@ -476,6 +483,9 @@ bool QScrollBar::event(QEvent *event) if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) d_func()->updateHoverControl(he->pos()); break; + case QEvent::StyleChange: + d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient)); + break; default: break; } @@ -521,6 +531,10 @@ void QScrollBar::paintEvent(QPaintEvent *) opt.activeSubControls = (QStyle::SubControl)d->hoverControl; } style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this); + if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient)) { + d->flashed = false; + update(); + } } /*! diff --git a/src/widgets/widgets/qscrollbar.h b/src/widgets/widgets/qscrollbar.h index 48863616ff..3e9ac8a47f 100644 --- a/src/widgets/widgets/qscrollbar.h +++ b/src/widgets/widgets/qscrollbar.h @@ -83,6 +83,7 @@ protected: private: + friend class QAbstractScrollAreaPrivate; friend Q_WIDGETS_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollBar); Q_DISABLE_COPY(QScrollBar) diff --git a/src/widgets/widgets/qscrollbar_p.h b/src/widgets/widgets/qscrollbar_p.h new file mode 100644 index 0000000000..fb4f5b07da --- /dev/null +++ b/src/widgets/widgets/qscrollbar_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCROLLBAR_P_H +#define QSCROLLBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qabstractslider_p.h" +#include "qstyle.h" + +QT_BEGIN_NAMESPACE + +class QScrollBarPrivate : public QAbstractSliderPrivate +{ + Q_DECLARE_PUBLIC(QScrollBar) +public: + QStyle::SubControl pressedControl; + bool pointerOutsidePressedControl; + + int clickOffset, snapBackPosition; + + void activateControl(uint control, int threshold = 500); + void stopRepeatAction(); + int pixelPosToRangeValue(int pos) const; + void init(); + bool updateHoverControl(const QPoint &pos); + QStyle::SubControl newHoverControl(const QPoint &pos); + + QStyle::SubControl hoverControl; + QRect hoverRect; + + bool transient; + void setTransient(bool value); + + bool flashed; + void flash(); +}; + +QT_END_NAMESPACE + +#endif // QSCROLLBAR_P_H diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri index c86bc1eff7..797f3e9b76 100644 --- a/src/widgets/widgets/widgets.pri +++ b/src/widgets/widgets/widgets.pri @@ -46,6 +46,7 @@ HEADERS += \ widgets/qradiobutton.h \ widgets/qrubberband.h \ widgets/qscrollbar.h \ + widgets/qscrollbar_p.h \ widgets/qscrollarea_p.h \ widgets/qsizegrip.h \ widgets/qslider.h \ |