implement toggle animations

This commit is contained in:
laserpants 2016-05-29 22:12:02 +03:00
parent e51251408b
commit a6bef3d327
5 changed files with 198 additions and 53 deletions

View File

@ -4,11 +4,15 @@
#include <QSignalTransition>
#include <QPropertyAnimation>
#include "lib/rippleoverlay.h"
#include "lib/ripple.h"
#include "lib/style.h"
#include "toggle_p.h"
#include "toggle_internal.h"
TogglePrivate::TogglePrivate(Toggle *q)
: q_ptr(q),
thumb(new Thumb(q)),
track(new ToggleTrack(q)),
thumb(new ToggleThumb(q)),
ripple(new RippleOverlay(q->parentWidget())),
orientation(Qt::Horizontal)
{
@ -34,36 +38,76 @@ void TogglePrivate::init()
//
transition = new QSignalTransition(thumb, SIGNAL(clicked()));
transition = new QSignalTransition(thumb, SIGNAL(clicked(bool)));
transition->setTargetState(onState);
offState->addTransition(transition);
animation = new QPropertyAnimation;
animation->setPropertyName("shift");
animation->setTargetObject(thumb);
animation->setDuration(200);
animation->setEasingCurve(QEasingCurve::OutQuad);
transition->addAnimation(animation);
animation = new QPropertyAnimation;
animation->setPropertyName("trackColor");
animation->setTargetObject(track);
animation->setDuration(150);
transition->addAnimation(animation);
//
transition = new QSignalTransition(thumb, SIGNAL(clicked()));
transition->setTargetState(offState);
onState->addTransition(transition);
animation = new QPropertyAnimation;
animation->setPropertyName("shift");
animation->setPropertyName("thumbColor");
animation->setTargetObject(thumb);
animation->setDuration(150);
transition->addAnimation(animation);
//
transition = new QSignalTransition(thumb, SIGNAL(clicked(bool)));
transition->setTargetState(offState);
onState->addTransition(transition);
animation = new QPropertyAnimation;
animation->setPropertyName("shift");
animation->setTargetObject(thumb);
animation->setDuration(200);
animation->setEasingCurve(QEasingCurve::OutQuad);
transition->addAnimation(animation);
animation = new QPropertyAnimation;
animation->setPropertyName("trackColor");
animation->setTargetObject(track);
animation->setDuration(150);
transition->addAnimation(animation);
animation = new QPropertyAnimation;
animation->setPropertyName("thumbColor");
animation->setTargetObject(thumb);
animation->setDuration(150);
transition->addAnimation(animation);
//
const Style &style = Style::instance();
offState->assignProperty(thumb, "shift", 0);
onState->assignProperty(thumb, "shift", 1);
QColor trackOnColor = style.themeColor("primary1");
trackOnColor.setAlpha(100);
QColor trackOffColor = style.themeColor("accent3");
trackOffColor.setAlpha(170);
offState->assignProperty(track, "trackColor", trackOffColor);
onState->assignProperty(track, "trackColor", trackOnColor);
offState->assignProperty(thumb, "thumbColor", style.themeColor("canvas"));
onState->assignProperty(thumb, "thumbColor", style.themeColor("primary1"));
machine.start();
QObject::connect(thumb, SIGNAL(clicked()), q, SLOT(addRipple()));
QObject::connect(thumb, SIGNAL(clicked(bool)), q, SLOT(addRipple(bool)));
}
Toggle::Toggle(QWidget *parent)
@ -114,19 +158,28 @@ void Toggle::updateOverlayGeometry()
}
}
void Toggle::addRipple()
void Toggle::addRipple(bool checked)
{
Q_D(Toggle);
int t, w;
if (Qt::Horizontal == d->orientation) {
const int t = height()/2;
const int w = d->thumb->height()/2+10;
d->ripple->addRipple(QPoint(10+t, 20+t), w);
t = height()/2;
w = d->thumb->height()/2+10;
} else {
const int t = width()/2;
const int w = d->thumb->width()/2+10;
d->ripple->addRipple(QPoint(10+t, 20+t), w);
t = width()/2;
w = d->thumb->width()/2+10;
}
Ripple *ripple = new Ripple(QPoint(10+t, 20+t));
ripple->setColor(Style::instance().themeColor(checked
? "primary2"
: "accent3"));
ripple->setRadiusEndValue(w);
ripple->setOpacityStartValue(0.4);
d->ripple->addRipple(ripple);
}
bool Toggle::event(QEvent *event)
@ -153,25 +206,15 @@ void Toggle::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
Q_D(Toggle);
#ifdef DEBUG_LAYOUT
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QBrush brush;
brush.setColor(QColor(180, 180, 180));
brush.setStyle(Qt::SolidPattern);
painter.setBrush(brush);
painter.setPen(Qt::NoPen);
if (Qt::Horizontal == d->orientation) {
const int h = height()/2;
const QRect r(0, h/2, width(), h);
painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h/2-4, h/2-4);
} else {
const int w = width()/2;
const QRect r(w/2, 0, w, height());
painter.drawRoundedRect(r.adjusted(4, 14, -4, -14), w/2-4, w/2-4);
}
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(1);
painter.setOpacity(1);
painter.setPen(pen);
painter.setBrush(Qt::NoBrush);
painter.drawRect(rect().adjusted(0, 0, -1, -1));
#endif
}

View File

@ -21,7 +21,7 @@ public:
void updateOverlayGeometry();
protected slots:
void addRipple();
void addRipple(bool checked);
protected:
bool event(QEvent *event) Q_DECL_OVERRIDE;

View File

@ -1,10 +1,11 @@
#include <QPainter>
#include <QEvent>
#include <QGraphicsDropShadowEffect>
#include "lib/style.h"
#include "toggle_internal.h"
#include "toggle.h"
Thumb::Thumb(Toggle *parent)
ToggleThumb::ToggleThumb(Toggle *parent)
: QWidget(parent),
_toggle(parent),
_shift(0),
@ -21,11 +22,11 @@ Thumb::Thumb(Toggle *parent)
setGraphicsEffect(effect);
}
Thumb::~Thumb()
ToggleThumb::~ToggleThumb()
{
}
void Thumb::setShift(qreal shift)
void ToggleThumb::setShift(qreal shift)
{
if (_shift == shift)
return;
@ -40,16 +41,18 @@ void Thumb::setShift(qreal shift)
update();
}
bool Thumb::eventFilter(QObject *obj, QEvent *event)
bool ToggleThumb::eventFilter(QObject *obj, QEvent *event)
{
const QEvent::Type type = event->type();
if (QEvent::Resize == type || QEvent::Move == type) {
setGeometry(parentWidget()->rect().adjusted(8, 8, -8, -8));
} else if (QEvent::MouseButtonPress == type) {
return true;
}
return QWidget::eventFilter(obj, event);
}
void Thumb::paintEvent(QPaintEvent *event)
void ToggleThumb::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
@ -58,7 +61,12 @@ void Thumb::paintEvent(QPaintEvent *event)
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
if (_toggle->isEnabled()) {
brush.setColor(_thumbColor);
} else {
QColor disabledColor = Style::instance().themeColor("accent3");
brush.setColor(disabledColor.lighter(140));
}
painter.setBrush(brush);
painter.setPen(Qt::NoPen);
@ -71,11 +79,57 @@ void Thumb::paintEvent(QPaintEvent *event)
}
}
void Thumb::mouseReleaseEvent(QMouseEvent *event)
void ToggleThumb::mouseReleaseEvent(QMouseEvent *event)
{
if (_toggle->isEnabled()) {
_toggle->setChecked(!_toggle->isChecked());
emit clicked();
const bool newChecked = !_toggle->isChecked();
_toggle->setChecked(newChecked);
emit clicked(newChecked);
}
QWidget::mouseReleaseEvent(event);
}
ToggleTrack::ToggleTrack(Toggle *parent)
: QWidget(parent),
_toggle(parent)
{
parent->installEventFilter(this);
}
ToggleTrack::~ToggleTrack()
{
}
bool ToggleTrack::eventFilter(QObject *obj, QEvent *event)
{
const QEvent::Type type = event->type();
if (QEvent::Resize == type || QEvent::Move == type) {
setGeometry(parentWidget()->rect());
}
return QWidget::eventFilter(obj, event);
}
void ToggleTrack::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QBrush brush;
brush.setColor(_trackColor);
brush.setStyle(Qt::SolidPattern);
painter.setBrush(brush);
painter.setPen(Qt::NoPen);
if (Qt::Horizontal == _toggle->orientation()) {
const int h = height()/2;
const QRect r(0, h/2, width(), h);
painter.drawRoundedRect(r.adjusted(14, 4, -14, -4), h/2-4, h/2-4);
} else {
const int w = width()/2;
const QRect r(w/2, 0, w, height());
painter.drawRoundedRect(r.adjusted(4, 14, -4, -14), w/2-4, w/2-4);
}
}

View File

@ -5,23 +5,35 @@
class Toggle;
class Thumb : public QWidget
class ToggleThumb : public QWidget
{
Q_OBJECT
Q_PROPERTY(qreal shift WRITE setShift READ shift)
Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor)
public:
Thumb(Toggle *parent);
~Thumb();
ToggleThumb(Toggle *parent);
~ToggleThumb();
void setShift(qreal shift);
inline qreal shift() const { return _shift; }
inline qreal offset() const { return _offset; }
inline void setThumbColor(const QColor &color)
{
_thumbColor = color;
update();
}
inline QColor thumbColor() const
{
return _thumbColor;
}
signals:
void clicked();
void clicked(bool);
protected:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
@ -29,11 +41,44 @@ protected:
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(Thumb)
Q_DISABLE_COPY(ToggleThumb)
Toggle *const _toggle;
qreal _shift;
qreal _offset;
QColor _thumbColor;
};
class ToggleTrack : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor trackColor WRITE setTrackColor READ trackColor)
public:
ToggleTrack(Toggle *parent);
~ToggleTrack();
inline void setTrackColor(const QColor &color)
{
_trackColor = color;
update();
}
inline QColor trackColor() const
{
return _trackColor;
}
protected:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(ToggleTrack)
Toggle *const _toggle;
QColor _trackColor;
};
#endif // TOGGLE_INTERNAL_H

View File

@ -2,9 +2,11 @@
#define TOGGLE_P_H
#include <QStateMachine>
#include "toggle_internal.h"
class RippleOverlay;
class Toggle;
class ToggleThumb;
class ToggleTrack;
class TogglePrivate
{
@ -17,7 +19,8 @@ public:
void init();
Toggle *const q_ptr;
Thumb *const thumb;
ToggleTrack *const track;
ToggleThumb *const thumb;
RippleOverlay *const ripple;
QStateMachine machine;
Qt::Orientation orientation;