From 7501d55ae005cf9a155a6bcbeac468bfde40177d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 5 Oct 2012 10:42:10 +0200 Subject: Introduce (private) QStyleAnimation QStyleAnimation handles style animations in a generic fashion by sending StyleAnimationUpdate events back to the animation target instead of calling QWidget::update() directly. This decouples style animations from widgets and makes it possible to run style animations for QQuickItems (ie. the desktop components). The next step is to add "QObject* QStyleOption::target" and use that everywhere instead of the widget pointer passed to various QStyle methods. Change-Id: Ib963c54872805fc3f0123ff922f82c9962a68b90 Reviewed-by: J-P Nurmi Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qcleanlooksstyle.cpp | 9 +- src/widgets/styles/qcleanlooksstyle_p.h | 1 - src/widgets/styles/qcommonstyle.cpp | 54 +++++++++++ src/widgets/styles/qcommonstyle.h | 1 + src/widgets/styles/qcommonstyle_p.h | 25 ++++- src/widgets/styles/qgtkstyle.cpp | 9 +- src/widgets/styles/qmacstyle_mac.mm | 134 +++++-------------------- src/widgets/styles/qmacstyle_mac_p.h | 8 -- src/widgets/styles/qplastiquestyle.cpp | 71 ++++---------- src/widgets/styles/qplastiquestyle.h | 1 - src/widgets/styles/qstyleanimation.cpp | 148 ++++++++++++++++++++++++++++ src/widgets/styles/qstyleanimation_p.h | 110 +++++++++++++++++++++ src/widgets/styles/qstylesheetstyle.cpp | 7 +- src/widgets/styles/qwindowsstyle.cpp | 58 ++++------- src/widgets/styles/qwindowsstyle.h | 1 - src/widgets/styles/qwindowsstyle_p.h | 10 +- src/widgets/styles/qwindowsvistastyle.cpp | 156 ++++++++---------------------- src/widgets/styles/qwindowsvistastyle.h | 1 - src/widgets/styles/qwindowsvistastyle_p.h | 45 +++------ src/widgets/styles/styles.pri | 3 + 20 files changed, 475 insertions(+), 377 deletions(-) create mode 100644 src/widgets/styles/qstyleanimation.cpp create mode 100644 src/widgets/styles/qstyleanimation_p.h (limited to 'src') diff --git a/src/widgets/styles/qcleanlooksstyle.cpp b/src/widgets/styles/qcleanlooksstyle.cpp index 99e4b179f4..896f2ead32 100644 --- a/src/widgets/styles/qcleanlooksstyle.cpp +++ b/src/widgets/styles/qcleanlooksstyle.cpp @@ -67,6 +67,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -1759,9 +1760,11 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o } else { Q_D(const QCleanlooksStyle); int slideWidth = ((rect.width() - 4) * 2) / 3; - int step = ((d->animateStep * slideWidth) / d->animationFps) % slideWidth; - if ((((d->animateStep * slideWidth) / d->animationFps) % (2 * slideWidth)) >= slideWidth) - step = slideWidth - step; + int step = 0; +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(widget))) + step = animation->progressStep(slideWidth); +#endif progressBar.setRect(rect.left() + 1 + step, rect.top() + 1, slideWidth / 2, rect.height() - 3); } diff --git a/src/widgets/styles/qcleanlooksstyle_p.h b/src/widgets/styles/qcleanlooksstyle_p.h index ccf0d5e1c2..5a6bef5fe7 100644 --- a/src/widgets/styles/qcleanlooksstyle_p.h +++ b/src/widgets/styles/qcleanlooksstyle_p.h @@ -66,7 +66,6 @@ class QCleanlooksStylePrivate : public QWindowsStylePrivate public: QCleanlooksStylePrivate() : QWindowsStylePrivate() { - animationFps = 24; } ~QCleanlooksStylePrivate() { diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 5c34caef6b..50fceab694 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -75,6 +75,7 @@ #include #include #include +#include #include @@ -1048,6 +1049,57 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget } #endif //QT_NO_TABBAR +/*! \internal */ +QList QCommonStylePrivate::animationTargets() const +{ + return animations.keys(); +} + +/*! \internal */ +QStyleAnimation * QCommonStylePrivate::animation(const QObject *target) const +{ + return animations.value(target); +} + +/*! \internal */ +void QCommonStylePrivate::startAnimation(QStyleAnimation *animation) +{ +#ifndef QT_NO_ANIMATION + Q_Q(QCommonStyle); + stopAnimation(animation->target()); + q->connect(animation, SIGNAL(finished()), SLOT(_q_removeAnimation()), Qt::UniqueConnection); + q->connect(animation, SIGNAL(destroyed()), SLOT(_q_removeAnimation()), Qt::UniqueConnection); + animations.insert(animation->target(), animation); + animation->start(); +#endif // QT_NO_ANIMATION +} + +/*! \internal */ +void QCommonStylePrivate::stopAnimation(const QObject *target) +{ +#ifndef QT_NO_ANIMATION + QStyleAnimation *animation = animations.value(target); + if (animation) { + if (animation->state() == QAbstractAnimation::Stopped) + animations.take(target)->deleteLater(); + else + animation->stop(); + } +#endif // QT_NO_ANIMATION +} + +/*! \internal */ +void QCommonStylePrivate::_q_removeAnimation() +{ +#ifndef QT_NO_ANIMATION + Q_Q(QCommonStyle); + QObject *animation = q->sender(); + if (animation) { + animations.remove(animation->parent()); + animation->deleteLater(); + } +#endif // QT_NO_ANIMATION +} /*! \reimp @@ -5903,3 +5955,5 @@ void QCommonStyle::unpolish(QApplication *application) QT_END_NAMESPACE + +#include "moc_qcommonstyle.cpp" diff --git a/src/widgets/styles/qcommonstyle.h b/src/widgets/styles/qcommonstyle.h index ba0837a5d5..878213702c 100644 --- a/src/widgets/styles/qcommonstyle.h +++ b/src/widgets/styles/qcommonstyle.h @@ -100,6 +100,7 @@ protected: private: Q_DECLARE_PRIVATE(QCommonStyle) Q_DISABLE_COPY(QCommonStyle) + Q_PRIVATE_SLOT(d_func(), void _q_removeAnimation()) }; QT_END_NAMESPACE diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h index 496723f8dd..2032e06e31 100644 --- a/src/widgets/styles/qcommonstyle_p.h +++ b/src/widgets/styles/qcommonstyle_p.h @@ -44,6 +44,7 @@ #include "qcommonstyle.h" #include "qstyle_p.h" +#include "qstyleanimation_p.h" #include "qstyleoption.h" @@ -67,17 +68,24 @@ class QCommonStylePrivate : public QStylePrivate { Q_DECLARE_PUBLIC(QCommonStyle) public: - inline QCommonStylePrivate() + inline QCommonStylePrivate() : #ifndef QT_NO_ITEMVIEWS - : cachedOption(0) + cachedOption(0), #endif + animationFps(30) { } -#ifndef QT_NO_ITEMVIEWS ~QCommonStylePrivate() { +#ifndef QT_NO_ANIMATION + qDeleteAll(animations); +#endif +#ifndef QT_NO_ITEMVIEWS delete cachedOption; +#endif } + +#ifndef QT_NO_ITEMVIEWS void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const; void viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect, QRect *pixmapRect, QRect *textRect, bool sizehint) const; @@ -106,6 +114,17 @@ public: #ifndef QT_NO_TABBAR void tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const; #endif + + int animationFps; + void _q_removeAnimation(); + + QList animationTargets() const; + QStyleAnimation* animation(const QObject *target) const; + void startAnimation(QStyleAnimation *animation); + void stopAnimation(const QObject *target); + +private: + QHash animations; }; QT_END_NAMESPACE diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp index 9bcf45e928..83e70d022b 100644 --- a/src/widgets/styles/qgtkstyle.cpp +++ b/src/widgets/styles/qgtkstyle.cpp @@ -71,6 +71,7 @@ #include #include +#include #undef signals // Collides with GTK stymbols #include #include @@ -3491,9 +3492,11 @@ void QGtkStyle::drawControl(ControlElement element, } else { Q_D(const QGtkStyle); int slideWidth = ((rect.width() - 4) * 2) / 3; - int step = ((d->animateStep * slideWidth) / d->animationFps) % slideWidth; - if ((((d->animateStep * slideWidth) / d->animationFps) % (2 * slideWidth)) >= slideWidth) - step = slideWidth - step; + int step = 0; +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(widget))) + step = animation->progressStep(slideWidth); +#endif progressBar.setRect(rect.left() + step, rect.top(), slideWidth / 2, rect.height()); } diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index ecb3e7f222..77656f9ed5 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -101,6 +101,7 @@ #include #include #include +#include #include QT_USE_NAMESPACE @@ -125,9 +126,9 @@ QMacStylePrivate *mPrivate; { Q_UNUSED(notification); QEvent event(QEvent::StyleChange); - Q_FOREACH (QPointer sb, mPrivate->scrollBars) { - if (sb) - QCoreApplication::sendEvent(sb, &event); + Q_FOREACH (const QObject* target, mPrivate->animationTargets()) { + if (target) + QCoreApplication::sendEvent(const_cast(target), &event); } } @end @@ -1668,7 +1669,7 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti } QMacStylePrivate::QMacStylePrivate() - : timerID(-1), progressFrame(0), mouseDown(false) + : mouseDown(false) { defaultButtonStart = CFAbsoluteTimeGetCurrent(); memset(&buttonState, 0, sizeof(ButtonState)); @@ -1696,54 +1697,42 @@ bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QWidget * } return true; } - } else if (as == AquaProgressBar) { - if (progressBars.contains((const_cast(w)))) - return true; - } else if (as == AquaScrollBar) { - if (scrollBars.contains((const_cast(w)))) - return true; } - return false; + return animation(w); } void QMacStylePrivate::stopAnimate(QMacStylePrivate::Animates as, QWidget *w) { + stopAnimation(w); if (as == AquaPushButton && defaultButton) { + stopAnimation(defaultButton); QPushButton *tmp = defaultButton; defaultButton = 0; tmp->update(); - } else if (as == AquaProgressBar) { - progressBars.removeAll(w); } else if (as == AquaScrollBar) { - scrollBars.removeAll(w); scrollBarInfos.remove(w); } } void QMacStylePrivate::startAnimate(QMacStylePrivate::Animates as, QWidget *w) { +#ifndef QT_NO_ANIMATION + if (!animation(w)) + { + if (as == AquaProgressBar) + startAnimation(new QProgressStyleAnimation(animateSpeed(as), w)); + else + startAnimation(new QStyleAnimation(w)); + } +#endif if (as == AquaPushButton) defaultButton = static_cast(w); - else if (as == AquaProgressBar) - progressBars.append(w); - else if (as == AquaScrollBar) - scrollBars.append(w); - startAnimationTimer(); -} - -void QMacStylePrivate::startAnimationTimer() -{ - Q_Q(QMacStyle); - if ((defaultButton || !progressBars.isEmpty() || !scrollBars.isEmpty()) && timerID <= -1) - timerID = q->startTimer(animateSpeed(AquaListViewItemOpen)); } bool QMacStylePrivate::addWidget(QWidget *w) { //already knew of it - if (static_cast(w) == defaultButton - || progressBars.contains(static_cast(w)) - || scrollBars.contains(static_cast(w))) + if (w == defaultButton || animation(w)) return false; Q_Q(QMacStyle); @@ -1802,68 +1791,6 @@ ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags) return tds; } -void QMacStylePrivate::animate() -{ - Q_Q(QMacStyle); - int animated = 0; - if (defaultButton && defaultButton->isEnabled() && defaultButton->window()->isActiveWindow() - && defaultButton->isVisibleTo(0) && (defaultButton->isDefault() - || (defaultButton->autoDefault() && defaultButton->hasFocus())) - && doAnimate(AquaPushButton)) { - ++animated; - defaultButton->update(); - } - if (!progressBars.isEmpty()) { - int i = 0; - while (i < progressBars.size()) { - QWidget *maybeProgress = progressBars.at(i); - if (!maybeProgress) { - progressBars.removeAt(i); - } else { - if (QProgressBar *pb = qobject_cast(maybeProgress)) { - if (pb->maximum() == 0 || (pb->value() > 0 && pb->value() < pb->maximum())) { - if (doAnimate(AquaProgressBar)) - pb->update(); - } - } - ++i; - } - } - if (i > 0) { - ++progressFrame; - animated += i; - } - } - if (!scrollBars.isEmpty()) { - int i = 0; - const qint64 dt = QDateTime::currentMSecsSinceEpoch(); - while (i < scrollBars.size()) { - QWidget *maybeScroll = scrollBars.at(i); - if (!maybeScroll) { - scrollBars.removeAt(i); - } else { - if (QScrollBar *sb = qobject_cast(maybeScroll)) { - const OverlayScrollBarInfo& info = scrollBarInfos[sb]; - const qreal elapsed = qMax(dt - info.lastHovered, - dt - info.lastUpdate); - const CGFloat opacity = 1.0 - qMax(0.0, (elapsed - ScrollBarFadeOutDelay) / - ScrollBarFadeOutDuration); - if ((opacity > 0.0 || !info.cleared) && (elapsed > ScrollBarFadeOutDelay)) { - if (doAnimate(AquaScrollBar)) - sb->update(); - } - } - ++i; - ++animated; - } - } - } - if (animated <= 0) { - q->killTimer(timerID); - timerID = -1; - } -} - /*! \reimp */ bool QMacStyle::eventFilter(QObject *o, QEvent *e) { @@ -1874,12 +1801,11 @@ bool QMacStyle::eventFilter(QObject *o, QEvent *e) default: break; case QEvent::Show: - if (!d->progressBars.contains(pb)) - d->startAnimate(QMacStylePrivate::AquaProgressBar, pb); + d->startAnimate(QMacStylePrivate::AquaProgressBar, pb); break; case QEvent::Destroy: case QEvent::Hide: - d->progressBars.removeAll(pb); + d->stopAnimate(QMacStylePrivate::AquaProgressBar, pb); } #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 } else if (QScrollBar *sb = qobject_cast(o)) { @@ -1986,17 +1912,6 @@ bool QMacStyle::eventFilter(QObject *o, QEvent *e) return false; } -bool QMacStylePrivate::doAnimate(QMacStylePrivate::Animates as) -{ - if (as == AquaPushButton) { - } else if (as == AquaProgressBar) { - // something for later... - } else if (as == AquaListViewItemOpen) { - // To be revived later... - } - return true; -} - void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi, QPainter *p, const QStyleOption *opt) const { @@ -3754,7 +3669,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter bdi.adornment |= kThemeAdornmentDefault; bdi.animation.time.start = d->defaultButtonStart; bdi.animation.time.current = CFAbsoluteTimeGetCurrent(); - const_cast(d)->startAnimationTimer(); } // Unlike Carbon, we want the button to always be drawn inside its bounds. // Therefore, make the button a bit smaller, so that even if it got focus, @@ -4462,7 +4376,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter tdi.min = pb->minimum; tdi.value = pb->progress; tdi.attributes = vertical ? 0 : kThemeTrackHorizontal; - tdi.trackInfo.progress.phase = d->progressFrame; +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(w))) + tdi.trackInfo.progress.phase = animation->animationStep(); +#endif if (!(pb->state & State_Active)) tdi.enableState = kThemeTrackInactive; else if (!(pb->state & State_Enabled)) @@ -6514,9 +6431,6 @@ bool QMacStyle::event(QEvent *e) } else if(e->type() == QEvent::FocusOut) { if(d->focusWidget) d->focusWidget->setWidget(0); - } else if (e->type() == QEvent::Timer) { - if (static_cast(e)->timerId() == d->timerID) - d->animate(); } return false; } diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h index ac482b8fc7..63cc005033 100644 --- a/src/widgets/styles/qmacstyle_mac_p.h +++ b/src/widgets/styles/qmacstyle_mac_p.h @@ -172,8 +172,6 @@ public: QSize szHint=QSize(-1, -1), QSize *insz = 0) const; void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider, HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe) const; - void animate(); - bool doAnimate(Animates); inline int animateSpeed(Animates) const { return 33; } // Utility functions @@ -202,13 +200,8 @@ public: HIThemeButtonDrawInfo *bdi) const; QPixmap generateBackgroundPattern() const; - void startAnimationTimer(); - public: QPointer defaultButton; //default push buttons - int timerID; - QList > progressBars; //existing progress bars that need animation - QList > scrollBars; //existing scroll bars that need animation struct OverlayScrollBarInfo { OverlayScrollBarInfo() @@ -235,7 +228,6 @@ public: int frame; enum { ButtonDark, ButtonLight } dir; } buttonState; - UInt8 progressFrame; mutable QPointer focusWidget; CFAbsoluteTime defaultButtonStart; bool mouseDown; diff --git a/src/widgets/styles/qplastiquestyle.cpp b/src/widgets/styles/qplastiquestyle.cpp index d22f82ff85..fe1e5c3dc3 100644 --- a/src/widgets/styles/qplastiquestyle.cpp +++ b/src/widgets/styles/qplastiquestyle.cpp @@ -79,7 +79,6 @@ static const int blueFrameWidth = 2; // with of line edit focus frame #include #include #include -#include #include #include #include @@ -89,6 +88,7 @@ static const int blueFrameWidth = 2; // with of line edit focus frame #include #include #include +#include QT_BEGIN_NAMESPACE @@ -987,12 +987,6 @@ public: virtual ~QPlastiqueStylePrivate(); void drawPartialFrame(QPainter *painter, const QStyleOptionComplex *option, const QRect &rect, const QWidget *widget) const; - -#ifndef QT_NO_PROGRESSBAR - QList bars; - int progressBarAnimateTimer; - QElapsedTimer timer; -#endif }; /*! @@ -1000,9 +994,6 @@ public: */ QPlastiqueStylePrivate::QPlastiqueStylePrivate() : QWindowsStylePrivate() -#ifndef QT_NO_PROGRESSBAR - , progressBarAnimateTimer(0) -#endif { } @@ -2577,9 +2568,11 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op } } else { int slideWidth = ((rect.width() - 4) * 2) / 3; - int step = ((d->animateStep * slideWidth) / ProgressBarFps) % slideWidth; - if ((((d->animateStep * slideWidth) / ProgressBarFps) % (2 * slideWidth)) >= slideWidth) - step = slideWidth - step; + int step = 0; +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(widget))) + step = animation->progressStep(slideWidth); +#endif progressBar.setRect(rect.left() + 2 + step, rect.top() + 2, slideWidth / 2, rect.height() - 4); } @@ -2732,7 +2725,13 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op if (!vertical) progressBar.adjust(0, 1, 0, 1); if (!indeterminate) { - int step = (AnimateProgressBar || (indeterminate && AnimateBusyProgressBar)) ? (d->animateStep % 20) : 0; + int step = 0; + if (AnimateProgressBar || (indeterminate && AnimateBusyProgressBar)) { +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(widget))) + step = animation->animationStep() % 20; +#endif + } if (reverse) painter->drawPixmap(progressBar.left() - 25 + step, progressBar.top(), cache); else @@ -5706,11 +5705,8 @@ void QPlastiqueStyle::unpolish(QWidget *widget) } #ifndef QT_NO_PROGRESSBAR - if (AnimateBusyProgressBar && qobject_cast(widget)) { - Q_D(QPlastiqueStyle); + if (AnimateBusyProgressBar && qobject_cast(widget)) widget->removeEventFilter(this); - d->bars.removeAll(static_cast(widget)); - } #endif #if defined QPlastique_MaskButtons @@ -5834,24 +5830,13 @@ bool QPlastiqueStyle::eventFilter(QObject *watched, QEvent *event) switch (event->type()) { case QEvent::Show: - if (QProgressBar *bar = qobject_cast(watched)) { - d->bars.append(bar); - if (d->bars.size() == 1) { - Q_ASSERT(ProgressBarFps > 0); - d->timer.start(); - d->progressBarAnimateTimer = startTimer(1000 / ProgressBarFps); - } - } + if (QProgressBar *bar = qobject_cast(watched)) + d->startProgressAnimation(this, bar); break; case QEvent::Destroy: case QEvent::Hide: - if(!d->bars.isEmpty()) { - d->bars.removeAll(reinterpret_cast(watched)); - if (d->bars.isEmpty()) { - killTimer(d->progressBarAnimateTimer); - d->progressBarAnimateTimer = 0; - } - } + if (QProgressBar *bar = qobject_cast(watched)) + d->stopProgressAnimation(this, bar); break; #if defined QPlastique_MaskButtons case QEvent::Resize: @@ -5879,26 +5864,6 @@ bool QPlastiqueStyle::eventFilter(QObject *watched, QEvent *event) return QWindowsStyle::eventFilter(watched, event); } -/*! - \reimp -*/ -void QPlastiqueStyle::timerEvent(QTimerEvent *event) -{ -#ifndef QT_NO_PROGRESSBAR - Q_D(QPlastiqueStyle); - - if (event->timerId() == d->progressBarAnimateTimer) { - Q_ASSERT(ProgressBarFps > 0); - d->animateStep = d->timer.elapsed() / (1000 / ProgressBarFps); - foreach (QProgressBar *bar, d->bars) { - if (AnimateProgressBar || (bar->minimum() == 0 && bar->maximum() == 0)) - bar->update(); - } - } -#endif // QT_NO_PROGRESSBAR - event->ignore(); -} - QT_END_NAMESPACE #endif // !defined(QT_NO_STYLE_PLASTIQUE) || defined(QT_PLUGIN) diff --git a/src/widgets/styles/qplastiquestyle.h b/src/widgets/styles/qplastiquestyle.h index 05679a85c3..bda686e215 100644 --- a/src/widgets/styles/qplastiquestyle.h +++ b/src/widgets/styles/qplastiquestyle.h @@ -101,7 +101,6 @@ public: protected: bool eventFilter(QObject *watched, QEvent *event); - void timerEvent(QTimerEvent *event); private: Q_DISABLE_COPY(QPlastiqueStyle) diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp new file mode 100644 index 0000000000..8bc8e9d241 --- /dev/null +++ b/src/widgets/styles/qstyleanimation.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qstyleanimation_p.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ANIMATION + +QStyleAnimation::QStyleAnimation(QObject *target) : QAbstractAnimation(target), + _startTime(QTime::currentTime()) +{ +} + +QStyleAnimation::~QStyleAnimation() +{ +} + +int QStyleAnimation::duration() const +{ + return -1; +} + +QObject *QStyleAnimation::target() const +{ + return parent(); +} + +QTime QStyleAnimation::startTime() const +{ + return _startTime; +} + +void QStyleAnimation::setStartTime(const QTime &time) +{ + _startTime = time; +} + +bool QStyleAnimation::isUpdateNeeded() const +{ + return true; +} + +void QStyleAnimation::updateCurrentTime(int) +{ + if (target()->isWidgetType()) { + QWidget *widget = static_cast(target()); + if (!widget->isVisible() || widget->window()->isMinimized()) + stop(); + } + + if (isUpdateNeeded()) { + QEvent event(QEvent::StyleAnimationUpdate); + QCoreApplication::sendEvent(target(), &event); + } +} + +QProgressStyleAnimation::QProgressStyleAnimation(int speed, QObject *target) : + QStyleAnimation(target), _speed(speed), _step(-1) +{ +} + +int QProgressStyleAnimation::animationStep() const +{ + return currentTime() / (1000.0 / _speed); +} + +int QProgressStyleAnimation::progressStep(int width) const +{ + int step = animationStep(); + int progress = (step * width / _speed) % width; + if (((step * width / _speed) % (2 * width)) >= width) + progress = width - progress; + return progress; +} + +int QProgressStyleAnimation::speed() const +{ + return _speed; +} + +void QProgressStyleAnimation::setSpeed(int speed) +{ + _speed = speed; +} + +bool QProgressStyleAnimation::isUpdateNeeded() const +{ + QProgressBar *pb = qobject_cast(parent()); + if (pb && pb->minimum() == 0 && pb->maximum() == 0) { + int current = animationStep(); + if (_step == -1 || _step != current) + { + _step = current; + return true; + } + } else { + // the progress bar is no longer indeterminate -> stop + const_cast(this)->stop(); + } + return false; +} + +#endif // QT_NO_ANIMATION + +QT_END_NAMESPACE diff --git a/src/widgets/styles/qstyleanimation_p.h b/src/widgets/styles/qstyleanimation_p.h new file mode 100644 index 0000000000..2c00048b7d --- /dev/null +++ b/src/widgets/styles/qstyleanimation_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** 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 QSTYLEANIMATION_P_H +#define QSTYLEANIMATION_P_H + +#include "qabstractanimation.h" +#include "qdatetime.h" + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience of +// qcommonstyle.cpp. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// + +#ifndef QT_NO_ANIMATION + +class QStyleAnimation : public QAbstractAnimation +{ + Q_OBJECT + +public: + QStyleAnimation(QObject *target); + virtual ~QStyleAnimation(); + + int duration() const; + QObject *target() const; + + QTime startTime() const; + void setStartTime(const QTime &time); + +protected: + virtual bool isUpdateNeeded() const; + virtual void updateCurrentTime(int time); + +private: + QTime _startTime; +}; + +class QProgressStyleAnimation : public QStyleAnimation +{ + Q_OBJECT + +public: + QProgressStyleAnimation(int speed, QObject *target); + + int animationStep() const; + int progressStep(int width) const; + + int speed() const; + void setSpeed(int speed); + +protected: + bool isUpdateNeeded() const; + +private: + int _speed; + mutable int _step; +}; + +#endif // QT_NO_ANIMATION + +QT_END_NAMESPACE + +#endif // QSTYLEANIMATION_P_H diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 1cd9a98e87..068b7a4355 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -3832,7 +3833,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (pb->minimum == 0 && pb->maximum == 0) { Q_D(const QWindowsStyle); int chunkCount = fillWidth/chunkWidth; - int offset = (d->animateStep*8%rect.width()); + int offset = 0; +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(w))) + offset = animation->animationStep() * 8 % rect.width(); +#endif int x = reverse ? r.left() + r.width() - offset - chunkWidth : r.x() + offset; while (chunkCount > 0) { r.setRect(x, rect.y(), chunkWidth, rect.height()); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 355ecf8a35..ee13852813 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -70,6 +70,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -117,7 +118,7 @@ enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight }; \internal */ QWindowsStylePrivate::QWindowsStylePrivate() - : alt_down(false), menuBarTimer(0), animationFps(10), animateTimer(0), animateStep(0) + : alt_down(false), menuBarTimer(0) { #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA @@ -126,27 +127,21 @@ QWindowsStylePrivate::QWindowsStylePrivate() pSHGetStockIconInfo = (PtrSHGetStockIconInfo)shellLib.resolve("SHGetStockIconInfo"); } #endif - startTime.start(); } -void QWindowsStylePrivate::startAnimation(QObject *o, QProgressBar *bar) +void QWindowsStylePrivate::startProgressAnimation(QObject *o, QProgressBar *bar) { - if (!animatedProgressBars.contains(bar)) { - animatedProgressBars << bar; - if (!animateTimer) { - Q_ASSERT(animationFps > 0); - animateTimer = o->startTimer(1000 / animationFps); - } - } + Q_UNUSED(o); +#ifndef QT_NO_ANIMATION + if (!animation(bar)) + startAnimation(new QProgressStyleAnimation(animationFps, bar)); +#endif } -void QWindowsStylePrivate::stopAnimation(QObject *o, QProgressBar *bar) +void QWindowsStylePrivate::stopProgressAnimation(QObject *o, QProgressBar *bar) { - animatedProgressBars.removeAll(bar); - if (animatedProgressBars.isEmpty() && animateTimer) { - o->killTimer(animateTimer); - animateTimer = 0; - } + Q_UNUSED(o); + stopAnimation(bar); } // Returns true if the toplevel parent of \a widget has seen the Alt-key @@ -156,23 +151,6 @@ bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const return seenAlt.contains(widget); } -/*! - \reimp -*/ -void QWindowsStyle::timerEvent(QTimerEvent *event) -{ -#ifndef QT_NO_PROGRESSBAR - Q_D(QWindowsStyle); - if (event->timerId() == d->animateTimer) { - Q_ASSERT(d->animationFps> 0); - d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps); - foreach (QProgressBar *bar, d->animatedProgressBars) - bar->update(); - } -#endif // QT_NO_PROGRESSBAR - event->ignore(); -} - /*! \reimp */ @@ -232,9 +210,9 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) // Animation by timer for progress bars that have their min and // max values the same if (bar->minimum() == bar->maximum()) - d->startAnimation(this, bar); + d->startProgressAnimation(this, bar); else - d->stopAnimation(this, bar); + d->stopProgressAnimation(this, bar); } break; case QEvent::Destroy: @@ -242,7 +220,7 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) // Do static_cast because there is no type info when getting // the destroy event. We know that it is a QProgressBar, since // we only install a widget event filter for QScrollBars. - d->stopAnimation(this, static_cast(o)); + d->stopProgressAnimation(this, static_cast(o)); break; #endif // QT_NO_PROGRESSBAR default: @@ -349,7 +327,7 @@ void QWindowsStyle::unpolish(QWidget *widget) if (QProgressBar *bar=qobject_cast(widget)) { Q_D(QWindowsStyle); widget->removeEventFilter(this); - d->stopAnimation(this, bar); + d->stopProgressAnimation(this, bar); } #endif } @@ -2405,8 +2383,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai pbBits.rect = rect; pbBits.palette = pal2; + int step = 0; int chunkCount = w / unit_width + 1; - int step = d->animateStep%chunkCount; +#ifndef QT_NO_ANIMATION + if (QProgressStyleAnimation *animation = qobject_cast(d->animation(widget))) + step = (animation->animationStep() / 3) % chunkCount; +#endif int chunksInRow = 5; int myY = pbBits.rect.y(); int myHeight = pbBits.rect.height(); diff --git a/src/widgets/styles/qwindowsstyle.h b/src/widgets/styles/qwindowsstyle.h index cacaeaa301..1d9347a72e 100644 --- a/src/widgets/styles/qwindowsstyle.h +++ b/src/widgets/styles/qwindowsstyle.h @@ -91,7 +91,6 @@ public: protected: bool eventFilter(QObject *o, QEvent *e); - void timerEvent(QTimerEvent *event); QWindowsStyle(QWindowsStylePrivate &dd); private: diff --git a/src/widgets/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h index 0cf53b9903..f24696f0bd 100644 --- a/src/widgets/styles/qwindowsstyle_p.h +++ b/src/widgets/styles/qwindowsstyle_p.h @@ -59,7 +59,6 @@ #ifndef QT_NO_STYLE_WINDOWS #include #include -#include QT_BEGIN_NAMESPACE @@ -71,19 +70,14 @@ class QWindowsStylePrivate : public QCommonStylePrivate Q_DECLARE_PUBLIC(QWindowsStyle) public: QWindowsStylePrivate(); - void startAnimation(QObject *o, QProgressBar *bar); - void stopAnimation(QObject *o, QProgressBar *bar); + void startProgressAnimation(QObject *o, QProgressBar *bar); + void stopProgressAnimation(QObject *o, QProgressBar *bar); bool hasSeenAlt(const QWidget *widget) const; bool altDown() const { return alt_down; } bool alt_down; QList seenAlt; int menuBarTimer; - QList animatedProgressBars; - int animationFps; - int animateTimer; - QElapsedTimer startTime; - int animateStep; QColor inactiveCaptionText; QColor activeCaptionColor; QColor activeGradientCaptionColor; diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index cb34a20fa3..d1a0af3a91 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -43,6 +43,7 @@ #include "qwindowsvistastyle_p.h" #include #include +#include #include #include #include @@ -202,6 +203,11 @@ void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option Q_UNUSED(painter); } +bool QWindowsVistaAnimation::isUpdateNeeded() const +{ + return QWindowsVistaStylePrivate::useVista(); +} + /*! \internal Helperfunction to paint the current transition state between two @@ -255,7 +261,7 @@ void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, flo /*! \internal Paints a transition state. The result will be a mix between the initial and final state of the transition, depending on the time - difference between _startTime and current time. + difference between startTime and current time. */ void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option) { @@ -263,18 +269,18 @@ void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *optio if (_duration > 0) { QTime current = QTime::currentTime(); - if (_startTime > current) - _startTime = current; + if (startTime() > current) + setStartTime(current); - int timeDiff = _startTime.msecsTo(current); + int timeDiff = startTime().msecsTo(current); alpha = timeDiff/(float)_duration; if (timeDiff > _duration) { - _running = false; + stop(); alpha = 1.0; } } else { - _running = false; + stop(); } drawBlendedImage(painter, option->rect, alpha); } @@ -282,7 +288,7 @@ void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *optio /*! \internal Paints a pulse. The result will be a mix between the primary and secondary pulse images depending on the time difference between - _startTime and current time. + startTime and current time. */ void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option) { @@ -290,15 +296,15 @@ void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option) if (_duration > 0) { QTime current = QTime::currentTime(); - if (_startTime > current) - _startTime = current; + if (startTime() > current) + setStartTime(current); - int timeDiff = _startTime.msecsTo(current) % _duration*2; + int timeDiff = startTime().msecsTo(current) % _duration*2; if (timeDiff > _duration) timeDiff = _duration*2 - timeDiff; alpha = timeDiff/(float)_duration; } else { - _running = false; + stop(); } drawBlendedImage(painter, option->rect, alpha); } @@ -341,6 +347,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt int state = option->state; if (!QWindowsVistaStylePrivate::useVista()) { + foreach (const QObject *target, d->animationTargets()) + d->stopAnimation(target); QWindowsStyle::drawPrimitive(element, option, painter, widget); return; } @@ -399,9 +407,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt startImage.fill(0); QPainter startPainter(&startImage); - QWindowsVistaAnimation *anim = d->widgetAnimation(widget); - QWindowsVistaTransition *t = new QWindowsVistaTransition; - t->setWidget(w); + QWindowsVistaAnimation *anim = qobject_cast(d->animation(widget)); + QWindowsVistaTransition *t = new QWindowsVistaTransition(w); // If we have a running animation on the widget already, we will use that to paint the initial // state of the new transition, this ensures a smooth transition from a current animation such as a @@ -539,7 +546,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_IndicatorCheckBox: case PE_IndicatorRadioButton: { - if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = qobject_cast(d->animation(widget)) ){ a->paint(painter, option); } else { QWindowsXPStyle::drawPrimitive(element, option, painter, widget); @@ -655,7 +662,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt break; case PE_FrameLineEdit: - if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = qobject_cast(d->animation(widget))) { anim->paint(painter, option); } else { QPainter *p = painter; @@ -903,6 +910,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QWindowsVistaStylePrivate *d = const_cast(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { + foreach (const QObject *target, d->animationTargets()) + d->stopAnimation(target); QWindowsStyle::drawControl(element, option, painter, widget); return; } @@ -950,14 +959,13 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); - QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + QWindowsVistaAnimation *anim = qobject_cast(d->animation(widget)); QStyleOptionButton opt = *button; opt.state = (QStyle::State)oldState; startImage.fill(0); - QWindowsVistaTransition *t = new QWindowsVistaTransition; - t->setWidget(w); + QWindowsVistaTransition *t = new QWindowsVistaTransition(w); QPainter startPainter(&startImage); if (!anim) { @@ -992,7 +1000,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption case CE_PushButtonBevel: if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { - QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + QWindowsVistaAnimation *anim = qobject_cast(d->animation(widget)); if (anim && (btn->state & State_Enabled)) { anim->paint(painter, option); } else { @@ -1026,8 +1034,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); alternateImage.fill(0); - QWindowsVistaPulse *pulse = new QWindowsVistaPulse; - pulse->setWidget(const_cast(widget)); + QWindowsVistaPulse *pulse = new QWindowsVistaPulse(const_cast(widget)); QPainter startPainter(&startImage); stateId = PBS_DEFAULTED; @@ -1095,16 +1102,10 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } if (const QProgressBar *progressbar = qobject_cast(widget)) { - if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) { - if (!d->widgetAnimation(progressbar)) { - QWindowsVistaAnimation *a = new QWindowsVistaAnimation; - a->setWidget(const_cast(widget)); - a->setStartTime(QTime::currentTime()); - d->startAnimation(a); - } - } else { + if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) + d->startProgressAnimation(0, const_cast(progressbar)); + else d->stopAnimation(progressbar); - } } XPThemeData theme(widget, painter, @@ -1115,7 +1116,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QTime current = QTime::currentTime(); if (isIndeterminate) { - if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { + if (QProgressStyleAnimation *a = qobject_cast(d->animation(widget))) { int glowSize = 120; int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); int animOffset = a->startTime().msecsTo(current) / 4; @@ -1185,7 +1186,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } d->drawBackground(theme); - if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { + if (QProgressStyleAnimation *a = qobject_cast(d->animation(widget))) { int glowSize = 140; int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); int animOffset = a->startTime().msecsTo(current) / 4; @@ -1574,6 +1575,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle { QWindowsVistaStylePrivate *d = const_cast(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { + foreach (const QObject *target, d->animationTargets()) + d->stopAnimation(target); QWindowsStyle::drawComplexControl(control, option, painter, widget); return; } @@ -1636,9 +1639,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); - QWindowsVistaAnimation *anim = d->widgetAnimation(widget); - QWindowsVistaTransition *t = new QWindowsVistaTransition; - t->setWidget(w); + QWindowsVistaAnimation *anim = qobject_cast(d->animation(widget)); + QWindowsVistaTransition *t = new QWindowsVistaTransition(w); if (!anim) { if (const QStyleOptionComboBox *combo = qstyleoption_cast(option)) { //Combo boxes are special cased to avoid cleartype issues @@ -1692,7 +1694,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle t->setDuration(500); } - if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = qobject_cast(d->animation(widget))) { anim->paint(painter, option); return; } @@ -2335,29 +2337,6 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt return rect; } -/*! - \internal - */ -bool QWindowsVistaStyle::event(QEvent *e) -{ - Q_D(QWindowsVistaStyle); - switch (e->type()) { - case QEvent::Timer: - { - QTimerEvent *timerEvent = (QTimerEvent *)e; - if (d->animationTimer.timerId() == timerEvent->timerId()) { - d->timerEvent(); - e->accept(); - return true; - } - } - break; - default: - break; - } - return QWindowsXPStyle::event(e); -} - /*! \internal */ @@ -2549,53 +2528,9 @@ QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() : QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate() { - qDeleteAll(animations); cleanupTreeViewTheming(); } -void QWindowsVistaStylePrivate::timerEvent() -{ - for (int i = animations.size() - 1 ; i >= 0 ; --i) { - - if (animations[i]->widget()) - animations[i]->widget()->update(); - - if (!animations[i]->widget() || - !animations[i]->widget()->isVisible() || - animations[i]->widget()->window()->isMinimized() || - !animations[i]->running() || - !QWindowsVistaStylePrivate::useVista()) - { - QWindowsVistaAnimation *a = animations.takeAt(i); - delete a; - } - } - if (animations.size() == 0 && animationTimer.isActive()) { - animationTimer.stop(); - } -} - -void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w) -{ - for (int i = animations.size() - 1 ; i >= 0 ; --i) { - if (animations[i]->widget() == w) { - QWindowsVistaAnimation *a = animations.takeAt(i); - delete a; - break; - } - } -} - -void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t) -{ - Q_Q(QWindowsVistaStyle); - stopAnimation(t->widget()); - animations.append(t); - if (animations.size() > 0 && !animationTimer.isActive()) { - animationTimer.start(45, q); - } -} - bool QWindowsVistaStylePrivate::transitionsEnabled() const { BOOL animEnabled = false; @@ -2607,19 +2542,6 @@ bool QWindowsVistaStylePrivate::transitionsEnabled() const return false; } - -QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const -{ - if (!widget) - return 0; - foreach (QWindowsVistaAnimation *a, animations) { - if (a->widget() == widget) - return a; - } - return 0; -} - - /*! \internal Returns true if all the necessary theme engine symbols were resolved. diff --git a/src/widgets/styles/qwindowsvistastyle.h b/src/widgets/styles/qwindowsvistastyle.h index 5a030afddc..0b17881101 100644 --- a/src/widgets/styles/qwindowsvistastyle.h +++ b/src/widgets/styles/qwindowsvistastyle.h @@ -88,7 +88,6 @@ public: void polish(QPalette &pal); void polish(QApplication *app); void unpolish(QApplication *app); - bool event(QEvent *event); QPalette standardPalette() const; private: diff --git a/src/widgets/styles/qwindowsvistastyle_p.h b/src/widgets/styles/qwindowsvistastyle_p.h index faf3777025..1d427fe45c 100644 --- a/src/widgets/styles/qwindowsvistastyle_p.h +++ b/src/widgets/styles/qwindowsvistastyle_p.h @@ -57,6 +57,7 @@ #if !defined(QT_NO_STYLE_WINDOWSVISTA) #include +#include #include #include #include @@ -83,7 +84,6 @@ #include #include #include -#include #include #include @@ -135,57 +135,50 @@ QT_BEGIN_NAMESPACE #define TDLG_SECONDARYPANEL 8 #endif -class QWindowsVistaAnimation +class QWindowsVistaAnimation : public QStyleAnimation { -public : - QWindowsVistaAnimation() : _running(true) { } + Q_OBJECT +public: + QWindowsVistaAnimation(QObject *target) : QStyleAnimation(target), _duration(-1) { } virtual ~QWindowsVistaAnimation() { } - QWidget * widget() const { return _widget; } - bool running() const { return _running; } - const QTime &startTime() const { return _startTime; } - void setRunning(bool val) { _running = val; } - void setWidget(QWidget *widget) { _widget = widget; } - void setStartTime(const QTime &startTime) { _startTime = startTime; } virtual void paint(QPainter *painter, const QStyleOption *option); + virtual bool isUpdateNeeded() const; + virtual int duration() const { return _duration; } + //set time in ms to complete a state transition / pulse cycle + void setDuration(int duration) { _duration = duration; } protected: void drawBlendedImage(QPainter *painter, QRect rect, float value); - QTime _startTime; - QPointer _widget; QImage _primaryImage; QImage _secondaryImage; QImage _tempImage; - bool _running; + int _duration; }; // Handles state transition animations class QWindowsVistaTransition : public QWindowsVistaAnimation { -public : - QWindowsVistaTransition() : QWindowsVistaAnimation() {} + Q_OBJECT +public: + QWindowsVistaTransition(QObject *target) : QWindowsVistaAnimation(target) {} virtual ~QWindowsVistaTransition() { } - void setDuration(int duration) { _duration = duration; } void setStartImage(const QImage &image) { _primaryImage = image; } void setEndImage(const QImage &image) { _secondaryImage = image; } virtual void paint(QPainter *painter, const QStyleOption *option); - int duration() const { return _duration; } - int _duration; //set time in ms to complete a state transition }; // Handles pulse animations (default buttons) class QWindowsVistaPulse: public QWindowsVistaAnimation { -public : - QWindowsVistaPulse() : QWindowsVistaAnimation() {} + Q_OBJECT +public: + QWindowsVistaPulse(QObject *target) : QWindowsVistaAnimation(target) {} virtual ~QWindowsVistaPulse() { } - void setDuration(int duration) { _duration = duration; } void setPrimaryImage(const QImage &image) { _primaryImage = image; } void setAlternateImage(const QImage &image) { _secondaryImage = image; } virtual void paint(QPainter *painter, const QStyleOption *option); - int duration() const { return _duration; } - int _duration; //time in ms to complete a pulse cycle }; @@ -198,18 +191,12 @@ public: ~QWindowsVistaStylePrivate(); static bool resolveSymbols(); static inline bool useVista(); - void startAnimation(QWindowsVistaAnimation *); - void stopAnimation(const QWidget *); - QWindowsVistaAnimation* widgetAnimation(const QWidget *) const; - void timerEvent(); bool transitionsEnabled() const; private: bool initTreeViewTheming(); void cleanupTreeViewTheming(); - QList animations; - QBasicTimer animationTimer; HWND m_treeViewHelper; }; diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri index 6ba9875236..d04b3d5416 100644 --- a/src/widgets/styles/styles.pri +++ b/src/widgets/styles/styles.pri @@ -3,6 +3,7 @@ HEADERS += \ styles/qdrawutil.h \ styles/qstyle.h \ + styles/qstyleanimation_p.h \ styles/qstylefactory.h \ styles/qstyleoption.h \ styles/qstyleplugin.h \ @@ -11,12 +12,14 @@ HEADERS += \ styles/qstylehelper_p.h \ styles/qproxystyle.h \ styles/qproxystyle_p.h \ + styles/qcommonstyle_p.h \ styles/qstylepainter.h \ styles/qstylesheetstyle_p.h SOURCES += \ styles/qdrawutil.cpp \ styles/qstyle.cpp \ + styles/qstyleanimation.cpp \ styles/qstylefactory.cpp \ styles/qstyleoption.cpp \ styles/qstyleplugin.cpp \ -- cgit v1.2.3