From 6f1b058ccd492a53e882bc9c473feee2484426ef Mon Sep 17 00:00:00 2001 From: laserpants Date: Sun, 1 May 2016 16:29:33 +0300 Subject: [PATCH] animate slider handle when value goes to minimum --- components/slider.cpp | 50 +++++++++++++++++++++++++++++++++++-------- components/slider.h | 13 +++++++---- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/components/slider.cpp b/components/slider.cpp index b2e738e..592ce75 100644 --- a/components/slider.cpp +++ b/components/slider.cpp @@ -8,7 +8,8 @@ Handle::Handle(Slider *slider) : QWidget(slider), _slider(slider), _knobSize(12), - _haloSize(0) + _haloSize(0), + _phase(0) { setAttribute(Qt::WA_TransparentForMouseEvents); } @@ -39,6 +40,7 @@ void Handle::paintEvent(QPaintEvent *event) painter.setBrush(brush); painter.setPen(Qt::NoPen); + // Paint halo if (_haloSize > 12) { painter.save(); painter.setOpacity(0.1); @@ -46,18 +48,26 @@ void Handle::paintEvent(QPaintEvent *event) painter.restore(); } - if (_slider->minimum() == _slider->value()) { + const QRectF rect((width()-_knobSize)/2, (height()-_knobSize)/2, _knobSize, _knobSize); + + // Paint default knob + painter.drawEllipse(rect); + + // Hollow knob (indicates that value == minimum or slider is disabled) + if (_phase < 1) + { QPen pen; pen.setColor(QColor(0, 0, 0, 80)); pen.setWidth(2); painter.setPen(pen); - QBrush brush; - brush.setColor(Qt::white); - brush.setStyle(Qt::SolidPattern); - painter.setBrush(brush); - } - painter.drawEllipse(QRectF((width()-_knobSize)/2, (height()-_knobSize)/2, _knobSize, _knobSize)); + brush.setColor(Qt::white); + painter.setBrush(brush); + + painter.setOpacity(1-_phase); + + painter.drawEllipse(rect); + } QWidget::paintEvent(event); } @@ -66,6 +76,7 @@ Slider::Slider(QWidget *parent) : QAbstractSlider(parent), _knobAnimation(new QPropertyAnimation(this)), _haloAnimation(new QPropertyAnimation(this)), + _phaseAnimation(new QPropertyAnimation(this)), _handle(new Handle(this)), _drag(false), _hover(false), @@ -83,6 +94,12 @@ Slider::Slider(QWidget *parent) _haloAnimation->setEndValue(30); _haloAnimation->setDuration(220); + _phaseAnimation->setPropertyName("phase"); + _phaseAnimation->setTargetObject(_handle); + _phaseAnimation->setStartValue(0); + _phaseAnimation->setEndValue(1); + _phaseAnimation->setDuration(500); + setMouseTracking(true); } @@ -224,7 +241,22 @@ void Slider::updateValue() // @TODO: use QStyle::sliderValueFromPosition() - setValue((1-r)*minimum()+r*maximum()); + const int oldValue = value(); + const int newValue = (1-r)*minimum()+r*maximum(); + + if (oldValue == newValue) { + return; + } + + setValue(newValue); + + if (oldValue == 0 && newValue != 0) { + _phaseAnimation->setDirection(QAbstractAnimation::Forward); + _phaseAnimation->start(); + } else if (newValue == 0 && oldValue != 0) { + _phaseAnimation->setDirection(QAbstractAnimation::Backward); + _phaseAnimation->start(); + } update(); } diff --git a/components/slider.h b/components/slider.h index 8c0b911..5ecba99 100644 --- a/components/slider.h +++ b/components/slider.h @@ -4,6 +4,7 @@ #include #include +class QPropertyAnimation; class Slider; class Handle : public QWidget @@ -12,6 +13,7 @@ class Handle : public QWidget Q_PROPERTY(qreal knobSize WRITE setKnobSize READ knobSize) Q_PROPERTY(qreal haloSize WRITE setHaloSize READ haloSize) + Q_PROPERTY(qreal phase WRITE setPhase READ phase) public: explicit Handle(Slider *slider); @@ -27,12 +29,15 @@ public: inline void setOffset(const QPoint &offset) { _offset = offset; update(); } inline const QPoint &offset() const { return _offset; } - inline void setKnobSize (qreal size ) { _knobSize = size; refreshGeometry(); } + inline void setKnobSize (qreal size) { _knobSize = size; refreshGeometry(); } inline qreal knobSize() const { return _knobSize; } - inline void setHaloSize (qreal size ) { _haloSize = size; update(); } + inline void setHaloSize (qreal size) { _haloSize = size; update(); } inline qreal haloSize() const { return _haloSize; } + inline void setPhase (qreal phase) { _phase = phase; update(); } + inline qreal phase() const { return _phase; } + void refreshGeometry(); protected: @@ -44,10 +49,9 @@ private: QPoint _offset; qreal _knobSize; qreal _haloSize; + qreal _phase; }; -class QPropertyAnimation; - class Slider : public QAbstractSlider { Q_OBJECT @@ -80,6 +84,7 @@ protected: private: QPropertyAnimation *const _knobAnimation; QPropertyAnimation *const _haloAnimation; + QPropertyAnimation *const _phaseAnimation; Handle *const _handle; bool _drag; bool _hover;