implement toggle state machine

This commit is contained in:
laserpants 2016-05-29 14:58:20 +03:00
parent 1e77ac42a2
commit e97d88b5a9
5 changed files with 112 additions and 1 deletions

View File

@ -1,9 +1,12 @@
#include "toggle.h"
#include <QPainter>
#include <QState>
#include <QEventTransition>
#include "toggle_p.h"
TogglePrivate::TogglePrivate(Toggle *q)
: q_ptr(q),
thumb(new Thumb(q)),
orientation(Qt::Horizontal)
{
}
@ -13,6 +16,37 @@ void TogglePrivate::init()
Q_Q(Toggle);
q->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
QState *offState = new QState;
QState *onState = new QState;
machine.addState(offState);
machine.addState(onState);
machine.setInitialState(offState);
QEventTransition *transition;
transition = new QEventTransition(q, QEvent::MouseButtonPress);
transition->setTargetState(onState);
offState->addTransition(transition);
transition = new QEventTransition(q, QEvent::MouseButtonDblClick);
transition->setTargetState(onState);
offState->addTransition(transition);
transition = new QEventTransition(q, QEvent::MouseButtonPress);
transition->setTargetState(offState);
onState->addTransition(transition);
transition = new QEventTransition(q, QEvent::MouseButtonDblClick);
transition->setTargetState(offState);
onState->addTransition(transition);
offState->assignProperty(thumb, "shift", 0);
onState->assignProperty(thumb, "shift", 1);
machine.start();
}
Toggle::Toggle(QWidget *parent)
@ -35,6 +69,13 @@ QSize Toggle::sizeHint() const
: QSize(48, 64);
}
Qt::Orientation Toggle::orientation() const
{
Q_D(const Toggle);
return d->orientation;
}
void Toggle::setOrientation(Qt::Orientation orientation)
{
Q_D(Toggle);

View File

@ -15,6 +15,7 @@ public:
QSize sizeHint() const;
Qt::Orientation orientation() const;
void setOrientation(Qt::Orientation orientation) Q_DECL_OVERRIDE;
protected:

View File

@ -1,11 +1,64 @@
#include <QPainter>
#include <QEvent>
#include "toggle_internal.h"
#include "toggle.h"
Thumb::Thumb(Toggle *parent)
: QWidget(parent)
: QWidget(parent),
_toggle(parent),
_shift(0),
_offset(0)
{
parent->installEventFilter(this);
}
Thumb::~Thumb()
{
}
void Thumb::setShift(qreal shift)
{
if (_shift == shift)
return;
_shift = shift;
const QSize s(Qt::Horizontal == _toggle->orientation()
? size() : size().transposed());
_offset = shift*static_cast<qreal>(s.width()-s.height());
update();
}
bool Thumb::eventFilter(QObject *obj, QEvent *event)
{
const QEvent::Type type = event->type();
if (QEvent::Resize == type || QEvent::Move == type) {
setGeometry(parentWidget()->rect().adjusted(8, 8, -8, -8));
} //else if (QEvent::MouseButtonRelease == type) {
//return true;
//}
return QWidget::eventFilter(obj, event);
}
void Thumb::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
painter.setBrush(brush);
painter.setPen(Qt::NoPen);
if (Qt::Horizontal == _toggle->orientation()) {
const int s = height()-10;
painter.drawEllipse(5+_offset, 5, s, s);
} else {
const int s = width()-10;
painter.drawEllipse(5, 5+_offset, s, s);
}
}

View File

@ -9,12 +9,25 @@ class Thumb : public QWidget
{
Q_OBJECT
Q_PROPERTY(qreal shift WRITE setShift READ shift)
public:
Thumb(Toggle *parent);
~Thumb();
void setShift(qreal shift);
inline qreal shift() const { return _shift; }
protected:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(Thumb)
Toggle *const _toggle;
qreal _shift;
int _offset;
};
#endif // TOGGLE_INTERNAL_H

View File

@ -1,6 +1,7 @@
#ifndef TOGGLE_P_H
#define TOGGLE_P_H
#include <QStateMachine>
#include "toggle_internal.h"
class TogglePrivate
@ -14,6 +15,8 @@ public:
void init();
Toggle *const q_ptr;
Thumb *const thumb;
QStateMachine machine;
Qt::Orientation orientation;
};