From 2d2a4bc31ffa4188b3ec4ddef3fabead54e33eaf Mon Sep 17 00:00:00 2001 From: FarmRadio Hangar Date: Thu, 12 May 2016 11:39:17 +0300 Subject: [PATCH] move Slider state machine to separate class --- components/slider.cpp | 15 +- components/slider.h | 8 - components/slider_p.h | 251 +++--------------------------- components/sliderstatemachine.cpp | 223 ++++++++++++++++++++++++++ components/sliderstatemachine.h | 29 ++++ qt-material-widgets.pro | 6 +- 6 files changed, 286 insertions(+), 246 deletions(-) create mode 100644 components/sliderstatemachine.cpp create mode 100644 components/sliderstatemachine.h diff --git a/components/slider.cpp b/components/slider.cpp index 0670433..38659e2 100644 --- a/components/slider.cpp +++ b/components/slider.cpp @@ -12,7 +12,7 @@ Slider::Slider(QWidget *parent) : QAbstractSlider(parent), d_ptr(new SliderPrivate(this)) { - d_func()->init(this); + d_func()->init(); } Slider::~Slider() @@ -77,11 +77,11 @@ void Slider::sliderChange(SliderChange change) } else if (SliderValueChange == change) { if (minimum() == value()) { triggerAction(SliderToMinimum); - emit changedToMinimum(); + emit d->machine->changedToMinimum(); } else if (maximum() == value()) { triggerAction(SliderToMaximum); } else if (minimum() == d->oldValue) { - emit changedFromMinimum(); + emit d->machine->changedFromMinimum(); } d->oldValue = value(); } @@ -90,11 +90,14 @@ void Slider::sliderChange(SliderChange change) void Slider::changeEvent(QEvent *event) { - if (QEvent::EnabledChange == event->type()) { + if (QEvent::EnabledChange == event->type()) + { + Q_D(Slider); + if (isEnabled()) { - emit sliderEnabled(); + emit d->machine->sliderEnabled(); } else { - emit sliderDisabled(); + emit d->machine->sliderDisabled(); } } QAbstractSlider::changeEvent(event); diff --git a/components/slider.h b/components/slider.h index 340aec2..7c1eb7b 100644 --- a/components/slider.h +++ b/components/slider.h @@ -26,14 +26,6 @@ public: void setTrackWidth(int width); int trackWidth() const; -signals: - void changedToMinimum(); // @TODO: create custom event type - void changedFromMinimum(); // @TODO: create custom event type - void sliderEnabled(); // - void sliderDisabled(); // - void mouseEnter(); // - void mouseLeave(); // - protected: void sliderChange(SliderChange change) Q_DECL_OVERRIDE; diff --git a/components/slider_p.h b/components/slider_p.h index a5a86a2..a1adcd3 100644 --- a/components/slider_p.h +++ b/components/slider_p.h @@ -2,14 +2,12 @@ #define SLIDER_P_H #include -#include -#include -#include -#include +#include #include -#include "slider.h" #include "lib/style.h" +#include "slider.h" #include "sliderthumb.h" +#include "sliderstatemachine.h" class SliderPrivate { @@ -21,7 +19,7 @@ class SliderPrivate public: SliderPrivate(Slider *parent); - void init(Slider *slider); + void init(); QRectF trackGeometry() const; QRectF thumbGeometry() const; @@ -29,11 +27,11 @@ public: void paintTrack(QPainter *painter); int valueFromPosition(const QPoint &pos) const; - void setHovered(bool hovered); + void setHovered(bool status); - Slider *const q_ptr; - SliderThumb *const thumb; - QStateMachine machine; + Slider *const q_ptr; + SliderThumb *const thumb; + SliderStateMachine *const machine; bool hoverTrack; bool hoverThumb; bool hover; @@ -47,6 +45,7 @@ public: SliderPrivate::SliderPrivate(Slider *parent) : q_ptr(parent), thumb(new SliderThumb(parent)), + machine(new SliderStateMachine(parent, thumb)), hoverTrack(false), hoverThumb(false), hover(false), @@ -59,225 +58,17 @@ SliderPrivate::SliderPrivate(Slider *parent) parent->setMouseTracking(true); } -void SliderPrivate::init(Slider *slider) +void SliderPrivate::init() { - Style &style = Style::instance(); + Q_Q(Slider); - QState *topState = new QState(QState::ParallelStates); - - QState *fstState = new QState(topState); - - QState *inactiveState = new QState(fstState); - QState *focusState = new QState(fstState); - QState *slidingState = new QState(fstState); - QState *disabledState = new QState(fstState); - - QState *pulseOutState = new QState(focusState); - QState *pulseInState = new QState(focusState); - - focusState->setInitialState(pulseOutState); - - inactiveState->assignProperty(thumb, "haloSize", 0); - slidingState->assignProperty(thumb, "haloSize", 0); - - pulseOutState->assignProperty(thumb, "haloSize", 35); - pulseInState->assignProperty(thumb, "haloSize", 28); - - disabledState->assignProperty(thumb, "diameter", 7); - disabledState->assignProperty(thumb, "fillColor", style.themeColor("disabled")); - - inactiveState->assignProperty(thumb, "diameter", 11); - focusState->assignProperty(thumb, "diameter", 11); - slidingState->assignProperty(thumb, "diameter", 17); - - QColor fillColor = style.themeColor("primary1"); - - inactiveState->assignProperty(thumb, "fillColor", fillColor); - focusState->assignProperty(thumb, "fillColor", fillColor); - slidingState->assignProperty(thumb, "fillColor", fillColor); - - machine.addState(topState); - - fstState->setInitialState(inactiveState); - - machine.setInitialState(topState); - - QAbstractTransition *transition; - QPropertyAnimation *animation; - - // Add transitions - - 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); - - // Show halo on mouse enter - - transition = new QSignalTransition(slider, SIGNAL(mouseEnter())); - transition->setTargetState(focusState); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - inactiveState->addTransition(transition); - - // Show halo on focus in - - transition = new QEventTransition(slider, QEvent::FocusIn); - transition->setTargetState(focusState); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - inactiveState->addTransition(transition); - - // Hide halo on focus out - - transition = new QEventTransition(slider, QEvent::FocusOut); - transition->setTargetState(inactiveState); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - focusState->addTransition(transition); - - // Hide halo on mouse leave, except if widget has focus - - transition = new QSignalTransition(slider, SIGNAL(mouseLeave())); - transition->setTargetState(inactiveState); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - focusState->addTransition(transition); - - // Pulse in - - transition = new QSignalTransition(pulseOutState, SIGNAL(propertiesAssigned())); - transition->setTargetState(pulseInState); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - animation->setDuration(1000); - transition->addAnimation(animation); - pulseOutState->addTransition(transition); - - // Pulse out - - transition = new QSignalTransition(pulseInState, SIGNAL(propertiesAssigned())); - transition->setTargetState(pulseOutState); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - animation->setDuration(1000); - transition->addAnimation(animation); - pulseInState->addTransition(transition); - - // Slider pressed - - transition = new QSignalTransition(slider, SIGNAL(sliderPressed())); - transition->setTargetState(slidingState); - transition->addAnimation(new QPropertyAnimation(thumb, "diameter")); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - focusState->addTransition(transition); - - // Slider released - - transition = new QSignalTransition(slider, SIGNAL(sliderReleased())); - transition->setTargetState(focusState); - transition->addAnimation(new QPropertyAnimation(thumb, "diameter")); - - animation = new QPropertyAnimation(thumb, "haloSize"); - animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - slidingState->addTransition(transition); - - // Min. value transitions - - QState *sndState = new QState(topState); - - QState *minState = new QState(sndState); - QState *normalState = new QState(sndState); - - QColor minHaloColor = style.themeColor("accent3"); - minHaloColor.setAlphaF(0.15); - - QColor haloColor = style.themeColor("primary1"); - haloColor.setAlphaF(0.15); - - QColor canvasColor = style.themeColor("canvas"); - - minState->assignProperty(thumb, "minFillColor", canvasColor); - minState->assignProperty(thumb, "fillColor", canvasColor); - minState->assignProperty(thumb, "haloColor", minHaloColor); - minState->assignProperty(thumb, "borderWidth", 2); - normalState->assignProperty(thumb, "fillColor", fillColor); - normalState->assignProperty(thumb, "minFillColor", fillColor); - normalState->assignProperty(thumb, "haloColor", haloColor); - normalState->assignProperty(thumb, "borderWidth", 0); - - sndState->setInitialState(minState); - - transition = new QSignalTransition(slider, SIGNAL(changedFromMinimum())); - transition->setTargetState(normalState); - - animation = new QPropertyAnimation(thumb, "fillColor"); - animation->setDuration(200); - transition->addAnimation(animation); - - animation = new QPropertyAnimation(thumb, "haloColor"); - animation->setDuration(200); - transition->addAnimation(animation); - - animation = new QPropertyAnimation(thumb, "borderWidth"); - animation->setDuration(400); - transition->addAnimation(animation); - - minState->addTransition(transition); - - transition = new QSignalTransition(slider, SIGNAL(changedToMinimum())); - transition->setTargetState(minState); - - animation = new QPropertyAnimation(thumb, "minFillColor"); - animation->setDuration(200); - transition->addAnimation(animation); - - animation = new QPropertyAnimation(thumb, "haloColor"); - animation->setDuration(200); - transition->addAnimation(animation); - - animation = new QPropertyAnimation(thumb, "borderWidth"); - animation->setDuration(400); - transition->addAnimation(animation); - - normalState->addTransition(transition); - - machine.start(); - - // End of state machine code - - slider->setFocusPolicy(Qt::StrongFocus); + q->setFocusPolicy(Qt::StrongFocus); QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed); - if (slider->orientation() == Qt::Vertical) + if (q->orientation() == Qt::Vertical) sp.transpose(); - slider->setSizePolicy(sp); - slider->setAttribute(Qt::WA_WState_OwnSizePolicy, false); + q->setSizePolicy(sp); + q->setAttribute(Qt::WA_WState_OwnSizePolicy, false); QCoreApplication::processEvents(); } @@ -373,17 +164,17 @@ int SliderPrivate::valueFromPosition(const QPoint &pos) const q->invertedAppearance()); } -void SliderPrivate::setHovered(bool hovered) +void SliderPrivate::setHovered(bool status) { Q_Q(Slider); - if (hover != hovered) { - hover = hovered; + if (hover != status) { + hover = status; if (!q->hasFocus()) { - if (hovered) { - emit q->mouseEnter(); + if (status) { + emit machine->noFocusMouseEnter(); } else { - emit q->mouseLeave(); + emit machine->noFocusMouseLeave(); } } q->update(); diff --git a/components/sliderstatemachine.cpp b/components/sliderstatemachine.cpp new file mode 100644 index 0000000..e7c52af --- /dev/null +++ b/components/sliderstatemachine.cpp @@ -0,0 +1,223 @@ +#include "sliderstatemachine.h" +#include +#include +#include +#include "lib/style.h" +#include "slider.h" +#include "sliderthumb.h" + +SliderStateMachine::SliderStateMachine(Slider *parent, SliderThumb *thumb) + : QStateMachine(parent) +{ + Style &style = Style::instance(); + + QState *topState = new QState(QState::ParallelStates); + + QState *fstState = new QState(topState); + + QState *inactiveState = new QState(fstState); + QState *focusState = new QState(fstState); + QState *slidingState = new QState(fstState); + QState *disabledState = new QState(fstState); + + QState *pulseOutState = new QState(focusState); + QState *pulseInState = new QState(focusState); + + focusState->setInitialState(pulseOutState); + + inactiveState->assignProperty(thumb, "haloSize", 0); + slidingState->assignProperty(thumb, "haloSize", 0); + + pulseOutState->assignProperty(thumb, "haloSize", 35); + pulseInState->assignProperty(thumb, "haloSize", 28); + + disabledState->assignProperty(thumb, "diameter", 7); + disabledState->assignProperty(thumb, "fillColor", style.themeColor("disabled")); + + inactiveState->assignProperty(thumb, "diameter", 11); + focusState->assignProperty(thumb, "diameter", 11); + slidingState->assignProperty(thumb, "diameter", 17); + + QColor fillColor = style.themeColor("primary1"); + + inactiveState->assignProperty(thumb, "fillColor", fillColor); + focusState->assignProperty(thumb, "fillColor", fillColor); + slidingState->assignProperty(thumb, "fillColor", fillColor); + + addState(topState); + + fstState->setInitialState(inactiveState); + + setInitialState(topState); + + QAbstractTransition *transition; + QPropertyAnimation *animation; + + // Add transitions + + transition = new QSignalTransition(this, SIGNAL(sliderDisabled())); + transition->setTargetState(disabledState); + inactiveState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(sliderDisabled())); + transition->setTargetState(disabledState); + focusState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(sliderDisabled())); + transition->setTargetState(disabledState); + slidingState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(sliderEnabled())); + transition->setTargetState(inactiveState); + disabledState->addTransition(transition); + + // Show halo on mouse enter + + transition = new QSignalTransition(this, SIGNAL(noFocusMouseEnter())); + transition->setTargetState(focusState); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + transition->addAnimation(animation); + inactiveState->addTransition(transition); + + // Show halo on focus in + + transition = new QEventTransition(parent, QEvent::FocusIn); + transition->setTargetState(focusState); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + transition->addAnimation(animation); + inactiveState->addTransition(transition); + + // Hide halo on focus out + + transition = new QEventTransition(parent, QEvent::FocusOut); + transition->setTargetState(inactiveState); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + transition->addAnimation(animation); + focusState->addTransition(transition); + + // Hide halo on mouse leave, except if widget has focus + + transition = new QSignalTransition(this, SIGNAL(noFocusMouseLeave())); + transition->setTargetState(inactiveState); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + transition->addAnimation(animation); + focusState->addTransition(transition); + + // Pulse in + + transition = new QSignalTransition(pulseOutState, SIGNAL(propertiesAssigned())); + transition->setTargetState(pulseInState); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + animation->setDuration(1000); + transition->addAnimation(animation); + pulseOutState->addTransition(transition); + + // Pulse out + + transition = new QSignalTransition(pulseInState, SIGNAL(propertiesAssigned())); + transition->setTargetState(pulseOutState); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + animation->setDuration(1000); + transition->addAnimation(animation); + pulseInState->addTransition(transition); + + // Slider pressed + + transition = new QSignalTransition(parent, SIGNAL(sliderPressed())); + transition->setTargetState(slidingState); + transition->addAnimation(new QPropertyAnimation(thumb, "diameter")); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + transition->addAnimation(animation); + focusState->addTransition(transition); + + // Slider released + + transition = new QSignalTransition(parent, SIGNAL(sliderReleased())); + transition->setTargetState(focusState); + transition->addAnimation(new QPropertyAnimation(thumb, "diameter")); + + animation = new QPropertyAnimation(thumb, "haloSize"); + animation->setEasingCurve(QEasingCurve::InOutSine); + transition->addAnimation(animation); + slidingState->addTransition(transition); + + // Min. value transitions + + QState *sndState = new QState(topState); + + QState *minState = new QState(sndState); + QState *normalState = new QState(sndState); + + QColor minHaloColor = style.themeColor("accent3"); + minHaloColor.setAlphaF(0.15); + + QColor haloColor = style.themeColor("primary1"); + haloColor.setAlphaF(0.15); + + QColor canvasColor = style.themeColor("canvas"); + + minState->assignProperty(thumb, "minFillColor", canvasColor); + minState->assignProperty(thumb, "fillColor", canvasColor); + minState->assignProperty(thumb, "haloColor", minHaloColor); + minState->assignProperty(thumb, "borderWidth", 2); + normalState->assignProperty(thumb, "fillColor", fillColor); + normalState->assignProperty(thumb, "minFillColor", fillColor); + normalState->assignProperty(thumb, "haloColor", haloColor); + normalState->assignProperty(thumb, "borderWidth", 0); + + sndState->setInitialState(minState); + + transition = new QSignalTransition(this, SIGNAL(changedFromMinimum())); + transition->setTargetState(normalState); + + animation = new QPropertyAnimation(thumb, "fillColor"); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "haloColor"); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "borderWidth"); + animation->setDuration(400); + transition->addAnimation(animation); + + minState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(changedToMinimum())); + transition->setTargetState(minState); + + animation = new QPropertyAnimation(thumb, "minFillColor"); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "haloColor"); + animation->setDuration(200); + transition->addAnimation(animation); + + animation = new QPropertyAnimation(thumb, "borderWidth"); + animation->setDuration(400); + transition->addAnimation(animation); + + normalState->addTransition(transition); + + start(); +} + +SliderStateMachine::~SliderStateMachine() +{ +} diff --git a/components/sliderstatemachine.h b/components/sliderstatemachine.h new file mode 100644 index 0000000..6780856 --- /dev/null +++ b/components/sliderstatemachine.h @@ -0,0 +1,29 @@ +#ifndef SLIDERSTATEMACHINE_H +#define SLIDERSTATEMACHINE_H + +#include + +class Slider; +class SliderThumb; + +class SliderStateMachine : public QStateMachine +{ + Q_OBJECT + +public: + SliderStateMachine(Slider *parent, SliderThumb *thumb); + ~SliderStateMachine(); + +signals: + void changedToMinimum(); + void changedFromMinimum(); + void sliderEnabled(); + void sliderDisabled(); + void noFocusMouseEnter(); + void noFocusMouseLeave(); + +private: + Q_DISABLE_COPY(SliderStateMachine) +}; + +#endif // SLIDERSTATEMACHINE_H diff --git a/qt-material-widgets.pro b/qt-material-widgets.pro index 4aef75b..f572049 100644 --- a/qt-material-widgets.pro +++ b/qt-material-widgets.pro @@ -53,7 +53,8 @@ SOURCES += main.cpp\ lib/style.cpp \ components/sliderthumb.cpp \ components/searchfield.cpp \ - lib/theme.cpp + lib/theme.cpp \ + components/sliderstatemachine.cpp HEADERS += mainwindow.h \ components/appbar.h \ @@ -102,7 +103,8 @@ HEADERS += mainwindow.h \ components/sliderthumb.h \ components/searchfield.h \ lib/theme.h \ - lib/theme_p.h + lib/theme_p.h \ + components/sliderstatemachine.h RESOURCES += \ resources.qrc