qt-material-widgets/components/slider_p.h

301 lines
9.0 KiB
C
Raw Normal View History

2016-05-01 19:56:39 +00:00
#ifndef SLIDER_P_H
#define SLIDER_P_H
#include "slider.h"
2016-05-01 21:10:31 +00:00
#include <QPainter>
2016-05-09 20:32:16 +00:00
#include <QPropertyAnimation>
#include <QStateMachine>
#include <QEventTransition>
#include <QSignalTransition>
#include <QDebug>
#include "lib/style.h"
2016-05-10 06:25:44 +00:00
#include "sliderthumb.h"
2016-05-01 19:56:39 +00:00
2016-05-10 14:17:51 +00:00
// change
2016-05-09 20:32:16 +00:00
#define THUMB_OUTER_SIZE 20
2016-05-01 19:56:39 +00:00
class SliderPrivate
{
Q_DISABLE_COPY(SliderPrivate)
Q_DECLARE_PUBLIC(Slider)
2016-05-10 06:25:44 +00:00
friend class SliderThumb;
2016-05-01 19:56:39 +00:00
public:
2016-05-10 14:17:51 +00:00
SliderPrivate(Slider *parent);
2016-05-01 19:56:39 +00:00
2016-05-10 14:17:51 +00:00
void init(Slider *slider);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QRectF trackGeometry() const;
QRectF thumbGeometry() const;
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
void paintTrack(QPainter *painter);
int valueFromPosition(const QPoint &pos) const;
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
Slider *const q_ptr;
SliderThumb *const thumb;
QStateMachine machine;
bool hoverTrack;
bool hoverThumb;
bool step;
bool pageStepMode;
int stepTo;
int oldValue;
2016-05-11 06:09:19 +00:00
QColor trackColor;
2016-05-10 14:17:51 +00:00
};
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
SliderPrivate::SliderPrivate(Slider *parent)
: q_ptr(parent),
thumb(new SliderThumb(parent)),
hoverTrack(false),
hoverThumb(false),
step(false),
2016-05-10 14:29:50 +00:00
pageStepMode(false),
2016-05-10 14:17:51 +00:00
stepTo(0),
2016-05-11 06:09:19 +00:00
oldValue(parent->value()),
trackColor(QColor(200, 200, 200))
2016-05-10 14:17:51 +00:00
{
parent->setMouseTracking(true);
}
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
void SliderPrivate::init(Slider *slider)
{
QState *topState = new QState(QState::ParallelStates);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QState *fstState = new QState(topState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QState *inactiveState = new QState(fstState);
QState *focusState = new QState(fstState);
2016-05-11 06:09:19 +00:00
QState *slidingState = new QState(fstState);
QState *disabledState = new QState(fstState);
2016-05-10 14:17:51 +00:00
QState *pulseOutState = new QState(focusState);
QState *pulseInState = new QState(focusState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
focusState->setInitialState(pulseOutState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
inactiveState->assignProperty(thumb, "haloSize", 0);
2016-05-11 06:09:19 +00:00
slidingState->assignProperty(thumb, "haloSize", 0);
2016-05-10 14:17:51 +00:00
pulseOutState->assignProperty(thumb, "haloSize", 35);
pulseInState->assignProperty(thumb, "haloSize", 28);
2016-05-11 06:09:19 +00:00
disabledState->assignProperty(thumb, "diameter", 7);
//disabledState->assignProperty(thumb, "fillColor", QColor(200, 200, 200));
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
inactiveState->assignProperty(thumb, "diameter", 11);
focusState->assignProperty(thumb, "diameter", 11);
slidingState->assignProperty(thumb, "diameter", 17);
2016-05-09 20:32:16 +00:00
2016-05-11 06:09:19 +00:00
//inactiveState->assignProperty(thumb, "fillColor", QColor(0, 0, 0));
//focusState->assignProperty(thumb, "fillColor", QColor(0, 0, 0));
//slidingState->assignProperty(thumb, "fillColor", QColor(0, 0, 0));
2016-05-10 14:17:51 +00:00
machine.addState(topState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
fstState->setInitialState(inactiveState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
machine.setInitialState(topState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QAbstractTransition *transition;
QPropertyAnimation *animation;
2016-05-09 20:32:16 +00:00
2016-05-11 06:09:19 +00:00
//
transition = new QSignalTransition(slider, SIGNAL(sliderDisabled()));
transition->setTargetState(disabledState);
inactiveState->addTransition(transition);
transition = new QSignalTransition(slider, SIGNAL(sliderDisabled()));
transition->setTargetState(disabledState);
focusState->addTransition(transition);
transition = new QSignalTransition(slider, SIGNAL(sliderDisabled()));
transition->setTargetState(disabledState);
slidingState->addTransition(transition);
transition = new QSignalTransition(slider, SIGNAL(sliderEnabled()));
transition->setTargetState(inactiveState);
disabledState->addTransition(transition);
2016-05-10 14:17:51 +00:00
// Show halo on focus in
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QEventTransition(slider, QEvent::FocusIn);
transition->setTargetState(focusState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
animation = new QPropertyAnimation(thumb, "haloSize");
transition->addAnimation(animation);
inactiveState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
// Hide halo on focus out
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QEventTransition(slider, QEvent::FocusOut);
transition->setTargetState(inactiveState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
animation = new QPropertyAnimation(thumb, "haloSize");
transition->addAnimation(animation);
focusState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
// Pulse in
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QSignalTransition(pulseOutState, SIGNAL(propertiesAssigned()));
transition->setTargetState(pulseInState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
animation = new QPropertyAnimation(thumb, "haloSize");
animation->setEasingCurve(QEasingCurve::InOutSine);
animation->setDuration(1000);
transition->addAnimation(animation);
pulseOutState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
// Pulse out
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QSignalTransition(pulseInState, SIGNAL(propertiesAssigned()));
transition->setTargetState(pulseOutState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
animation = new QPropertyAnimation(thumb, "haloSize");
animation->setEasingCurve(QEasingCurve::InOutSine);
animation->setDuration(1000);
transition->addAnimation(animation);
pulseInState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
// Slider pressed
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QSignalTransition(slider, SIGNAL(sliderPressed()));
transition->setTargetState(slidingState);
transition->addAnimation(new QPropertyAnimation(thumb, "diameter"));
transition->addAnimation(new QPropertyAnimation(thumb, "haloSize"));
focusState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
// Slider released
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QSignalTransition(slider, SIGNAL(sliderReleased()));
transition->setTargetState(focusState);
transition->addAnimation(new QPropertyAnimation(thumb, "diameter"));
transition->addAnimation(new QPropertyAnimation(thumb, "haloSize"));
slidingState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
// Min. value animation
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QState *sndState = new QState(topState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QState *minState = new QState(sndState);
QState *normalState = new QState(sndState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
minState->assignProperty(thumb, "fillColor", QColor(0, 0, 0));
minState->assignProperty(thumb, "borderWidth", 0);
normalState->assignProperty(thumb, "fillColor", QColor(255, 255, 255));
normalState->assignProperty(thumb, "borderWidth", 1.5);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
sndState->setInitialState(minState);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QSignalTransition(slider, SIGNAL(changedToMinimum()));
transition->setTargetState(normalState);
animation = new QPropertyAnimation(thumb, "fillColor");
2016-05-10 14:29:50 +00:00
animation->setDuration(200);
2016-05-10 14:17:51 +00:00
transition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "borderWidth");
2016-05-10 14:29:50 +00:00
animation->setDuration(200);
2016-05-10 14:17:51 +00:00
transition->addAnimation(animation);
minState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
transition = new QSignalTransition(slider, SIGNAL(changedFromMinimum()));
transition->setTargetState(minState);
animation = new QPropertyAnimation(thumb, "fillColor");
2016-05-10 14:29:50 +00:00
animation->setDuration(200);
2016-05-10 14:17:51 +00:00
transition->addAnimation(animation);
animation = new QPropertyAnimation(thumb, "borderWidth");
2016-05-10 14:29:50 +00:00
animation->setDuration(200);
2016-05-10 14:17:51 +00:00
transition->addAnimation(animation);
normalState->addTransition(transition);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
machine.start();
}
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
QRectF SliderPrivate::trackGeometry() const
{
Q_Q(const Slider);
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
return Qt::Horizontal == q->orientation()
? QRectF(THUMB_OUTER_SIZE/2, q->rect().height()/2 - 1,
q->rect().width() - THUMB_OUTER_SIZE, 2)
: QRectF(q->rect().width()/2 - 1, THUMB_OUTER_SIZE/2, 2,
q->rect().height() - THUMB_OUTER_SIZE);
}
2016-05-01 23:22:43 +00:00
2016-05-10 14:17:51 +00:00
QRectF SliderPrivate::thumbGeometry() const
{
Q_Q(const Slider);
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
return Qt::Horizontal == q->orientation()
? QRectF(q->thumbOffset(), q->rect().height()/2 - THUMB_OUTER_SIZE/2,
THUMB_OUTER_SIZE, THUMB_OUTER_SIZE)
: QRectF(q->rect().width()/2 - THUMB_OUTER_SIZE/2, q->thumbOffset(),
THUMB_OUTER_SIZE, THUMB_OUTER_SIZE);
}
2016-05-01 21:44:38 +00:00
2016-05-10 14:17:51 +00:00
void SliderPrivate::paintTrack(QPainter *painter)
{
Q_Q(const Slider);
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
painter->save();
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
QBrush fg;
fg.setStyle(Qt::SolidPattern);
2016-05-11 06:09:19 +00:00
fg.setColor(thumb->fillColor());
2016-05-01 21:44:38 +00:00
2016-05-10 14:17:51 +00:00
QBrush bg;
bg.setStyle(Qt::SolidPattern);
2016-05-11 06:09:19 +00:00
bg.setColor(trackColor);
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
qreal offset = q->thumbOffset() + THUMB_OUTER_SIZE/2;
2016-05-01 23:22:43 +00:00
2016-05-11 06:09:19 +00:00
QSizeF box(q->isEnabled() ? offset : offset - 7,
qMax(q->width(), q->height()));
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
if (Qt::Vertical == q->orientation())
box.transpose();
2016-05-09 20:32:16 +00:00
2016-05-10 14:17:51 +00:00
QRectF rect = Qt::Vertical == q->orientation()
2016-05-11 06:09:19 +00:00
? QRectF(0, q->isEnabled() ? offset : offset + 7,
box.width(), box.width())
: QRectF(q->isEnabled() ? offset : offset + 7, 0,
box.height(), box.height());
2016-05-01 21:44:38 +00:00
2016-05-10 14:17:51 +00:00
bool inverted = q->invertedAppearance();
2016-05-01 23:22:43 +00:00
2016-05-10 14:17:51 +00:00
painter->fillRect(QRectF(QPointF(0, 0), box).intersected(trackGeometry()),
inverted ? bg : fg);
painter->fillRect(rect.intersected(trackGeometry()), inverted ? fg : bg);
2016-05-01 21:44:38 +00:00
2016-05-10 14:17:51 +00:00
painter->restore();
2016-05-01 23:22:43 +00:00
#ifdef DEBUG_LAYOUT
2016-05-10 14:17:51 +00:00
if (hoverTrack) {
painter->save();
painter->setPen(Qt::red);
painter->drawRect(trackGeometry());
painter->restore();
2016-05-01 21:10:31 +00:00
}
2016-05-10 14:17:51 +00:00
#endif
}
2016-05-01 21:10:31 +00:00
2016-05-10 14:17:51 +00:00
int SliderPrivate::valueFromPosition(const QPoint &pos) const
{
Q_Q(const Slider);
2016-05-03 22:40:34 +00:00
2016-05-10 14:17:51 +00:00
int position = Qt::Horizontal == q->orientation() ? pos.x() : pos.y();
2016-05-02 20:57:57 +00:00
2016-05-10 14:17:51 +00:00
int span = Qt::Horizontal == q->orientation()
? q->rect().width() - THUMB_OUTER_SIZE
: q->rect().height() - THUMB_OUTER_SIZE;
2016-05-02 20:57:57 +00:00
2016-05-10 14:17:51 +00:00
return Style::sliderValueFromPosition(
q->minimum(),
q->maximum(),
position - THUMB_OUTER_SIZE/2,
span,
q->invertedAppearance());
}
2016-05-01 19:56:39 +00:00
#endif // SLIDER_P_H