summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@digia.com>2012-10-22 19:27:05 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-25 14:10:04 +0200
commitd58161e749348a9e11e063b1bbb3dbbc0aa46c5e (patch)
tree23bf68c4e451fabe22afb437918d146db8ee6b7b /src
parent6e908f09dfc19be3cbbf38628c63c348c5172e53 (diff)
QMacStyle: make default button animations independent of QWidget
Change-Id: I63c078050288e3151a9c6aad5d4ae28a58afd84f Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm168
-rw-r--r--src/widgets/styles/qmacstyle_mac_p.h8
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp2
-rw-r--r--src/widgets/widgets/qpushbutton.cpp2
4 files changed, 65 insertions, 115 deletions
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 2b6f271a40..a227e06d77 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1683,46 +1683,6 @@ QMacStylePrivate::QMacStylePrivate()
}
-bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QObject *obj) const
-{
- if (!obj)
- return false;
-
- if (as == AquaPushButton) {
- QPushButton *pb = const_cast<QPushButton *>(qobject_cast<const QPushButton *>(obj));
- if (pb && pb->window()->isActiveWindow() && !mouseDown) {
- if (pb != defaultButton) {
- // Changed on its own, update the value.
- const_cast<QMacStylePrivate *>(this)->stopAnimate(as, defaultButton);
- const_cast<QMacStylePrivate *>(this)->startAnimate(as, pb);
- }
- return true;
- }
- }
- return animation(obj);
-}
-
-void QMacStylePrivate::stopAnimate(QMacStylePrivate::Animates as, QObject *obj)
-{
- stopAnimation(obj);
- if (as == AquaPushButton && defaultButton) {
- stopAnimation(defaultButton);
- QPushButton *tmp = defaultButton;
- defaultButton = 0;
- tmp->update();
- } else if (as == AquaScrollBar) {
- scrollBarInfos.remove(qobject_cast<QWidget*>(obj));
- }
-}
-
-void QMacStylePrivate::startAnimate(QMacStylePrivate::Animates as, QObject *obj)
-{
- if (!animation(obj))
- startAnimation(new QStyleAnimation(obj));
- if (as == AquaPushButton)
- defaultButton = qobject_cast<QPushButton *>(obj);
-}
-
bool QMacStylePrivate::addWidget(QWidget *w)
{
//already knew of it
@@ -1730,17 +1690,9 @@ bool QMacStylePrivate::addWidget(QWidget *w)
return false;
Q_Q(QMacStyle);
- if (QPushButton *btn = qobject_cast<QPushButton *>(w)) {
- btn->installEventFilter(q);
- if (btn->isDefault() || (btn->autoDefault() && btn->hasFocus()))
- startAnimate(AquaPushButton, btn);
+ if (qobject_cast<QScrollBar *>(w)) {
+ w->installEventFilter(q);
return true;
- } else {
- bool isScrollBar = (qobject_cast<QScrollBar *>(w));
- if (isScrollBar) {
- w->installEventFilter(q);
- return true;
- }
}
if (w->isWindow()) {
w->installEventFilter(q);
@@ -1749,16 +1701,6 @@ bool QMacStylePrivate::addWidget(QWidget *w)
return false;
}
-void QMacStylePrivate::removeWidget(QWidget *w)
-{
- QPushButton *btn = qobject_cast<QPushButton *>(w);
- if (btn && btn == defaultButton) {
- stopAnimate(AquaPushButton, btn);
- } else if (qobject_cast<QScrollBar *>(w)) {
- stopAnimate(AquaScrollBar, w);
- }
-}
-
ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
{
ThemeDrawState tds = kThemeStateActive;
@@ -1839,49 +1781,6 @@ bool QMacStyle::eventFilter(QObject *o, QEvent *e)
}
}
#endif
- } else if (QPushButton *btn = qobject_cast<QPushButton *>(o)) {
- switch (e->type()) {
- default:
- break;
- case QEvent::FocusIn:
- if (btn->autoDefault())
- d->startAnimate(QMacStylePrivate::AquaPushButton, btn);
- break;
- case QEvent::Destroy:
- case QEvent::Hide:
- if (btn == d->defaultButton)
- d->stopAnimate(QMacStylePrivate::AquaPushButton, btn);
- break;
- case QEvent::MouseButtonPress:
- // It is very confusing to keep the button pulsing, so just stop the animation.
- if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
- d->mouseDown = true;
- d->stopAnimate(QMacStylePrivate::AquaPushButton, btn);
- break;
- case QEvent::MouseButtonRelease:
- if (static_cast<QMouseEvent *>(e)->button() == Qt::LeftButton)
- d->mouseDown = false;
- // fall through
- case QEvent::FocusOut:
- case QEvent::Show:
- case QEvent::WindowActivate: {
- QList<QPushButton *> list = btn->window()->findChildren<QPushButton *>();
- for (int i = 0; i < list.size(); ++i) {
- QPushButton *pBtn = list.at(i);
- if ((e->type() == QEvent::FocusOut
- && (pBtn->isDefault() || (pBtn->autoDefault() && pBtn->hasFocus()))
- && pBtn != btn)
- || ((e->type() == QEvent::Show || e->type() == QEvent::MouseButtonRelease
- || e->type() == QEvent::WindowActivate)
- && pBtn->isDefault())) {
- if (pBtn->window()->isActiveWindow()) {
- d->startAnimate(QMacStylePrivate::AquaPushButton, pBtn);
- }
- break;
- }
- }
- break; }
- }
}
return false;
}
@@ -2172,7 +2071,6 @@ void QMacStyle::polish(QWidget* w)
void QMacStyle::unpolish(QWidget* w)
{
Q_D(QMacStyle);
- d->removeWidget(w);
if ((qobject_cast<QMenu*>(w) || qt_mac_is_metal(w)) && !w->testAttribute(Qt::WA_SetPalette)) {
QPalette pal = qApp->palette(w);
w->setPalette(pal);
@@ -2201,6 +2099,7 @@ void QMacStyle::unpolish(QWidget* w)
if (qobject_cast<QScrollBar*>(w)) {
w->setAttribute(Qt::WA_OpaquePaintEvent, true);
w->setMouseTracking(false);
+ d->scrollBarInfos.remove(w);
}
}
@@ -3633,13 +3532,64 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
break;
}
+ // a focused auto-default button within an active window
+ // takes precedence over a normal default button
+ if (btn->features & QStyleOptionButton::AutoDefaultButton
+ && opt->state & State_Active && opt->state & State_HasFocus) {
+ d->autoDefaultButton = opt->styleObject;
+ if (!d->animation(opt->styleObject))
+ d->startAnimation(new QStyleAnimation(opt->styleObject));
+ } else if (d->autoDefaultButton == opt->styleObject) {
+ if (QStyleAnimation *animation = d->animation(opt->styleObject)) {
+ animation->updateTarget();
+ d->stopAnimation(opt->styleObject);
+ }
+ d->autoDefaultButton = 0;
+ }
+
+ if (!d->autoDefaultButton) {
+ if (btn->features & QStyleOptionButton::DefaultButton && opt->state & State_Active) {
+ d->defaultButton = opt->styleObject;
+ if (!d->animation(opt->styleObject))
+ d->startAnimation(new QStyleAnimation(opt->styleObject));
+ } else if (d->defaultButton == opt->styleObject) {
+ if (QStyleAnimation *animation = d->animation(opt->styleObject)) {
+ animation->updateTarget();
+ d->stopAnimation(opt->styleObject);
+ }
+ d->defaultButton = 0;
+ }
+ }
+
+ // TODO: find out the pressed button in a qwidget independent way
+ extern QWidget *qt_button_down; // qwidgetwindow.cpp
+ if (opt->styleObject == qt_button_down)
+ d->pressedButton = opt->styleObject;
+ else if (d->pressedButton == opt->styleObject)
+ d->pressedButton = 0;
+
+ // the default button animation is paused meanwhile any button
+ // is pressed or an auto-default button is animated instead
+ if (QStyleAnimation *defaultAnimation = d->animation(d->defaultButton)) {
+ if (d->pressedButton || d->autoDefaultButton) {
+ if (defaultAnimation->state() == QStyleAnimation::Running) {
+ defaultAnimation->pause();
+ defaultAnimation->updateTarget();
+ }
+ } else if (defaultAnimation->state() == QStyleAnimation::Paused) {
+ defaultAnimation->resume();
+ }
+ }
+
HIThemeButtonDrawInfo bdi;
d->initHIThemePushButton(btn, w, tds, &bdi);
- if (btn->features & QStyleOptionButton::DefaultButton
- && d->animatable(QMacStylePrivate::AquaPushButton, w)) {
- bdi.adornment |= kThemeAdornmentDefault;
- bdi.animation.time.start = d->defaultButtonStart;
- bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
+ if (!d->pressedButton) {
+ QStyleAnimation* animation = d->animation(opt->styleObject);
+ if (animation && animation->state() == QStyleAnimation::Running) {
+ bdi.adornment |= kThemeAdornmentDefault;
+ bdi.animation.time.start = d->defaultButtonStart;
+ bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
+ }
}
// 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,
diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h
index 66691c63f7..ec6f7c75b4 100644
--- a/src/widgets/styles/qmacstyle_mac_p.h
+++ b/src/widgets/styles/qmacstyle_mac_p.h
@@ -160,12 +160,8 @@ public:
// Stuff from QAquaAnimate:
bool addWidget(QWidget *);
- void removeWidget(QWidget *);
enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen, AquaScrollBar };
- bool animatable(Animates, const QObject *) const;
- void stopAnimate(Animates, QObject *);
- void startAnimate(Animates, QObject *);
static ThemeDrawState getDrawState(QStyle::State flags);
QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
QStyle::ContentsType ct = QStyle::CT_CustomBase,
@@ -201,7 +197,9 @@ public:
QPixmap generateBackgroundPattern() const;
public:
- QPointer<QPushButton> defaultButton; //default push buttons
+ mutable QPointer<QObject> pressedButton;
+ mutable QPointer<QObject> defaultButton;
+ mutable QPointer<QObject> autoDefaultButton;
struct OverlayScrollBarInfo {
OverlayScrollBarInfo()
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
index 5d879c8930..eba63045fe 100644
--- a/src/widgets/widgets/qabstractbutton.cpp
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -1113,6 +1113,8 @@ void QAbstractButton::mouseReleaseEvent(QMouseEvent *e)
}
if (!d->down) {
+ // refresh is required by QMacStyle to resume the default button animation
+ d->refresh();
e->ignore();
return;
}
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index 5e8d7d16bd..0aeec551d6 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -329,7 +329,7 @@ void QPushButton::initStyleOption(QStyleOptionButton *option) const
if (d->menu)
option->features |= QStyleOptionButton::HasMenu;
#endif
- if (autoDefault() || d->defaultButton)
+ if (autoDefault())
option->features |= QStyleOptionButton::AutoDefaultButton;
if (d->defaultButton)
option->features |= QStyleOptionButton::DefaultButton;