fix Flat Button focus animation

This commit is contained in:
laserpants 2016-06-09 11:02:57 +03:00
parent 0d270024b8
commit a54da52665
4 changed files with 125 additions and 56 deletions

View File

@ -4,7 +4,6 @@
#include <QStylePainter> #include <QStylePainter>
#include <QStyleOption> #include <QStyleOption>
#include <QApplication> #include <QApplication>
#include <QDebug>
#include "lib/rippleoverlay.h" #include "lib/rippleoverlay.h"
#include "lib/ripple.h" #include "lib/ripple.h"
#include "flatbutton_p.h" #include "flatbutton_p.h"
@ -260,8 +259,9 @@ void FlatButton::paintEvent(QPaintEvent *event)
Q_D(FlatButton); Q_D(FlatButton);
const qreal bgOpacity = d->delegate->backgroundOpacity(); const qreal bgOpacity = d->delegate->backgroundOpacity();
const qreal haloOpacity = d->delegate->focusHaloOpacity(); const qreal haloOpacity = d->delegate->haloOpacity();
const qreal hs = static_cast<qreal>(width())*d->delegate->focusHaloSize()/2; const qreal s = d->delegate->haloScaleFactor()*d->delegate->haloSize()*0.7;
const qreal hs = static_cast<qreal>(width())*s;
const qreal cr = d->cornerRadius; const qreal cr = d->cornerRadius;
QPainter painter(this); QPainter painter(this);

View File

@ -4,30 +4,52 @@
#include <QSignalTransition> #include <QSignalTransition>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QSequentialAnimationGroup> #include <QSequentialAnimationGroup>
#include <QFocusEvent>
#include "flatbutton.h" #include "flatbutton.h"
FlatButtonDelegate::FlatButtonDelegate(FlatButton *parent) FlatButtonDelegate::FlatButtonDelegate(FlatButton *parent)
: QStateMachine(parent), : QStateMachine(parent),
button(parent), button(parent),
_normalState(new QState(this)), _normalState(new QState),
_normalFocusedState(new QState(this)), _normalFocusedState(new QState),
_hoveredState(new QState(this)), _hoveredState(new QState),
_hoveredFocusedState(new QState(this)), _hoveredFocusedState(new QState),
_pressedState(new QState(this)), _pressedState(new QState),
_releaseState(new QState(this)), _haloSize(0.8),
_focusHaloSize(0.8) _haloScaleFactor(1)
{ {
button->installEventFilter(this);
addState(_normalState);
addState(_normalFocusedState);
addState(_hoveredState);
addState(_hoveredFocusedState);
addState(_pressedState);
setInitialState(_normalState); setInitialState(_normalState);
addTransition(QEvent::Enter, _normalFocusedState, _hoveredFocusedState); addTransition(button, QEvent::FocusIn, _normalState, _normalFocusedState);
addTransition(QEvent::FocusIn, _normalState, _normalFocusedState); addTransition(button, QEvent::FocusOut, _normalFocusedState, _normalState);
addTransition(QEvent::FocusOut, _normalFocusedState, _normalState);
addTransition(QEvent::Enter, _normalState, _hoveredState); addTransition(button, QEvent::Enter, _normalState, _hoveredState);
addTransition(QEvent::Leave, _hoveredFocusedState, _normalFocusedState); addTransition(button, QEvent::Leave, _hoveredState, _normalState);
addTransition(QEvent::Leave, _hoveredState, _normalState);
addTransition(QEvent::MouseButtonPress, _hoveredState, _pressedState); addTransition(button, QEvent::Enter, _normalFocusedState, _hoveredFocusedState);
addTransition(QEvent::MouseButtonRelease, _pressedState, _releaseState); addTransition(button, QEvent::Leave, _hoveredFocusedState, _normalFocusedState);
addTransition(QEvent::Leave, _releaseState, _normalFocusedState);
addTransition(button, QEvent::FocusIn, _hoveredState, _hoveredFocusedState);
addTransition(button, QEvent::FocusOut, _hoveredFocusedState, _hoveredState);
addTransition(this, SIGNAL(pressed()), _hoveredState, _pressedState);
addTransition(button, QEvent::Leave, _pressedState, _normalFocusedState);
addTransition(button, QEvent::FocusOut, _pressedState, _hoveredState);
_normalFocusedState->assignProperty(this, "haloSize", 0.7);
_normalState->assignProperty(this, "haloSize", 1);
_hoveredState->assignProperty(this, "haloSize", 1);
_hoveredFocusedState->assignProperty(this, "haloSize", 0.7);
//
QSequentialAnimationGroup *group = new QSequentialAnimationGroup(this); QSequentialAnimationGroup *group = new QSequentialAnimationGroup(this);
@ -35,14 +57,14 @@ FlatButtonDelegate::FlatButtonDelegate(FlatButton *parent)
QPropertyAnimation *shrink = new QPropertyAnimation; QPropertyAnimation *shrink = new QPropertyAnimation;
grow->setTargetObject(this); grow->setTargetObject(this);
grow->setPropertyName("focusHaloSize"); grow->setPropertyName("haloScaleFactor");
grow->setStartValue(0.8); grow->setStartValue(0.8);
grow->setEndValue(0.9); grow->setEndValue(0.9);
grow->setEasingCurve(QEasingCurve::InOutSine); grow->setEasingCurve(QEasingCurve::InOutSine);
grow->setDuration(840); grow->setDuration(840);
shrink->setTargetObject(this); shrink->setTargetObject(this);
shrink->setPropertyName("focusHaloSize"); shrink->setPropertyName("haloScaleFactor");
shrink->setStartValue(0.9); shrink->setStartValue(0.9);
shrink->setEndValue(0.8); shrink->setEndValue(0.8);
shrink->setEasingCurve(QEasingCurve::InOutSine); shrink->setEasingCurve(QEasingCurve::InOutSine);
@ -82,26 +104,37 @@ QColor FlatButtonDelegate::backgroundColor() const
return _backgroundColor; return _backgroundColor;
} }
void FlatButtonDelegate::setFocusHaloOpacity(qreal opacity) void FlatButtonDelegate::setHaloOpacity(qreal opacity)
{ {
_focusHaloOpacity = opacity; _haloOpacity = opacity;
button->update(); button->update();
} }
qreal FlatButtonDelegate::focusHaloOpacity() const qreal FlatButtonDelegate::haloOpacity() const
{ {
return _focusHaloOpacity; return _haloOpacity;
} }
void FlatButtonDelegate::setFocusHaloSize(qreal size) void FlatButtonDelegate::setHaloSize(qreal size)
{ {
_focusHaloSize = size; _haloSize = size;
button->update(); button->update();
} }
qreal FlatButtonDelegate::focusHaloSize() const qreal FlatButtonDelegate::haloSize() const
{ {
return _focusHaloSize; return _haloSize;
}
void FlatButtonDelegate::setHaloScaleFactor(qreal size)
{
_haloScaleFactor = size;
button->update();
}
qreal FlatButtonDelegate::haloScaleFactor() const
{
return _haloScaleFactor;
} }
void FlatButtonDelegate::updatePalette() void FlatButtonDelegate::updatePalette()
@ -118,36 +151,55 @@ void FlatButtonDelegate::updatePalette()
_normalState->assignProperty(this, "backgroundOpacity", 0); _normalState->assignProperty(this, "backgroundOpacity", 0);
_normalState->assignProperty(this, "backgroundColor", bgColor); _normalState->assignProperty(this, "backgroundColor", bgColor);
_normalState->assignProperty(this, "focusHaloOpacity", 0); _normalState->assignProperty(this, "haloOpacity", 0);
_normalFocusedState->assignProperty(this, "backgroundOpacity", 0); _normalFocusedState->assignProperty(this, "backgroundOpacity", 0);
_normalFocusedState->assignProperty(this, "backgroundColor", bgColor); _normalFocusedState->assignProperty(this, "backgroundColor", bgColor);
_normalFocusedState->assignProperty(this, "focusHaloOpacity", button->peakOpacity()); _normalFocusedState->assignProperty(this, "haloOpacity", button->peakOpacity());
_hoveredState->assignProperty(this, "backgroundOpacity", button->peakOpacity()); _hoveredState->assignProperty(this, "backgroundOpacity", button->peakOpacity());
_hoveredState->assignProperty(this, "backgroundColor", bgColor); _hoveredState->assignProperty(this, "backgroundColor", bgColor);
_hoveredState->assignProperty(this, "focusHaloOpacity", 0); _hoveredState->assignProperty(this, "haloOpacity", 0);
_hoveredFocusedState->assignProperty(this, "backgroundOpacity", button->peakOpacity()); _hoveredFocusedState->assignProperty(this, "backgroundOpacity", button->peakOpacity());
_hoveredFocusedState->assignProperty(this, "backgroundColor", bgColor); _hoveredFocusedState->assignProperty(this, "backgroundColor", bgColor);
_normalFocusedState->assignProperty(this, "focusHaloOpacity", button->peakOpacity()); _hoveredFocusedState->assignProperty(this, "haloOpacity", button->peakOpacity());
_pressedState->assignProperty(this, "backgroundOpacity", 0);
_pressedState->assignProperty(this, "backgroundColor", bgColor);
_pressedState->assignProperty(this, "focusHaloOpacity", 0);
_releaseState->assignProperty(this, "backgroundOpacity", 0);
_releaseState->assignProperty(this, "backgroundColor", bgColor);
_releaseState->assignProperty(this, "focusHaloOpacity", 0);
button->update(); button->update();
} }
void FlatButtonDelegate::addTransition(QEvent::Type eventType, bool FlatButtonDelegate::eventFilter(QObject *watched, QEvent *event)
{
if (QEvent::FocusIn == event->type()) {
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
if (focusEvent && Qt::MouseFocusReason == focusEvent->reason()) {
emit pressed();
return true;
}
}
return QStateMachine::eventFilter(watched, event);
}
void FlatButtonDelegate::addTransition(QObject *object,
const char *signal,
QState *fromState,
QState *toState)
{
addTransition(new QSignalTransition(object, signal), fromState, toState);
}
void FlatButtonDelegate::addTransition(QObject *object,
QEvent::Type eventType,
QState *fromState,
QState *toState)
{
addTransition(new QEventTransition(object, eventType), fromState, toState);
}
void FlatButtonDelegate::addTransition(QAbstractTransition *transition,
QState *fromState, QState *fromState,
QState *toState) QState *toState)
{ {
QAbstractTransition *transition = new QEventTransition(button, eventType);
transition->setTargetState(toState); transition->setTargetState(toState);
QPropertyAnimation *animation; QPropertyAnimation *animation;
@ -160,7 +212,11 @@ void FlatButtonDelegate::addTransition(QEvent::Type eventType,
animation->setDuration(200); animation->setDuration(200);
transition->addAnimation(animation); transition->addAnimation(animation);
animation = new QPropertyAnimation(this, "focusHaloOpacity"); animation = new QPropertyAnimation(this, "haloOpacity");
animation->setDuration(350);
transition->addAnimation(animation);
animation = new QPropertyAnimation(this, "haloSize");
animation->setDuration(350); animation->setDuration(350);
transition->addAnimation(animation); transition->addAnimation(animation);

View File

@ -13,8 +13,9 @@ class FlatButtonDelegate : public QStateMachine
Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor)
Q_PROPERTY(qreal backgroundOpacity WRITE setBackgroundOpacity READ backgroundOpacity) Q_PROPERTY(qreal backgroundOpacity WRITE setBackgroundOpacity READ backgroundOpacity)
Q_PROPERTY(qreal focusHaloOpacity WRITE setFocusHaloOpacity READ focusHaloOpacity) Q_PROPERTY(qreal haloOpacity WRITE setHaloOpacity READ haloOpacity)
Q_PROPERTY(qreal focusHaloSize WRITE setFocusHaloSize READ focusHaloSize) Q_PROPERTY(qreal haloSize WRITE setHaloSize READ haloSize)
Q_PROPERTY(qreal haloScaleFactor WRITE setHaloScaleFactor READ haloScaleFactor)
public: public:
FlatButtonDelegate(FlatButton *parent); FlatButtonDelegate(FlatButton *parent);
@ -26,18 +27,29 @@ public:
void setBackgroundColor(const QColor &color); void setBackgroundColor(const QColor &color);
QColor backgroundColor() const; QColor backgroundColor() const;
void setFocusHaloOpacity(qreal opacity); void setHaloOpacity(qreal opacity);
qreal focusHaloOpacity() const; qreal haloOpacity() const;
void setFocusHaloSize(qreal size); void setHaloSize(qreal size);
qreal focusHaloSize() const; qreal haloSize() const;
void setHaloScaleFactor(qreal size);
qreal haloScaleFactor() const;
void updatePalette(); void updatePalette();
signals:
void pressed();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private: private:
Q_DISABLE_COPY(FlatButtonDelegate) Q_DISABLE_COPY(FlatButtonDelegate)
void addTransition(QEvent::Type eventType, QState *fromState, QState *toState); void addTransition(QObject *object, const char *signal, QState *fromState, QState *toState);
void addTransition(QObject *object, QEvent::Type eventType, QState *fromState, QState *toState);
void addTransition(QAbstractTransition *transition, QState *fromState, QState *toState);
FlatButton *const button; FlatButton *const button;
QState *const _normalState; QState *const _normalState;
@ -45,10 +57,10 @@ private:
QState *const _hoveredState; QState *const _hoveredState;
QState *const _hoveredFocusedState; QState *const _hoveredFocusedState;
QState *const _pressedState; QState *const _pressedState;
QState *const _releaseState;
qreal _backgroundOpacity; qreal _backgroundOpacity;
qreal _focusHaloOpacity; qreal _haloOpacity;
qreal _focusHaloSize; qreal _haloSize;
qreal _haloScaleFactor;
QColor _backgroundColor; QColor _backgroundColor;
}; };

View File

@ -145,8 +145,9 @@ void RaisedButton::paintEvent(QPaintEvent *event)
painter.drawRoundedRect(rect(), cr, cr); painter.drawRoundedRect(rect(), cr, cr);
if (isEnabled()) { if (isEnabled()) {
const qreal hs = static_cast<qreal>(width())*d->delegate->focusHaloSize()/2; const qreal s = d->delegate->haloScaleFactor()*d->delegate->haloSize()*0.7;
const qreal haloOpacity = d->delegate->focusHaloOpacity(); const qreal hs = static_cast<qreal>(width())*s;
const qreal haloOpacity = d->delegate->haloOpacity();
brush.setColor(palette().color(QPalette::Active, QPalette::ButtonText)); brush.setColor(palette().color(QPalette::Active, QPalette::ButtonText));
painter.setBrush(brush); painter.setBrush(brush);