123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- #include "qtmaterialslider_internal.h"
- #include <QState>
- #include <QAbstractTransition>
- #include <QSignalTransition>
- #include <QEventTransition>
- #include <QPropertyAnimation>
- #include <QPainter>
- #include "qtmaterialslider.h"
- #include "lib/qtmaterialstyle.h"
- #include "lib/qtmaterialstatetransition.h"
- /*!
- * \class QtMaterialSliderStateMachine
- * \internal
- */
- QtMaterialSliderStateMachine::QtMaterialSliderStateMachine(
- QtMaterialSlider *slider,
- QtMaterialSliderThumb *thumb,
- QtMaterialSliderTrack *track)
- : QStateMachine(slider),
- m_slider(slider),
- m_thumb(thumb),
- m_track(track),
- m_topState(new QState(QState::ParallelStates)),
- m_fstState(new QState(m_topState)),
- m_sndState(new QState(m_topState)),
- m_inactiveState(new QState(m_fstState)),
- m_focusState(new QState(m_fstState)),
- m_slidingState(new QState(m_fstState)),
- m_pulseOutState(new QState(m_focusState)),
- m_pulseInState(new QState(m_focusState)),
- m_minState(new QState(m_sndState)),
- m_normalState(new QState(m_sndState))
- {
- addState(m_topState);
- setInitialState(m_topState);
- m_fstState->setInitialState(m_inactiveState);
- m_focusState->setInitialState(m_pulseOutState);
- m_inactiveState->assignProperty(thumb, "haloSize", 0);
- m_slidingState->assignProperty(thumb, "haloSize", 0);
- m_pulseOutState->assignProperty(thumb, "haloSize", 35);
- m_pulseInState->assignProperty(thumb, "haloSize", 28);
- m_inactiveState->assignProperty(thumb, "diameter", 11);
- m_focusState->assignProperty(thumb, "diameter", 11);
- m_slidingState->assignProperty(thumb, "diameter", 17);
- QAbstractTransition *transition;
- QtMaterialStateTransition *customTransition;
- QPropertyAnimation *animation;
- // Show halo on mouse enter
- customTransition = new QtMaterialStateTransition(SliderNoFocusMouseEnter);
- customTransition->setTargetState(m_focusState);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- customTransition->addAnimation(animation);
- customTransition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
- m_inactiveState->addTransition(customTransition);
- // Show halo on focus in
- transition = new QEventTransition(slider, QEvent::FocusIn);
- transition->setTargetState(m_focusState);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- transition->addAnimation(animation);
- transition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
- m_inactiveState->addTransition(transition);
- // Hide halo on focus out
- transition = new QEventTransition(slider, QEvent::FocusOut);
- transition->setTargetState(m_inactiveState);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- transition->addAnimation(animation);
- transition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
- m_focusState->addTransition(transition);
- // Hide halo on mouse leave, except if widget has focus
- customTransition = new QtMaterialStateTransition(SliderNoFocusMouseLeave);
- customTransition->setTargetState(m_inactiveState);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- customTransition->addAnimation(animation);
- customTransition->addAnimation(new QPropertyAnimation(track, "fillColor", this));
- m_focusState->addTransition(customTransition);
- // Pulse in
- transition = new QSignalTransition(m_pulseOutState, SIGNAL(propertiesAssigned()));
- transition->setTargetState(m_pulseInState);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- animation->setDuration(1000);
- transition->addAnimation(animation);
- m_pulseOutState->addTransition(transition);
- // Pulse out
- transition = new QSignalTransition(m_pulseInState, SIGNAL(propertiesAssigned()));
- transition->setTargetState(m_pulseOutState);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- animation->setDuration(1000);
- transition->addAnimation(animation);
- m_pulseInState->addTransition(transition);
- // Slider pressed
- transition = new QSignalTransition(slider, SIGNAL(sliderPressed()));
- transition->setTargetState(m_slidingState);
- animation = new QPropertyAnimation(thumb, "diameter", this);
- animation->setDuration(70);
- transition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- transition->addAnimation(animation);
- m_focusState->addTransition(transition);
- // Slider released
- transition = new QSignalTransition(slider, SIGNAL(sliderReleased()));
- transition->setTargetState(m_focusState);
- animation = new QPropertyAnimation(thumb, "diameter", this);
- animation->setDuration(70);
- transition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "haloSize", this);
- animation->setEasingCurve(QEasingCurve::InOutSine);
- transition->addAnimation(animation);
- m_slidingState->addTransition(transition);
- // Min. value transitions
- m_minState->assignProperty(thumb, "borderWidth", 2);
- m_normalState->assignProperty(thumb, "borderWidth", 0);
- m_sndState->setInitialState(m_minState);
- customTransition = new QtMaterialStateTransition(SliderChangedFromMinimum);
- customTransition->setTargetState(m_normalState);
- animation = new QPropertyAnimation(thumb, "fillColor", this);
- animation->setDuration(200);
- customTransition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "haloColor", this);
- animation->setDuration(300);
- customTransition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "borderColor", this);
- animation->setDuration(200);
- customTransition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "borderWidth", this);
- animation->setDuration(200);
- customTransition->addAnimation(animation);
- m_minState->addTransition(customTransition);
- customTransition = new QtMaterialStateTransition(SliderChangedToMinimum);
- customTransition->setTargetState(m_minState);
- animation = new QPropertyAnimation(thumb, "fillColor", this);
- animation->setDuration(200);
- customTransition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "haloColor", this);
- animation->setDuration(300);
- customTransition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "borderColor", this);
- animation->setDuration(200);
- customTransition->addAnimation(animation);
- animation = new QPropertyAnimation(thumb, "borderWidth", this);
- animation->setDuration(200);
- customTransition->addAnimation(animation);
- m_normalState->addTransition(customTransition);
- setupProperties();
- }
- QtMaterialSliderStateMachine::~QtMaterialSliderStateMachine()
- {
- }
- void QtMaterialSliderStateMachine::setupProperties()
- {
- QColor trackColor = m_slider->trackColor();
- QColor thumbColor = m_slider->thumbColor();
- m_inactiveState->assignProperty(m_track, "fillColor", trackColor.lighter(130));
- m_slidingState->assignProperty(m_track, "fillColor", trackColor);
- m_focusState->assignProperty(m_track, "fillColor", trackColor);
- QColor holeColor = m_slider->palette().color(QPalette::Base);
- if (m_slider->parentWidget()) {
- holeColor = m_slider->parentWidget()->palette().color(m_slider->backgroundRole());
- }
- m_minState->assignProperty(m_thumb, "fillColor", holeColor);
- m_minState->assignProperty(m_thumb, "haloColor", trackColor);
- m_minState->assignProperty(m_thumb, "borderColor", trackColor);
- m_normalState->assignProperty(m_thumb, "fillColor", thumbColor);
- m_normalState->assignProperty(m_thumb, "haloColor", thumbColor);
- m_normalState->assignProperty(m_thumb, "borderColor", thumbColor);
- m_slider->update();
- }
- /*!
- * \class QtMaterialSliderThumb
- * \internal
- */
- QtMaterialSliderThumb::QtMaterialSliderThumb(QtMaterialSlider *slider)
- : QtMaterialOverlayWidget(slider->parentWidget()),
- m_slider(slider),
- m_diameter(11),
- m_borderWidth(2),
- m_haloSize(0),
- m_offset(0)
- {
- slider->installEventFilter(this);
- setAttribute(Qt::WA_TransparentForMouseEvents, true);
- }
- QtMaterialSliderThumb::~QtMaterialSliderThumb()
- {
- }
- bool QtMaterialSliderThumb::eventFilter(QObject *obj, QEvent *event)
- {
- if (QEvent::ParentChange == event->type()) {
- setParent(m_slider->parentWidget());
- }
- return QtMaterialOverlayWidget::eventFilter(obj, event);
- }
- void QtMaterialSliderThumb::paintEvent(QPaintEvent *event)
- {
- Q_UNUSED(event)
- QPainter painter(this);
- painter.setRenderHint(QPainter::Antialiasing);
- // Halo
- QBrush brush;
- brush.setStyle(Qt::SolidPattern);
- brush.setColor(m_haloColor);
- painter.setBrush(brush);
- painter.setPen(Qt::NoPen);
- QPointF disp = Qt::Horizontal == m_slider->orientation()
- ? QPointF(QT_MATERIAL_SLIDER_MARGIN + m_offset, m_slider->height()/2)
- : QPointF(m_slider->width()/2, QT_MATERIAL_SLIDER_MARGIN + m_offset);
- QRectF halo((m_slider->pos() - QPointF(m_haloSize, m_haloSize)/2) + disp,
- QSizeF(m_haloSize, m_haloSize));
- painter.setOpacity(0.15);
- painter.drawEllipse(halo);
- // Knob
- const bool isMin = m_slider->value() == m_slider->minimum();
- brush.setColor(m_slider->isEnabled()
- ? m_fillColor
- : m_slider->disabledColor());
- painter.setBrush(!m_slider->isEnabled() && isMin
- ? Qt::NoBrush
- : brush);
- if (m_slider->isEnabled() || isMin) {
- QPen pen;
- pen.setColor(m_borderColor);
- pen.setWidthF((isMin && !m_slider->isEnabled()) ? 1.7 : m_borderWidth);
- painter.setPen(pen);
- } else {
- painter.setPen(Qt::NoPen);
- }
- QRectF geometry = Qt::Horizontal == m_slider->orientation()
- ? QRectF(m_offset, m_slider->height()/2 - QT_MATERIAL_SLIDER_MARGIN,
- QT_MATERIAL_SLIDER_MARGIN*2, QT_MATERIAL_SLIDER_MARGIN*2).translated(m_slider->pos())
- : QRectF(m_slider->width()/2 - QT_MATERIAL_SLIDER_MARGIN, m_offset,
- QT_MATERIAL_SLIDER_MARGIN*2, QT_MATERIAL_SLIDER_MARGIN*2).translated(m_slider->pos());
- qreal s = m_slider->isEnabled() ? m_diameter : 7;
- QRectF thumb(0, 0, s, s);
- thumb.moveCenter(geometry.center());
- painter.setOpacity(1);
- painter.drawEllipse(thumb);
- }
- /*!
- * \class QtMaterialSliderTrack
- * \internal
- */
- QtMaterialSliderTrack::QtMaterialSliderTrack(QtMaterialSliderThumb *thumb, QtMaterialSlider *slider)
- : QtMaterialOverlayWidget(slider->parentWidget()),
- m_slider(slider),
- m_thumb(thumb),
- m_trackWidth(2)
- {
- slider->installEventFilter(this);
- setAttribute(Qt::WA_TransparentForMouseEvents, true);
- connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(update()));
- }
- QtMaterialSliderTrack::~QtMaterialSliderTrack()
- {
- }
- bool QtMaterialSliderTrack::eventFilter(QObject *obj, QEvent *event)
- {
- if (QEvent::ParentChange == event->type()) {
- setParent(m_slider->parentWidget());
- }
- return QtMaterialOverlayWidget::eventFilter(obj, event);
- }
- void QtMaterialSliderTrack::paintEvent(QPaintEvent *event)
- {
- Q_UNUSED(event)
- QPainter painter(this);
- painter.setRenderHint(QPainter::Antialiasing);
- QBrush fg;
- fg.setStyle(Qt::SolidPattern);
- fg.setColor(m_slider->isEnabled() ? m_slider->thumbColor()
- : m_slider->disabledColor());
- QBrush bg;
- bg.setStyle(Qt::SolidPattern);
- bg.setColor(m_slider->isEnabled() ? m_fillColor
- : m_slider->disabledColor());
- qreal offset = m_thumb->offset();
- if (Qt::Horizontal == m_slider->orientation()) {
- painter.translate(m_slider->x() + QT_MATERIAL_SLIDER_MARGIN,
- m_slider->y() + m_slider->height()/2
- - static_cast<qreal>(m_trackWidth)/2);
- } else {
- painter.translate(m_slider->x() + m_slider->width()/2
- - static_cast<qreal>(m_trackWidth)/2,
- m_slider->y() + QT_MATERIAL_SLIDER_MARGIN);
- }
- QRectF geometry = Qt::Horizontal == m_slider->orientation()
- ? QRectF(0, 0, m_slider->width() - QT_MATERIAL_SLIDER_MARGIN*2, m_trackWidth)
- : QRectF(0, 0, m_trackWidth, m_slider->height() - QT_MATERIAL_SLIDER_MARGIN*2);
- QRectF bgRect;
- QRectF fgRect;
- if (Qt::Horizontal == m_slider->orientation()) {
- fgRect = QRectF(0, 0, offset, m_trackWidth);
- bgRect = QRectF(offset, 0, m_slider->width(), m_trackWidth).intersected(geometry);
- } else {
- fgRect = QRectF(0, 0, m_trackWidth, offset);
- bgRect = QRectF(0, offset, m_trackWidth, m_slider->height()).intersected(geometry);
- }
- if (!m_slider->isEnabled()) {
- fgRect = fgRect.width() < 9 ? QRectF() : fgRect.adjusted(0, 0, -6, 0);
- bgRect = bgRect.width() < 9 ? QRectF() : bgRect.adjusted(6, 0, 0, 0);
- }
- if (m_slider->invertedAppearance()) {
- qSwap(bgRect, fgRect);
- }
- painter.fillRect(bgRect, bg);
- painter.fillRect(fgRect, fg);
- }
|