From: Gabriel de Dietrich Date: Mon, 3 Dec 2012 18:00:03 +0000 (+0100) Subject: Mac: Animated expanding scrollbars on 10.8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6f7791f871df300db27104b65d43c17ce825d733;p=profile%2Fivi%2Fqtbase.git Mac: Animated expanding scrollbars on 10.8 Change-Id: Ib57d0347a7828ac7582b0fa95adf8d437694cd41 Reviewed-by: Richard Moe Gustavsen --- diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index ba34a74..649e7f2 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -2181,11 +2181,11 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW switch (d->aquaSizeConstrain(opt, widget)) { case QAquaSizeUnknown: case QAquaSizeLarge: - ret = 9; + ret = QSysInfo::macVersion() >= QSysInfo::MV_10_8 ? 16 : 9; break; case QAquaSizeMini: case QAquaSizeSmall: - ret = 7; + ret = QSysInfo::macVersion() >= QSysInfo::MV_10_8 ? 14 : 7; break; } break; @@ -4909,6 +4909,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex if (cc == CC_ScrollBar && proxy()->styleHint(SH_ScrollBar_Transient)) { bool wasActive = false; CGFloat opacity = 1.0; + CGFloat expandScale = 1.0; + CGFloat expandOffset = -1.0; + bool shouldExpand = false; + const CGFloat maxExpandScale = tdi.kind == kThemeSmallScrollBar ? 11.0 / 7.0 : 13.0 / 9.0; + if (QObject *styleObject = opt->styleObject) { int oldPos = styleObject->property("_q_stylepos").toInt(); int oldMin = styleObject->property("_q_stylemin").toInt(); @@ -4936,23 +4941,24 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex styleObject->setProperty("_q_stylestate", static_cast(slider->state)); styleObject->setProperty("_q_stylecontrols", static_cast(slider->activeSubControls)); + QScrollbarAnimation *anim = qobject_cast(d->animation(styleObject)); if (transient) { - QFadeOutAnimation *anim = qobject_cast(d->animation(styleObject)); if (!anim) { - anim = new QFadeOutAnimation(styleObject); + anim = new QScrollbarAnimation(styleObject); + anim->setFadingOut(); d->startAnimation(anim); - } else { + } else if (anim->isFadingOut()) { // the scrollbar was already fading out while the // state changed -> restart the fade out animation anim->setCurrentTime(0); } - } else { + } else if (anim && anim->isFadingOut()) { d->stopAnimation(styleObject); } } - QFadeOutAnimation *anim = qobject_cast(d->animation(styleObject)); - if (anim) { + QScrollbarAnimation *anim = qobject_cast(d->animation(styleObject)); + if (anim && anim->isFadingOut()) { // once a scrollbar was active (hovered/pressed), it retains // the active look even if it's no longer active while fading out if (oldActiveControls) @@ -4961,6 +4967,24 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex wasActive = anim->wasActive(); opacity = anim->currentValue(); } + + shouldExpand = (opt->activeSubControls || wasActive) && QSysInfo::macVersion() >= QSysInfo::MV_10_8; + if (shouldExpand) { + if (!anim && !oldActiveControls) { + // Start expand animation only once and when entering + anim = new QScrollbarAnimation(styleObject); + anim->setExpanding(); + d->startAnimation(anim); + } + if (anim && !anim->isFadingOut()) { + expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue(); + expandOffset = 5.5 * anim->currentValue() - 1; + } else { + // Keep expanded state after the animation ends, and when fading out + expandScale = maxExpandScale; + expandOffset = 4.5; + } + } } const bool isHorizontal = slider->orientation == Qt::Horizontal; @@ -4985,29 +5009,27 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex [scroller setBounds:NSMakeRect(0, 0, slider->rect.width(), slider->rect.height())]; [scroller setScrollerStyle:NSScrollerStyleOverlay]; - // first we draw only the track, by using a disabled scroller - if (opt->activeSubControls || wasActive) { - CGContextBeginTransparencyLayerWithRect(cg, qt_hirectForQRect(slider->rect), - NULL); - CGContextSetAlpha(cg, opacity); - - [scroller setFrame:[scroller bounds]]; - [scroller setEnabled:(slider->state & State_Enabled) ? YES : NO]; - [scroller drawKnobSlotInRect:[scroller bounds] highlight:NO]; + CGContextBeginTransparencyLayer(cg, NULL); + CGContextSetAlpha(cg, opacity); - CGContextEndTransparencyLayer(cg); + // Draw the track when hovering + if (opt->activeSubControls || wasActive) { + CGRect rect = [scroller bounds]; + if (shouldExpand) { + if (isHorizontal) + rect.origin.y += 4.5 - expandOffset; + else + rect.origin.x += 4.5 - expandOffset; + } + [scroller drawKnobSlotInRect:rect highlight:YES]; } - CGContextBeginTransparencyLayerWithRect(cg, qt_hirectForQRect(slider->rect), NULL); - CGContextSetAlpha(cg, opacity); - const qreal length = slider->maximum - slider->minimum + slider->pageStep; const qreal proportion = slider->pageStep / length; qreal value = (slider->sliderValue - slider->minimum) / length; if (isHorizontal && slider->direction == Qt::RightToLeft) value = 1.0 - value - proportion; - [scroller setEnabled:(slider->state & State_Enabled) ? YES : NO]; [scroller setKnobProportion:1.0]; const int minKnobWidth = 26; @@ -5017,13 +5039,23 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex const qreal width = qMax(minKnobWidth, plannedWidth); const qreal totalWidth = slider->rect.width() + plannedWidth - width; [scroller setFrame:NSMakeRect(0, 0, width, slider->rect.height())]; - CGContextTranslateCTM(cg, value * totalWidth, 1); + if (shouldExpand) { + CGContextScaleCTM(cg, 1, expandScale); + CGContextTranslateCTM(cg, value * totalWidth, -expandOffset); + } else { + CGContextTranslateCTM(cg, value * totalWidth, 1); + } } else { const qreal plannedHeight = proportion * slider->rect.height(); const qreal height = qMax(minKnobWidth, plannedHeight); const qreal totalHeight = slider->rect.height() + plannedHeight - height; [scroller setFrame:NSMakeRect(0, 0, slider->rect.width(), height)]; - CGContextTranslateCTM(cg, 1, value * totalHeight); + if (shouldExpand) { + CGContextScaleCTM(cg, expandScale, 1); + CGContextTranslateCTM(cg, -expandOffset, value * totalHeight); + } else { + CGContextTranslateCTM(cg, 1, value * totalHeight); + } } if (length > 0.0) { [scroller layout]; diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index c2e5a02..a23c45f 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -211,32 +211,47 @@ public: #endif }; -class QFadeOutAnimation : public QNumberStyleAnimation +class QScrollbarAnimation : public QNumberStyleAnimation { Q_OBJECT public: - QFadeOutAnimation(QObject *target) : QNumberStyleAnimation(target), _active(false) + QScrollbarAnimation(QObject *target) : QNumberStyleAnimation(target), _active(false) + { } + + bool wasActive() const { return _active; } + void setActive(bool active) { _active = active; } + + bool isFadingOut() const { return _isFadingOut; } + + void setFadingOut() { + _isFadingOut = true; setDuration(QMacStylePrivate::ScrollBarFadeOutDelay + QMacStylePrivate::ScrollBarFadeOutDuration); setDelay(QMacStylePrivate::ScrollBarFadeOutDelay); setStartValue(1.0); setEndValue(0.0); } - bool wasActive() const { return _active; } - void setActive(bool active) { _active = active; } + void setExpanding() + { + _isFadingOut = false; + setDuration(QMacStylePrivate::ScrollBarFadeOutDuration); + setStartValue(0.0); + setEndValue(1.0); + } private slots: void updateCurrentTime(int time) { QNumberStyleAnimation::updateCurrentTime(time); - if (qFuzzyIsNull(currentValue())) + if (_isFadingOut && qFuzzyIsNull(currentValue())) target()->setProperty("visible", false); } private: bool _active; + bool _isFadingOut; }; QT_END_NAMESPACE