implement toggle animations
This commit is contained in:
parent
e51251408b
commit
a6bef3d327
|
@ -4,11 +4,15 @@
|
||||||
#include <QSignalTransition>
|
#include <QSignalTransition>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
#include "lib/rippleoverlay.h"
|
#include "lib/rippleoverlay.h"
|
||||||
|
#include "lib/ripple.h"
|
||||||
|
#include "lib/style.h"
|
||||||
#include "toggle_p.h"
|
#include "toggle_p.h"
|
||||||
|
#include "toggle_internal.h"
|
||||||
|
|
||||||
TogglePrivate::TogglePrivate(Toggle *q)
|
TogglePrivate::TogglePrivate(Toggle *q)
|
||||||
: q_ptr(q),
|
: q_ptr(q),
|
||||||
thumb(new Thumb(q)),
|
track(new ToggleTrack(q)),
|
||||||
|
thumb(new ToggleThumb(q)),
|
||||||
ripple(new RippleOverlay(q->parentWidget())),
|
ripple(new RippleOverlay(q->parentWidget())),
|
||||||
orientation(Qt::Horizontal)
|
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);
|
transition->setTargetState(onState);
|
||||||
offState->addTransition(transition);
|
offState->addTransition(transition);
|
||||||
|
|
||||||
animation = new QPropertyAnimation;
|
animation = new QPropertyAnimation;
|
||||||
animation->setPropertyName("shift");
|
animation->setPropertyName("shift");
|
||||||
animation->setTargetObject(thumb);
|
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);
|
animation->setDuration(150);
|
||||||
transition->addAnimation(animation);
|
transition->addAnimation(animation);
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
transition = new QSignalTransition(thumb, SIGNAL(clicked()));
|
|
||||||
transition->setTargetState(offState);
|
|
||||||
onState->addTransition(transition);
|
|
||||||
|
|
||||||
animation = new QPropertyAnimation;
|
animation = new QPropertyAnimation;
|
||||||
animation->setPropertyName("shift");
|
animation->setPropertyName("thumbColor");
|
||||||
animation->setTargetObject(thumb);
|
animation->setTargetObject(thumb);
|
||||||
animation->setDuration(150);
|
animation->setDuration(150);
|
||||||
transition->addAnimation(animation);
|
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);
|
offState->assignProperty(thumb, "shift", 0);
|
||||||
onState->assignProperty(thumb, "shift", 1);
|
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();
|
machine.start();
|
||||||
|
|
||||||
QObject::connect(thumb, SIGNAL(clicked()), q, SLOT(addRipple()));
|
QObject::connect(thumb, SIGNAL(clicked(bool)), q, SLOT(addRipple(bool)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Toggle::Toggle(QWidget *parent)
|
Toggle::Toggle(QWidget *parent)
|
||||||
|
@ -114,19 +158,28 @@ void Toggle::updateOverlayGeometry()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toggle::addRipple()
|
void Toggle::addRipple(bool checked)
|
||||||
{
|
{
|
||||||
Q_D(Toggle);
|
Q_D(Toggle);
|
||||||
|
|
||||||
|
int t, w;
|
||||||
|
|
||||||
if (Qt::Horizontal == d->orientation) {
|
if (Qt::Horizontal == d->orientation) {
|
||||||
const int t = height()/2;
|
t = height()/2;
|
||||||
const int w = d->thumb->height()/2+10;
|
w = d->thumb->height()/2+10;
|
||||||
d->ripple->addRipple(QPoint(10+t, 20+t), w);
|
|
||||||
} else {
|
} else {
|
||||||
const int t = width()/2;
|
t = width()/2;
|
||||||
const int w = d->thumb->width()/2+10;
|
w = d->thumb->width()/2+10;
|
||||||
d->ripple->addRipple(QPoint(10+t, 20+t), w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
bool Toggle::event(QEvent *event)
|
||||||
|
@ -153,25 +206,15 @@ void Toggle::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
|
|
||||||
Q_D(Toggle);
|
#ifdef DEBUG_LAYOUT
|
||||||
|
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
QBrush brush;
|
QPen pen;
|
||||||
brush.setColor(QColor(180, 180, 180));
|
pen.setColor(Qt::red);
|
||||||
brush.setStyle(Qt::SolidPattern);
|
pen.setWidth(1);
|
||||||
painter.setBrush(brush);
|
painter.setOpacity(1);
|
||||||
|
painter.setPen(pen);
|
||||||
painter.setPen(Qt::NoPen);
|
painter.setBrush(Qt::NoBrush);
|
||||||
|
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||||
if (Qt::Horizontal == d->orientation) {
|
#endif
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
void updateOverlayGeometry();
|
void updateOverlayGeometry();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void addRipple();
|
void addRipple(bool checked);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event(QEvent *event) Q_DECL_OVERRIDE;
|
bool event(QEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QGraphicsDropShadowEffect>
|
#include <QGraphicsDropShadowEffect>
|
||||||
|
#include "lib/style.h"
|
||||||
#include "toggle_internal.h"
|
#include "toggle_internal.h"
|
||||||
#include "toggle.h"
|
#include "toggle.h"
|
||||||
|
|
||||||
Thumb::Thumb(Toggle *parent)
|
ToggleThumb::ToggleThumb(Toggle *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_toggle(parent),
|
_toggle(parent),
|
||||||
_shift(0),
|
_shift(0),
|
||||||
|
@ -21,11 +22,11 @@ Thumb::Thumb(Toggle *parent)
|
||||||
setGraphicsEffect(effect);
|
setGraphicsEffect(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thumb::~Thumb()
|
ToggleThumb::~ToggleThumb()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thumb::setShift(qreal shift)
|
void ToggleThumb::setShift(qreal shift)
|
||||||
{
|
{
|
||||||
if (_shift == shift)
|
if (_shift == shift)
|
||||||
return;
|
return;
|
||||||
|
@ -40,16 +41,18 @@ void Thumb::setShift(qreal shift)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thumb::eventFilter(QObject *obj, QEvent *event)
|
bool ToggleThumb::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
const QEvent::Type type = event->type();
|
const QEvent::Type type = event->type();
|
||||||
if (QEvent::Resize == type || QEvent::Move == type) {
|
if (QEvent::Resize == type || QEvent::Move == type) {
|
||||||
setGeometry(parentWidget()->rect().adjusted(8, 8, -8, -8));
|
setGeometry(parentWidget()->rect().adjusted(8, 8, -8, -8));
|
||||||
|
} else if (QEvent::MouseButtonPress == type) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return QWidget::eventFilter(obj, event);
|
return QWidget::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thumb::paintEvent(QPaintEvent *event)
|
void ToggleThumb::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
|
|
||||||
|
@ -58,7 +61,12 @@ void Thumb::paintEvent(QPaintEvent *event)
|
||||||
|
|
||||||
QBrush brush;
|
QBrush brush;
|
||||||
brush.setStyle(Qt::SolidPattern);
|
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.setBrush(brush);
|
||||||
painter.setPen(Qt::NoPen);
|
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()) {
|
if (_toggle->isEnabled()) {
|
||||||
_toggle->setChecked(!_toggle->isChecked());
|
const bool newChecked = !_toggle->isChecked();
|
||||||
emit clicked();
|
_toggle->setChecked(newChecked);
|
||||||
|
emit clicked(newChecked);
|
||||||
}
|
}
|
||||||
QWidget::mouseReleaseEvent(event);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,23 +5,35 @@
|
||||||
|
|
||||||
class Toggle;
|
class Toggle;
|
||||||
|
|
||||||
class Thumb : public QWidget
|
class ToggleThumb : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(qreal shift WRITE setShift READ shift)
|
Q_PROPERTY(qreal shift WRITE setShift READ shift)
|
||||||
|
Q_PROPERTY(QColor thumbColor WRITE setThumbColor READ thumbColor)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Thumb(Toggle *parent);
|
ToggleThumb(Toggle *parent);
|
||||||
~Thumb();
|
~ToggleThumb();
|
||||||
|
|
||||||
void setShift(qreal shift);
|
void setShift(qreal shift);
|
||||||
inline qreal shift() const { return _shift; }
|
inline qreal shift() const { return _shift; }
|
||||||
|
|
||||||
inline qreal offset() const { return _offset; }
|
inline qreal offset() const { return _offset; }
|
||||||
|
|
||||||
|
inline void setThumbColor(const QColor &color)
|
||||||
|
{
|
||||||
|
_thumbColor = color;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QColor thumbColor() const
|
||||||
|
{
|
||||||
|
return _thumbColor;
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void clicked();
|
void clicked(bool);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
|
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
@ -29,11 +41,44 @@ protected:
|
||||||
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(Thumb)
|
Q_DISABLE_COPY(ToggleThumb)
|
||||||
|
|
||||||
Toggle *const _toggle;
|
Toggle *const _toggle;
|
||||||
qreal _shift;
|
qreal _shift;
|
||||||
qreal _offset;
|
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
|
#endif // TOGGLE_INTERNAL_H
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
#define TOGGLE_P_H
|
#define TOGGLE_P_H
|
||||||
|
|
||||||
#include <QStateMachine>
|
#include <QStateMachine>
|
||||||
#include "toggle_internal.h"
|
|
||||||
|
|
||||||
class RippleOverlay;
|
class RippleOverlay;
|
||||||
|
class Toggle;
|
||||||
|
class ToggleThumb;
|
||||||
|
class ToggleTrack;
|
||||||
|
|
||||||
class TogglePrivate
|
class TogglePrivate
|
||||||
{
|
{
|
||||||
|
@ -17,7 +19,8 @@ public:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
Toggle *const q_ptr;
|
Toggle *const q_ptr;
|
||||||
Thumb *const thumb;
|
ToggleTrack *const track;
|
||||||
|
ToggleThumb *const thumb;
|
||||||
RippleOverlay *const ripple;
|
RippleOverlay *const ripple;
|
||||||
QStateMachine machine;
|
QStateMachine machine;
|
||||||
Qt::Orientation orientation;
|
Qt::Orientation orientation;
|
||||||
|
|
Loading…
Reference in New Issue