Revise QMacStyle scrollbar animation handling

Skip animations whether styleObject is not set.

Task-number: QTBUG-27895
Change-Id: I1d2e4655b735627b672bc85f773605adcd375418
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
J-P Nurmi 2012-11-29 21:18:25 +01:00 committed by The Qt Project
parent 2ffb9b489a
commit f52177829a

View File

@ -4906,70 +4906,60 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (cc == CC_ScrollBar && proxy()->styleHint(SH_ScrollBar_Transient)) { if (cc == CC_ScrollBar && proxy()->styleHint(SH_ScrollBar_Transient)) {
QObject *styleObject = opt->styleObject; bool wasActive = false;
CGFloat opacity = 1.0;
if (QObject *styleObject = opt->styleObject) {
int oldPos = styleObject->property("_q_stylepos").toInt();
int oldMin = styleObject->property("_q_stylemin").toInt();
int oldMax = styleObject->property("_q_stylemax").toInt();
QRect oldRect = styleObject->property("_q_stylerect").toRect();
int oldState = styleObject->property("_q_stylestate").toInt();
uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt();
// Qt generally excepts styleObject to be set during draw calls, but // a scrollbar is transient when the the scrollbar itself and
// this is not always done. Create a temprary object in that case to // its sibling are both inactive (ie. not pressed/hovered/moved)
// prevent crashing. This will disable scroll bar animations. bool transient = !opt->activeSubControls && !(slider->state & State_On);
bool deleteStyleObject = false;
if (!styleObject) {
deleteStyleObject = true;
styleObject = new QObject;
}
int oldPos = styleObject->property("_q_stylepos").toInt(); if (!transient ||
int oldMin = styleObject->property("_q_stylemin").toInt(); oldPos != slider->sliderPosition ||
int oldMax = styleObject->property("_q_stylemax").toInt(); oldMin != slider->minimum ||
QRect oldRect = styleObject->property("_q_stylerect").toRect(); oldMax != slider->maximum ||
int oldState = styleObject->property("_q_stylestate").toInt(); oldRect != slider->rect ||
uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt(); oldState != slider->state ||
oldActiveControls != slider->activeSubControls) {
// a scrollbar is transient when the the scrollbar itself and styleObject->setProperty("_q_stylepos", slider->sliderPosition);
// its sibling are both inactive (ie. not pressed/hovered/moved) styleObject->setProperty("_q_stylemin", slider->minimum);
bool transient = !opt->activeSubControls && !(slider->state & State_On); styleObject->setProperty("_q_stylemax", slider->maximum);
styleObject->setProperty("_q_stylerect", slider->rect);
styleObject->setProperty("_q_stylestate", static_cast<int>(slider->state));
styleObject->setProperty("_q_stylecontrols", static_cast<uint>(slider->activeSubControls));
CGFloat opacity = 0.0; if (transient) {
if (!transient || QFadeOutAnimation *anim = qobject_cast<QFadeOutAnimation *>(d->animation(styleObject));
oldPos != slider->sliderPosition || if (!anim) {
oldMin != slider->minimum || anim = new QFadeOutAnimation(styleObject);
oldMax != slider->maximum || d->startAnimation(anim);
oldRect != slider->rect || } else {
oldState != slider->state || // the scrollbar was already fading out while the
oldActiveControls != slider->activeSubControls) { // state changed -> restart the fade out animation
anim->setCurrentTime(0);
// if the scrollbar is transient or its attributes, geometry or }
// state has changed, the opacity is reset back to 100% opaque
opacity = 1.0;
styleObject->setProperty("_q_stylepos", slider->sliderPosition);
styleObject->setProperty("_q_stylemin", slider->minimum);
styleObject->setProperty("_q_stylemax", slider->maximum);
styleObject->setProperty("_q_stylerect", slider->rect);
styleObject->setProperty("_q_stylestate", static_cast<int>(slider->state));
styleObject->setProperty("_q_stylecontrols", static_cast<uint>(slider->activeSubControls));
if (transient) {
QFadeOutAnimation *anim = qobject_cast<QFadeOutAnimation *>(d->animation(styleObject));
if (!anim) {
anim = new QFadeOutAnimation(styleObject);
d->startAnimation(anim);
} else { } else {
// the scrollbar was already fading out while the d->stopAnimation(styleObject);
// state changed -> restart the fade out animation
anim->setCurrentTime(0);
} }
} else {
d->stopAnimation(styleObject);
} }
}
QFadeOutAnimation *anim = qobject_cast<QFadeOutAnimation *>(d->animation(styleObject)); QFadeOutAnimation *anim = qobject_cast<QFadeOutAnimation *>(d->animation(styleObject));
if (anim) { if (anim) {
// once a scrollbar was active (hovered/pressed), it retains // once a scrollbar was active (hovered/pressed), it retains
// the active look even if it's no longer active while fading out // the active look even if it's no longer active while fading out
if (oldActiveControls) if (oldActiveControls)
anim->setActive(true); anim->setActive(true);
opacity = anim->currentValue();
wasActive = anim->wasActive();
opacity = anim->currentValue();
}
} }
const bool isHorizontal = slider->orientation == Qt::Horizontal; const bool isHorizontal = slider->orientation == Qt::Horizontal;
@ -5000,7 +4990,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
[scroller setScrollerStyle:NSScrollerStyleOverlay]; [scroller setScrollerStyle:NSScrollerStyleOverlay];
// first we draw only the track, by using a disabled scroller // first we draw only the track, by using a disabled scroller
if (opt->activeSubControls || (anim && anim->wasActive())) { if (opt->activeSubControls || wasActive) {
CGContextBeginTransparencyLayerWithRect(cg, qt_hirectForQRect(slider->rect), CGContextBeginTransparencyLayerWithRect(cg, qt_hirectForQRect(slider->rect),
NULL); NULL);
CGContextSetAlpha(cg, opacity); CGContextSetAlpha(cg, opacity);
@ -5050,10 +5040,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
[NSGraphicsContext restoreGraphicsState]; [NSGraphicsContext restoreGraphicsState];
CGContextRestoreGState(cg); CGContextRestoreGState(cg);
if (deleteStyleObject) {
delete styleObject;
}
} else } else
#endif #endif
{ {