summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJens Bache-Wiig <jens.bache-wiig@digia.com>2012-10-23 18:34:25 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-25 16:09:34 +0200
commit79a389c34618880fab7a0b4f397ed3b0f0c0c675 (patch)
tree0c23860bc80d02dfe115b52f13f989bfa22d779b /src
parent38630bc35af614ddebade70b9a44574c162ce4a9 (diff)
Remove widget dependencies on Vista style animations
This patch will make it possible to get animations on desktop components without using the widget pointer. Change-Id: I2d2eca111dab0d96f276ff3627505c0652c4b4e5 Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp679
1 files changed, 350 insertions, 329 deletions
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index d58e76e043..87c67dc84b 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -144,6 +144,20 @@ bool QWindowsVistaStylePrivate::useVista()
(QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)));
}
+/* \internal
+ Checks and returns the style object
+*/
+inline QObject *styleObject(const QStyleOption *option) {
+ return option ? option->styleObject : 0;
+}
+
+bool canAnimate(const QStyleOption *option) {
+ return option
+ && option->styleObject
+ && !option->styleObject->property("_q_no_animation").toBool();
+}
+
+
/*!
\class QWindowsVistaStyle
\brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
@@ -328,17 +342,17 @@ void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option)
transition has completed. During this time, the result will be
retrieved by the Animation::paint(...) function and not by the style
itself.
-
+
To determine if a transition should occur, the style needs to know
the previous state of the widget as well as the current one. This is
solved by updating dynamic properties on the widget every time the
function is called.
-
+
Transitions interrupting existing transitions should always be
smooth, so whenever a hover-transition is started on a pulsating
button, it uses the current frame of the pulse-animation as the
starting image for the hover transition.
-
+
*/
void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const
@@ -353,135 +367,135 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
return;
}
- QRect oldRect;
- QRect newRect;
-
- if (widget && d->transitionsEnabled())
- {
- /* all widgets that supports state transitions : */
- if (
-#ifndef QT_NO_LINEEDIT
- (qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) ||
-#endif // QT_NO_LINEEDIT
- (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) ||
- (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) ||
- (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) ||
- (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel)
- )
+ if (d->transitionsEnabled() && canAnimate(option)) {
{
- // Retrieve and update the dynamic properties tracking
- // the previous state of the widget:
- QWidget *w = const_cast<QWidget *> (widget);
- int oldState = w->property("_q_stylestate").toInt();
- oldRect = w->property("_q_stylerect").toRect();
- newRect = w->rect();
- w->setProperty("_q_stylestate", (int)option->state);
- w->setProperty("_q_stylerect", w->rect());
-
- bool doTransition = oldState &&
- ((state & State_Sunken) != (oldState & State_Sunken) ||
- (state & State_On) != (oldState & State_On) ||
- (state & State_MouseOver) != (oldState & State_MouseOver));
-
- if (oldRect != newRect ||
- (state & State_Enabled) != (oldState & State_Enabled) ||
- (state & State_Active) != (oldState & State_Active))
- d->stopAnimation(widget);
+ QRect oldRect;
+ QRect newRect;
-#ifndef QT_NO_LINEEDIT
- if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget))
- if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits
+ /* widgets that support state transitions : */
+ if ( element == PE_FrameLineEdit
+ || element == PE_IndicatorRadioButton
+ || element == PE_IndicatorCheckBox)
+ {
+ // Retrieve and update the dynamic properties tracking
+ // the previous state of the widget:
+ QObject *styleObject = option->styleObject;
+ styleObject->setProperty("_q_no_animation", true);
+
+ int oldState = styleObject->property("_q_stylestate").toInt();
+ oldRect = styleObject->property("_q_stylerect").toRect();
+ newRect = option->rect;
+ styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylerect", option->rect);
+
+ bool doTransition = oldState &&
+ ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
+
+ if (oldRect != newRect ||
+ (state & State_Enabled) != (oldState & State_Enabled) ||
+ (state & State_Active) != (oldState & State_Active))
+ d->stopAnimation(styleObject);
+
+ if (option->state & State_ReadOnly && element == PE_FrameLineEdit) // Do not animate read only line edits
doTransition = false;
-#endif // QT_NO_LINEEDIT
- if (doTransition) {
+ if (doTransition) {
+ QStyleOption *styleOption = 0;
+ if (const QStyleOptionGroupBox *combo = qstyleoption_cast<const QStyleOptionGroupBox*>(option))
+ styleOption = new QStyleOptionGroupBox(*combo);
+ else
+ styleOption = new QStyleOption(*option);
- // We create separate images for the initial and final transition states and store them in the
- // Transition object.
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QStyleOption opt = *option;
+ styleOption->state = (QStyle::State)oldState;
+ styleOption->rect = QRect(QPoint(0,0), newRect.size());
- opt.rect.setRect(0, 0, option->rect.width(), option->rect.height());
- opt.state = (QStyle::State)oldState;
- startImage.fill(0);
- QPainter startPainter(&startImage);
+ QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
+ QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
- QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget));
- QWindowsVistaTransition *t = new QWindowsVistaTransition(w);
+ // We create separate images for the initial and final transition states and store them in the
+ // Transition object.
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
- // 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
- // pulsating default button into the intended target state.
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
- if (!anim)
- proxy()->drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0
- else // this ensures that we do not recurse in the animation logic above
- anim->paint(&startPainter, &opt);
+ // 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
+ // pulsating default button into the intended target state.
+ if (!anim)
+ proxy()->drawPrimitive(element, styleOption, &startPainter, widget);
+ else
+ anim->paint(&startPainter, styleOption);
- d->startAnimation(t);
- t->setStartImage(startImage);
+ t->setStartImage(startImage);
- // The end state of the transition is simply the result we would have painted
- // if the style was not animated.
+ // The end state of the transition is simply the result we would have painted
+ // if the style was not animated.
+ styleOption->state = option->state;
+ drawPrimitive(element, styleOption, &endPainter, widget);
- QPainter endPainter(&endImage);
- endImage.fill(0);
- QStyleOption opt2 = opt;
- opt2.state = option->state;
- proxy()->drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0
- // this ensures that we do not recurse in the animation logic above
- t->setEndImage(endImage);
- HTHEME theme;
- int partId;
- int duration;
- int fromState = 0;
- int toState = 0;
+ t->setEndImage(endImage);
- //translate state flags to UXTHEME states :
- if (element == PE_FrameLineEdit) {
- theme = pOpenThemeData(0, L"Edit");
- partId = EP_EDITBORDER_NOSCROLL;
+ HTHEME theme;
+ int partId;
+ int duration;
+ int fromState = 0;
+ int toState = 0;
+
+ //translate state flags to UXTHEME states :
+ if (element == PE_FrameLineEdit) {
+ theme = pOpenThemeData(0, L"Edit");
+ partId = EP_EDITBORDER_NOSCROLL;
+
+ if (oldState & State_MouseOver)
+ fromState = ETS_HOT;
+ else if (oldState & State_HasFocus)
+ fromState = ETS_FOCUSED;
+ else
+ fromState = ETS_NORMAL;
- if (oldState & State_MouseOver)
- fromState = ETS_HOT;
- else if (oldState & State_HasFocus)
- fromState = ETS_FOCUSED;
- else
- fromState = ETS_NORMAL;
+ if (state & State_MouseOver)
+ toState = ETS_HOT;
+ else if (state & State_HasFocus)
+ toState = ETS_FOCUSED;
+ else
+ toState = ETS_NORMAL;
- if (state & State_MouseOver)
- toState = ETS_HOT;
- else if (state & State_HasFocus)
- toState = ETS_FOCUSED;
- else
- toState = ETS_NORMAL;
+ } else {
+ theme = pOpenThemeData(0, L"Button");
+ if (element == PE_IndicatorRadioButton)
+ partId = BP_RADIOBUTTON;
+ else if (element == PE_IndicatorCheckBox)
+ partId = BP_CHECKBOX;
+ else
+ partId = BP_PUSHBUTTON;
- } else {
- theme = pOpenThemeData(0, L"Button");
- if (element == PE_IndicatorRadioButton)
- partId = BP_RADIOBUTTON;
- else if (element == PE_IndicatorCheckBox)
- partId = BP_CHECKBOX;
- else
- partId = BP_PUSHBUTTON;
+ fromState = buttonStateId(oldState, partId);
+ toState = buttonStateId(option->state, partId);
+ }
- fromState = buttonStateId(oldState, partId);
- toState = buttonStateId(option->state, partId);
- }
+ // Retrieve the transition time between the states from the system.
+ if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
+ TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+ {
+ t->setDuration(duration);
+ }
+ t->setStartTime(QTime::currentTime());
- // Retrieve the transition time between the states from the system.
- if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
- TMT_TRANSITIONDURATIONS, &duration) == S_OK)
- {
- t->setDuration(duration);
+ delete styleOption;
+ d->startAnimation(t);
}
- t->setStartTime(QTime::currentTime());
+ styleObject->setProperty("_q_no_animation", false);
}
- }
- } // End of animation part
+ } // End of animation part
+ }
QRect rect = option->rect;
@@ -546,7 +560,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
case PE_IndicatorCheckBox:
case PE_IndicatorRadioButton:
{
- if (QWindowsVistaAnimation *a = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget)) ){
+ if (QWindowsVistaAnimation *a =
+ qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))){
a->paint(painter, option);
} else {
QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
@@ -563,36 +578,32 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
d->drawBackground(theme);
}
break;
- case PE_Frame:
-#ifndef QT_NO_TEXTEDIT
- if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) {
- painter->save();
- int stateId = ETS_NORMAL;
- if (!(state & State_Enabled))
- stateId = ETS_DISABLED;
- else if (edit->isReadOnly())
- stateId = ETS_READONLY;
- else if (state & State_HasFocus)
- stateId = ETS_SELECTED;
- XPThemeData theme(widget, painter,
- QWindowsXPStylePrivate::EditTheme,
- EP_EDITBORDER_HVSCROLL, stateId, option->rect);
- uint resolve_mask = option->palette.resolve();
- if (resolve_mask & (1 << QPalette::Base)) {
- // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
- int borderSize = 1;
- pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
- QRegion clipRegion = option->rect;
- QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
- clipRegion ^= content;
- painter->setClipRegion(clipRegion);
- }
- d->drawBackground(theme);
- painter->restore();
- } else
-#endif // QT_NO_TEXTEDIT
- QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
- break;
+ case PE_Frame: {
+ painter->save();
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = ETS_READONLY;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter,
+ QWindowsXPStylePrivate::EditTheme,
+ EP_EDITBORDER_HVSCROLL, stateId, option->rect);
+ uint resolve_mask = option->palette.resolve();
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
+ int borderSize = 1;
+ pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
+ QRegion clipRegion = option->rect;
+ QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ clipRegion ^= content;
+ painter->setClipRegion(clipRegion);
+ }
+ d->drawBackground(theme);
+ painter->restore();
+ }
+ break;
case PE_PanelLineEdit:
if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
@@ -662,7 +673,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
break;
case PE_FrameLineEdit:
- if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget))) {
+ if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))) {
anim->paint(painter, option);
} else {
QPainter *p = painter;
@@ -928,145 +939,166 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int partId = 0;
int stateId = 0;
- QRect oldRect;
- QRect newRect;
+ if (d->transitionsEnabled() && canAnimate(option))
+ {
+ if (element == CE_PushButtonBevel) {
+ QRect oldRect;
+ QRect newRect;
+
+ QObject *styleObject = option->styleObject;
+
+ int oldState = styleObject->property("_q_stylestate").toInt();
+ oldRect = styleObject->property("_q_stylerect").toRect();
+ newRect = option->rect;
+ styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylerect", option->rect);
+
+ bool wasDefault = false;
+ bool isDefault = false;
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ wasDefault = styleObject->property("_q_isdefault").toBool();
+ isDefault = button->features & QStyleOptionButton::DefaultButton;
+ styleObject->setProperty("_q_isdefault", isDefault);
+ }
- if (d->transitionsEnabled() && widget) {
- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- if ((qobject_cast<const QPushButton*>(widget) && element == CE_PushButtonBevel))
- {
- QWidget *w = const_cast<QWidget *> (widget);
- int oldState = w->property("_q_stylestate").toInt();
- oldRect = w->property("_q_stylerect").toRect();
- newRect = w->rect();
- w->setProperty("_q_stylestate", (int)option->state);
- w->setProperty("_q_stylerect", w->rect());
-
- bool wasDefault = w->property("_q_isdefault").toBool();
- bool isDefault = button->features & QStyleOptionButton::DefaultButton;
- w->setProperty("_q_isdefault", isDefault);
-
- bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
- (state & State_On) != (oldState & State_On) ||
- (state & State_MouseOver) != (oldState & State_MouseOver));
-
- if (oldRect != newRect || (wasDefault && !isDefault))
- {
- doTransition = false;
- d->stopAnimation(widget);
- }
+ bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
- if (doTransition) {
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget));
+ if (oldRect != newRect || (wasDefault && !isDefault)) {
+ doTransition = false;
+ d->stopAnimation(styleObject);
+ }
- QStyleOptionButton opt = *button;
- opt.state = (QStyle::State)oldState;
+ if (doTransition) {
+ styleObject->setProperty("_q_no_animation", true);
+
+ QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
+ QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
+ QStyleOption *styleOption = 0;
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option))
+ styleOption = new QStyleOptionComboBox(*combo);
+ else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option))
+ styleOption = new QStyleOptionButton(*button);
+ else
+ styleOption = new QStyleOption(*option);
- startImage.fill(0);
- QWindowsVistaTransition *t = new QWindowsVistaTransition(w);
- QPainter startPainter(&startImage);
+ styleOption->state = (QStyle::State)oldState;
+ styleOption->rect = QRect(QPoint(0,0), newRect.size());
- if (!anim) {
- proxy()->drawControl(element, &opt, &startPainter, 0 /* Intentional */);
- } else {
- anim->paint(&startPainter, &opt);
- d->stopAnimation(widget);
- }
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
- t->setStartImage(startImage);
- d->startAnimation(t);
+ // Use current state of existing animation if already one is running
+ if (!anim) {
+ proxy()->drawControl(element, styleOption, &startPainter, widget);
+ } else {
+ anim->paint(&startPainter, styleOption);
+ d->stopAnimation(styleObject);
+ }
- endImage.fill(0);
- QPainter endPainter(&endImage);
- proxy()->drawControl(element, option, &endPainter, 0 /* Intentional */);
- t->setEndImage(endImage);
- int duration = 0;
- HTHEME theme = pOpenThemeData(0, L"Button");
+ t->setStartImage(startImage);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+ styleOption->state = option->state;
+ proxy()->drawControl(element, styleOption, &endPainter, widget);
+ t->setEndImage(endImage);
- int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
- int toState = buttonStateId(option->state, BP_PUSHBUTTON);
- if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
- t->setDuration(duration);
- else
- t->setDuration(0);
- t->setStartTime(QTime::currentTime());
- }
+
+ int duration = 0;
+ HTHEME theme = pOpenThemeData(0, L"Button");
+
+ int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
+ int toState = buttonStateId(option->state, BP_PUSHBUTTON);
+ if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+ t->setDuration(duration);
+ else
+ t->setDuration(0);
+ t->setStartTime(QTime::currentTime());
+ styleObject->setProperty("_q_no_animation", false);
+
+ delete styleOption;
+ d->startAnimation(t);
+ }
+
+ QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
+ if (anim) {
+ anim->paint(painter, option);
+ return;
}
+
}
}
switch (element) {
case CE_PushButtonBevel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
{
- QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget));
- if (anim && (btn->state & State_Enabled)) {
- anim->paint(painter, option);
- } else {
- themeNumber = QWindowsXPStylePrivate::ButtonTheme;
- partId = BP_PUSHBUTTON;
- if (btn->features & QStyleOptionButton::CommandLinkButton)
- partId = BP_COMMANDLINK;
- bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
- if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
- stateId = PBS_DISABLED;
- else if (justFlat)
- ;
- else if (flags & (State_Sunken | State_On))
- stateId = PBS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = PBS_HOT;
- else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
- stateId = PBS_DEFAULTED;
- else
- stateId = PBS_NORMAL;
+ themeNumber = QWindowsXPStylePrivate::ButtonTheme;
+ partId = BP_PUSHBUTTON;
+ if (btn->features & QStyleOptionButton::CommandLinkButton)
+ partId = BP_COMMANDLINK;
+ bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
+ if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
+ stateId = PBS_DISABLED;
+ else if (justFlat)
+ ;
+ else if (flags & (State_Sunken | State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
- if (!justFlat) {
+ if (!justFlat) {
- if (widget && d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
+ if (d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
!(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
- (state & State_Enabled) && (state & State_Active))
- {
- if (!anim && widget) {
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- startImage.fill(0);
- QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- alternateImage.fill(0);
-
- QWindowsVistaPulse *pulse = new QWindowsVistaPulse(const_cast<QWidget*>(widget));
-
- QPainter startPainter(&startImage);
- stateId = PBS_DEFAULTED;
- XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect);
- d->drawBackground(theme);
-
- QPainter alternatePainter(&alternateImage);
- theme.stateId = PBS_DEFAULTED_ANIMATING;
- theme.painter = &alternatePainter;
- d->drawBackground(theme);
- pulse->setPrimaryImage(startImage);
- pulse->setAlternateImage(alternateImage);
- pulse->setStartTime(QTime::currentTime());
- pulse->setDuration(2000);
- d->startAnimation(pulse);
- anim = pulse;
- }
+ (state & State_Enabled) && (state & State_Active))
+ {
+ QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)));
- if (anim)
- anim->paint(painter, option);
- else {
- XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
- d->drawBackground(theme);
- }
+ if (!anim) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ startImage.fill(0);
+ QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ alternateImage.fill(0);
+
+ QWindowsVistaPulse *pulse = new QWindowsVistaPulse(styleObject(option));
+
+ QPainter startPainter(&startImage);
+ stateId = PBS_DEFAULTED;
+ XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect);
+ d->drawBackground(theme);
+
+ QPainter alternatePainter(&alternateImage);
+ theme.stateId = PBS_DEFAULTED_ANIMATING;
+ theme.painter = &alternatePainter;
+ d->drawBackground(theme);
+ pulse->setPrimaryImage(startImage);
+ pulse->setAlternateImage(alternateImage);
+ pulse->setStartTime(QTime::currentTime());
+ pulse->setDuration(2000);
+ d->startAnimation(pulse);
+ anim = pulse;
}
+
+ if (anim)
+ anim->paint(painter, option);
else {
- d->stopAnimation(widget);
XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
d->drawBackground(theme);
}
}
+ else {
+ XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
}
+
if (btn->features & QStyleOptionButton::HasMenu) {
int mbiw = 0, mbih = 0;
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
@@ -1102,10 +1134,10 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
if (isIndeterminate || (bar->progress > 0 && (bar->progress < bar->maximum) && d->transitionsEnabled())) {
- if (!d->animation(option->styleObject))
- d->startAnimation(new QProgressStyleAnimation(d->animationFps, option->styleObject));
+ if (!d->animation(styleObject(option)))
+ d->startAnimation(new QProgressStyleAnimation(d->animationFps, styleObject(option)));
} else {
- d->stopAnimation(option->styleObject);
+ d->stopAnimation(styleObject(option));
}
XPThemeData theme(widget, painter,
@@ -1116,7 +1148,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QTime current = QTime::currentTime();
if (isIndeterminate) {
- if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(option->styleObject))) {
+ if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) {
int glowSize = 120;
int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
int animOffset = a->startTime().msecsTo(current) / 4;
@@ -1186,7 +1218,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
d->drawBackground(theme);
- if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(option->styleObject))) {
+ if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) {
int glowSize = 140;
int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
int animOffset = a->startTime().msecsTo(current) / 4;
@@ -1195,7 +1227,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (bar->progress < bar->maximum)
a->setStartTime(QTime::currentTime());
else
- d->stopAnimation(option->styleObject); //we stop the glow motion only after it has
+ d->stopAnimation(styleObject(option)); //we stop the glow motion only after it has
//moved out of view
}
painter->save();
@@ -1592,38 +1624,33 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
flags |= State_MouseOver;
- if (d->transitionsEnabled() && widget) {
- if ((qobject_cast<const QScrollBar *>(widget) && control == CC_ScrollBar)
-#ifndef QT_NO_SPINBOX
- || (qobject_cast<const QAbstractSpinBox*>(widget) && control == CC_SpinBox)
-#endif // QT_NO_SPINBOX
-#ifndef QT_NO_COMBOBOX
- || (qobject_cast<const QComboBox*>(widget) && control == CC_ComboBox)
-#endif // QT_NO_COMBOBOX
- )
- {
- QWidget *w = const_cast<QWidget *> (widget);
+ if (d->transitionsEnabled() && canAnimate(option))
+ {
+
+ if (control == CC_ScrollBar || control == CC_SpinBox ) {
+
+ QObject *styleObject = option->styleObject; // Can be widget or qquickitem
- int oldState = w->property("_q_stylestate").toInt();
- int oldActiveControls = w->property("_q_stylecontrols").toInt();
- QRect oldRect = w->property("_q_stylerect").toRect();
- w->setProperty("_q_stylestate", (int)option->state);
- w->setProperty("_q_stylecontrols", (int)option->activeSubControls);
- w->setProperty("_q_stylerect", w->rect());
+ int oldState = styleObject->property("_q_stylestate").toInt();
+ int oldActiveControls = styleObject->property("_q_stylecontrols").toInt();
+
+ QRect oldRect = styleObject->property("_q_stylerect").toRect();
+ styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylecontrols", (int)option->activeSubControls);
+ styleObject->setProperty("_q_stylerect", option->rect);
bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
(state & State_On) != (oldState & State_On) ||
(state & State_MouseOver) != (oldState & State_MouseOver) ||
- oldActiveControls != option->activeSubControls);
-
+ oldActiveControls != option->activeSubControls);
if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- QRect oldSliderPos = w->property("_q_stylesliderpos").toRect();
+ QRect oldSliderPos = styleObject->property("_q_stylesliderpos").toRect();
QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- w->setProperty("_q_stylesliderpos", currentPos);
+ styleObject->setProperty("_q_stylesliderpos", currentPos);
if (oldSliderPos != currentPos) {
doTransition = false;
- d->stopAnimation(widget);
+ d->stopAnimation(styleObject);
}
} else if (control == CC_SpinBox) {
//spinboxes have a transition when focus changes
@@ -1633,58 +1660,51 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
if (oldRect != option->rect) {
doTransition = false;
- d->stopAnimation(widget);
+ d->stopAnimation(styleObject);
}
if (doTransition) {
QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+
QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget));
- QWindowsVistaTransition *t = new QWindowsVistaTransition(w);
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+
+ QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
+ QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
+
+ // Draw the image that ends the animation by using the current styleoption
+ QStyleOptionComplex *styleOption = 0;
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option))
+ styleOption = new QStyleOptionSlider(*slider);
+ else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option))
+ styleOption = new QStyleOptionSpinBox(*spinbox);
+ else
+ styleOption = new QStyleOptionComplex(*option);
+
+ styleOption->rect = QRect(QPoint(0,0), option->rect.size());
+
+ styleObject->setProperty("_q_no_animation", true);
+
+ // Draw transition source
if (!anim) {
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
- //Combo boxes are special cased to avoid cleartype issues
- startImage.fill(0);
- QPainter startPainter(&startImage);
- QStyleOptionComboBox startCombo = *combo;
- startCombo.state = (QStyle::State)oldState;
- startCombo.activeSubControls = (QStyle::SubControl)oldActiveControls;
- proxy()->drawComplexControl(control, &startCombo, &startPainter, 0 /* Intentional */);
- t->setStartImage(startImage);
- } else if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
- //This is a workaround for the direct3d engine as it currently has some issues with grabWindow
- startImage.fill(0);
- QPainter startPainter(&startImage);
- QStyleOptionSlider startSlider = *slider;
- startSlider.state = (QStyle::State)oldState;
- startSlider.activeSubControls = (QStyle::SubControl)oldActiveControls;
- proxy()->drawComplexControl(control, &startSlider, &startPainter, 0 /* Intentional */);
- t->setStartImage(startImage);
- } else {
- QPoint offset(0, 0);
- QWindow *window = widget->windowHandle();
- if (!window) {
- if (const QWidget *nativeParent = widget->nativeParentWidget()) {
- offset = widget->mapTo(nativeParent, offset);
- window = nativeParent->windowHandle();
- }
- }
- if (window && window->handle()) {
- const QPixmap pixmap = window->screen()->grabWindow(window->winId(),
- offset.x(), offset.y(), option->rect.width(), option->rect.height());
- t->setStartImage(pixmap.toImage());
- }
- }
+ styleOption->state = (QStyle::State)oldState;
+ styleOption->activeSubControls = (QStyle::SubControl)oldActiveControls;
+ proxy()->drawComplexControl(control, styleOption, &startPainter, widget);
} else {
- startImage.fill(0);
- QPainter startPainter(&startImage);
anim->paint(&startPainter, option);
- t->setStartImage(startImage);
}
- d->startAnimation(t);
- endImage.fill(0);
- QPainter endPainter(&endImage);
- proxy()->drawComplexControl(control, option, &endPainter, 0 /* Intentional */);
+ t->setStartImage(startImage);
+
+ // Draw transition target
+ styleOption->state = option->state;
+ styleOption->activeSubControls = option->activeSubControls;
+ proxy()->drawComplexControl(control, styleOption, &endPainter, widget);
+
+ styleObject->setProperty("_q_no_animation", false);
+
t->setEndImage(endImage);
t->setStartTime(QTime::currentTime());
@@ -1692,13 +1712,14 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
t->setDuration(150);
else
t->setDuration(500);
- }
- if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(widget))) {
+ delete styleOption;
+ d->startAnimation(t);
+ }
+ if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject))) {
anim->paint(painter, option);
return;
}
-
}
}