animate slider handle when value goes to minimum

This commit is contained in:
laserpants 2016-05-01 16:29:33 +03:00
parent 9c15f89a17
commit 6f1b058ccd
2 changed files with 50 additions and 13 deletions

View File

@ -8,7 +8,8 @@ Handle::Handle(Slider *slider)
: QWidget(slider), : QWidget(slider),
_slider(slider), _slider(slider),
_knobSize(12), _knobSize(12),
_haloSize(0) _haloSize(0),
_phase(0)
{ {
setAttribute(Qt::WA_TransparentForMouseEvents); setAttribute(Qt::WA_TransparentForMouseEvents);
} }
@ -39,6 +40,7 @@ void Handle::paintEvent(QPaintEvent *event)
painter.setBrush(brush); painter.setBrush(brush);
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
// Paint halo
if (_haloSize > 12) { if (_haloSize > 12) {
painter.save(); painter.save();
painter.setOpacity(0.1); painter.setOpacity(0.1);
@ -46,18 +48,26 @@ void Handle::paintEvent(QPaintEvent *event)
painter.restore(); 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; QPen pen;
pen.setColor(QColor(0, 0, 0, 80)); pen.setColor(QColor(0, 0, 0, 80));
pen.setWidth(2); pen.setWidth(2);
painter.setPen(pen); 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); QWidget::paintEvent(event);
} }
@ -66,6 +76,7 @@ Slider::Slider(QWidget *parent)
: QAbstractSlider(parent), : QAbstractSlider(parent),
_knobAnimation(new QPropertyAnimation(this)), _knobAnimation(new QPropertyAnimation(this)),
_haloAnimation(new QPropertyAnimation(this)), _haloAnimation(new QPropertyAnimation(this)),
_phaseAnimation(new QPropertyAnimation(this)),
_handle(new Handle(this)), _handle(new Handle(this)),
_drag(false), _drag(false),
_hover(false), _hover(false),
@ -83,6 +94,12 @@ Slider::Slider(QWidget *parent)
_haloAnimation->setEndValue(30); _haloAnimation->setEndValue(30);
_haloAnimation->setDuration(220); _haloAnimation->setDuration(220);
_phaseAnimation->setPropertyName("phase");
_phaseAnimation->setTargetObject(_handle);
_phaseAnimation->setStartValue(0);
_phaseAnimation->setEndValue(1);
_phaseAnimation->setDuration(500);
setMouseTracking(true); setMouseTracking(true);
} }
@ -224,7 +241,22 @@ void Slider::updateValue()
// @TODO: use QStyle::sliderValueFromPosition() // @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(); update();
} }

View File

@ -4,6 +4,7 @@
#include <QAbstractSlider> #include <QAbstractSlider>
#include <QPoint> #include <QPoint>
class QPropertyAnimation;
class Slider; class Slider;
class Handle : public QWidget class Handle : public QWidget
@ -12,6 +13,7 @@ class Handle : public QWidget
Q_PROPERTY(qreal knobSize WRITE setKnobSize READ knobSize) Q_PROPERTY(qreal knobSize WRITE setKnobSize READ knobSize)
Q_PROPERTY(qreal haloSize WRITE setHaloSize READ haloSize) Q_PROPERTY(qreal haloSize WRITE setHaloSize READ haloSize)
Q_PROPERTY(qreal phase WRITE setPhase READ phase)
public: public:
explicit Handle(Slider *slider); explicit Handle(Slider *slider);
@ -27,12 +29,15 @@ public:
inline void setOffset(const QPoint &offset) { _offset = offset; update(); } inline void setOffset(const QPoint &offset) { _offset = offset; update(); }
inline const QPoint &offset() const { return _offset; } 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 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 qreal haloSize() const { return _haloSize; }
inline void setPhase (qreal phase) { _phase = phase; update(); }
inline qreal phase() const { return _phase; }
void refreshGeometry(); void refreshGeometry();
protected: protected:
@ -44,10 +49,9 @@ private:
QPoint _offset; QPoint _offset;
qreal _knobSize; qreal _knobSize;
qreal _haloSize; qreal _haloSize;
qreal _phase;
}; };
class QPropertyAnimation;
class Slider : public QAbstractSlider class Slider : public QAbstractSlider
{ {
Q_OBJECT Q_OBJECT
@ -80,6 +84,7 @@ protected:
private: private:
QPropertyAnimation *const _knobAnimation; QPropertyAnimation *const _knobAnimation;
QPropertyAnimation *const _haloAnimation; QPropertyAnimation *const _haloAnimation;
QPropertyAnimation *const _phaseAnimation;
Handle *const _handle; Handle *const _handle;
bool _drag; bool _drag;
bool _hover; bool _hover;