diff --git a/components/toggle.cpp b/components/toggle.cpp index 0155e15..ca97450 100644 --- a/components/toggle.cpp +++ b/components/toggle.cpp @@ -4,11 +4,15 @@ #include #include #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 } diff --git a/components/toggle.h b/components/toggle.h index 5bd27ba..0ab5afb 100644 --- a/components/toggle.h +++ b/components/toggle.h @@ -21,7 +21,7 @@ public: void updateOverlayGeometry(); protected slots: - void addRipple(); + void addRipple(bool checked); protected: bool event(QEvent *event) Q_DECL_OVERRIDE; diff --git a/components/toggle_internal.cpp b/components/toggle_internal.cpp index 11e6c22..7dfe14e 100644 --- a/components/toggle_internal.cpp +++ b/components/toggle_internal.cpp @@ -1,10 +1,11 @@ #include #include #include +#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); + } +} diff --git a/components/toggle_internal.h b/components/toggle_internal.h index fd3ebc4..f0d95e4 100644 --- a/components/toggle_internal.h +++ b/components/toggle_internal.h @@ -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 diff --git a/components/toggle_p.h b/components/toggle_p.h index 1767d2d..6cdbe92 100644 --- a/components/toggle_p.h +++ b/components/toggle_p.h @@ -2,9 +2,11 @@ #define TOGGLE_P_H #include -#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;