diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-04-22 04:47:24 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-04-22 04:47:24 (GMT) |
commit | 2366667fc97eb6a56203b2dd7dac776ff4164abd (patch) | |
tree | b2acb6cc6bfe475d7e619e4788973b61fff775e0 /examples/statemachine | |
parent | 2c762f3b8b284a7c6dc0c499b7052013bad5b707 (diff) | |
download | Qt-2366667fc97eb6a56203b2dd7dac776ff4164abd.zip Qt-2366667fc97eb6a56203b2dd7dac776ff4164abd.tar.gz Qt-2366667fc97eb6a56203b2dd7dac776ff4164abd.tar.bz2 |
Initial import of kinetic-dui branch from the old kinetic
Diffstat (limited to 'examples/statemachine')
34 files changed, 1890 insertions, 0 deletions
diff --git a/examples/statemachine/README b/examples/statemachine/README new file mode 100644 index 0000000..2879e67 --- /dev/null +++ b/examples/statemachine/README @@ -0,0 +1,36 @@ +Qt is provided with a powerful hierchical finite state machine through +the Qt State Machine classes. + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. diff --git a/examples/statemachine/citizenquartz/citizenquartz.pro b/examples/statemachine/citizenquartz/citizenquartz.pro new file mode 100644 index 0000000..58039a0 --- /dev/null +++ b/examples/statemachine/citizenquartz/citizenquartz.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp \ + clock.cpp \ + clockbutton.cpp \ + clockdisplay.cpp \ + propertyaddstate.cpp \ + +HEADERS += clock.h \ + clockbutton.h \ + clockdisplay.h \ + propertyaddstate.h \ + timeperiod.h \ + +RESOURCES += citizenquartz.qrc +CONFIG += console diff --git a/examples/statemachine/citizenquartz/citizenquartz.qrc b/examples/statemachine/citizenquartz/citizenquartz.qrc new file mode 100644 index 0000000..bcc675a --- /dev/null +++ b/examples/statemachine/citizenquartz/citizenquartz.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>sound/alarm.wav</file> +</qresource> +</RCC>
\ No newline at end of file diff --git a/examples/statemachine/citizenquartz/clock.cpp b/examples/statemachine/citizenquartz/clock.cpp new file mode 100644 index 0000000..51180f5 --- /dev/null +++ b/examples/statemachine/citizenquartz/clock.cpp @@ -0,0 +1,382 @@ +#include "clock.h" +#include "clockbutton.h" +#include "clockdisplay.h" +#include "propertyaddstate.h" +#include "timeperiod.h" + +#include <QStateMachine> +#include <QState> +#include <QHistoryState> + +#include <QPainter> +#include <QTimer> +#include <QSound> + +Clock::Clock(QGraphicsItem *parent) + : QGraphicsItem(parent), + m_stateMachine(0), + m_clockDisplay(0), + m_buttonA(0), + m_buttonB(0), + m_buttonC(0), + m_buttonD(0), + m_alarmState(0), + m_timeState(0), + m_updateState(0), + m_regularState(0), + m_alarmSound(new QSound(":/sound/alarm.wav", this)) +{ +} + +void Clock::initializeUi() +{ + QPainterPath path = shape(); + QPointF pap; + qreal aap; + + m_buttonA = new ClockButton("Button A", this); + pap = path.pointAtPercent(0.05); + aap = path.angleAtPercent(0.05); + m_buttonA->translate(pap.x(), pap.y()); + m_buttonA->rotate(-aap); + connect(m_buttonA, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); + + m_buttonB = new ClockButton("Button B", this); + pap = path.pointAtPercent(0.77); + aap = path.angleAtPercent(0.77); + m_buttonB->translate(pap.x(), pap.y()); + m_buttonB->rotate(-aap); + connect(m_buttonB, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); + + m_buttonC = new ClockButton("Button C", this); + pap = path.pointAtPercent(0.67); + aap = path.angleAtPercent(0.67); + m_buttonC->translate(pap.x(), pap.y()); + m_buttonC->rotate(-aap); + connect(m_buttonC, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); + + m_buttonD = new ClockButton("Button D", this); + pap = path.pointAtPercent(0.57); + aap = path.angleAtPercent(0.57); + m_buttonD->translate(pap.x(), pap.y()); + m_buttonD->rotate(-aap); + connect(m_buttonD, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); + + QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(this); + label->setText("CITIZEN"); + label->setPos(0.0 - label->boundingRect().width() / 2.0, -100.0); + + m_clockDisplay = new ClockDisplay(this); + m_clockDisplay->setCurrentTime(QDateTime::currentDateTime()); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); + timer->setInterval(1); + timer->start(); + m_time.start(); +} + +void Clock::initializeStateMachine() +{ + m_stateMachine = new QStateMachine; + + QState *displays = new QState(m_stateMachine->rootState()); + displays->setObjectName("displays"); + initializeDisplaysState(displays); + + /*QState *alarmsBeep = new QState(m_stateMachine->rootState()); + alarmsBeep->setObjectName("alarmsBeep"); + initializeAlarmsBeepState(alarmsBeep);*/ + + m_stateMachine->setInitialState(displays); + m_stateMachine->start(); +} + +void Clock::initializeUpdateState(QState *updateState) +{ + QState *sec = new QState(updateState); + sec->setObjectName("sec"); + sec->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditSecondMode); + updateState->setInitialState(sec); + + PropertyAddState *secIncrease = new PropertyAddState(updateState); + secIncrease->setObjectName("sec ++"); + secIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setSeconds(1)); + sec->addTransition(m_buttonD, SIGNAL(pressed()), secIncrease); + secIncrease->addTransition(sec); + + QState *oneMin = new QState(updateState); + oneMin->setObjectName("1 min"); + oneMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditMinuteMode); + sec->addTransition(m_buttonC, SIGNAL(pressed()), oneMin); + + PropertyAddState *oneMinIncrease = new PropertyAddState(updateState); + oneMinIncrease->setObjectName("1 min ++"); + oneMinIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setMinutes(1)); + oneMin->addTransition(m_buttonD, SIGNAL(pressed()), oneMinIncrease); + oneMinIncrease->addTransition(oneMin); + + QState *tenMin = new QState(updateState); + tenMin->setObjectName("10 min"); + tenMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditMinuteMode); + oneMin->addTransition(m_buttonC, SIGNAL(pressed()), tenMin); + + PropertyAddState *tenMinIncrease = new PropertyAddState(updateState); + tenMinIncrease->setObjectName("10 min ++"); + tenMinIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setMinutes(10)); + tenMin->addTransition(m_buttonD, SIGNAL(pressed()), tenMinIncrease); + tenMinIncrease->addTransition(tenMin); + + QState *hr = new QState(updateState); + hr->setObjectName("hr"); + hr->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditHourMode); + tenMin->addTransition(m_buttonC, SIGNAL(pressed()), hr); + + PropertyAddState *hrIncrease = new PropertyAddState(updateState); + hrIncrease->setObjectName("hr ++"); + hrIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setHours(1)); + hr->addTransition(m_buttonD, SIGNAL(pressed()), hrIncrease); + hrIncrease->addTransition(hr); + + QState *mon = new QState(updateState); + mon->setObjectName("mon"); + mon->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditMonthMode); + hr->addTransition(m_buttonC, SIGNAL(pressed()), mon); + + PropertyAddState *monIncrease = new PropertyAddState(updateState); + monIncrease->setObjectName("mon ++"); + monIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setMonths(1)); + mon->addTransition(m_buttonD, SIGNAL(pressed()), monIncrease); + monIncrease->addTransition(mon); + + QState *day = new QState(updateState); + day->setObjectName("day"); + day->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditDayMode); + mon->addTransition(m_buttonC, SIGNAL(pressed()), day); + + PropertyAddState *dayIncrease = new PropertyAddState(updateState); + dayIncrease->setObjectName("day ++"); + dayIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setDays(1)); + day->addTransition(m_buttonD, SIGNAL(pressed()), dayIncrease); + dayIncrease->addTransition(day); + + QState *year = new QState(updateState); + year->setObjectName("year"); + year->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditYearMode); + day->addTransition(m_buttonC, SIGNAL(pressed()), year); + + PropertyAddState *yearIncrease = new PropertyAddState(updateState); + yearIncrease->setObjectName("year ++"); + yearIncrease->addToProperty(m_clockDisplay, "currentTime", + TimePeriod().setYears(1)); + year->addTransition(m_buttonD, SIGNAL(pressed()), yearIncrease); + yearIncrease->addTransition(year); + year->addTransition(m_buttonC, SIGNAL(pressed()), m_timeState); +} + +void Clock::initializeRegularState(QState *regular) +{ + m_timeState = new QState(regular); + m_timeState->setObjectName("time"); + m_timeState->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::CurrentTimeMode); + + QState *date = new QState(regular); + date->setObjectName("date"); + date->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::CurrentDateMode); + + QState *dateTimerState = new QState(date); + dateTimerState->setObjectName("dateTimerState"); + + // Date state exits after 2 m + QTimer *dateTimer = new QTimer(dateTimerState); + dateTimer->setSingleShot(true); + dateTimer->setInterval(2*60000); + dateTimerState->invokeMethodOnEntry(dateTimer, "start"); + dateTimerState->invokeMethodOnExit(dateTimer, "stop"); + + date->setInitialState(dateTimerState); + + m_updateState = new QState(regular); + m_updateState->setObjectName("update"); + + // Update state exits after 2 m + QTimer *updateTimer = new QTimer(m_updateState); + updateTimer->setSingleShot(true); + updateTimer->setInterval(2 * 60000); + m_updateState->invokeMethodOnEntry(updateTimer, "start"); + m_updateState->invokeMethodOnExit(updateTimer, "stop"); + + initializeUpdateState(m_updateState); + + m_timeState->addTransition(m_buttonD, SIGNAL(pressed()), date); + date->addTransition(m_buttonD, SIGNAL(pressed()), m_timeState); + date->addTransition(dateTimer, SIGNAL(timeout()), m_timeState); + + m_updateState->addTransition(updateTimer, SIGNAL(timeout()), m_timeState); + m_updateState->addTransition(m_buttonB, SIGNAL(pressed()), m_timeState); + + regular->setInitialState(m_timeState); +} + +void Clock::initializeAlarmUpdateState(QState *update) +{ + QState *hr = new QState(update); + hr->setObjectName("hr"); + hr->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditAlarmHourMode); + + PropertyAddState *hrInc = new PropertyAddState(update); + hrInc->setObjectName("hr ++"); + hrInc->addToProperty(m_clockDisplay, "alarm", TimePeriod().setHours(1)); + hr->addTransition(m_buttonD, SIGNAL(pressed()), hrInc); + hrInc->addTransition(hr); + + QState *tenMin = new QState(update); + tenMin->setObjectName("10 min"); + tenMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditAlarmTenMinuteMode); + hr->addTransition(m_buttonC, SIGNAL(pressed()), tenMin); + + PropertyAddState *tenMinInc = new PropertyAddState(update); + tenMinInc->setObjectName("10 min ++"); + tenMinInc->addToProperty(m_clockDisplay, "alarm", TimePeriod().setMinutes(10)); + tenMin->addTransition(m_buttonD, SIGNAL(pressed()), tenMinInc); + tenMinInc->addTransition(tenMin); + + QState *oneMin = new QState(update); + oneMin->setObjectName("1 min"); + oneMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditAlarmMinuteMode); + tenMin->addTransition(m_buttonC, SIGNAL(pressed()), oneMin); + + PropertyAddState *oneMinInc = new PropertyAddState(update); + oneMinInc->setObjectName("1 min ++"); + oneMinInc->addToProperty(m_clockDisplay, "alarm", TimePeriod().setMinutes(1)); + oneMin->addTransition(m_buttonD, SIGNAL(pressed()), oneMinInc); + oneMinInc->addTransition(oneMin); + + oneMin->addTransition(m_buttonC, SIGNAL(pressed()), m_alarmState); + m_alarmState->addTransition(m_buttonC, SIGNAL(pressed()), hr); +} + +void Clock::initializeOutState(QState *out) +{ + m_alarmState = new QState(out); + m_alarmState->setObjectName("alarmState"); + m_alarmState->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::AlarmMode); + initializeAlarmState(m_alarmState); + out->setInitialState(m_alarmState); + + QState *alarmUpdate = new QState(out); + alarmUpdate->setObjectName("alarmUpdate"); + initializeAlarmUpdateState(alarmUpdate); + + alarmUpdate->addTransition(m_buttonB, SIGNAL(pressed()), m_alarmState); + m_alarmState->addTransition(m_buttonA, SIGNAL(pressed()), m_regularState); +} + +void Clock::initializeDisplaysState(QState *displays) +{ + m_regularState = new QState(displays); + m_regularState->setObjectName("regular"); + initializeRegularState(m_regularState); + displays->setInitialState(m_regularState); + + QState *out = new QState(displays); + out->setObjectName("out"); + + QTimer *outTimer = new QTimer(out); + outTimer->setSingleShot(true); + outTimer->setInterval(2 * 60000); + out->invokeMethodOnEntry(outTimer, "start"); + out->invokeMethodOnExit(outTimer, "stop"); + + initializeOutState(out); + + QState *wait = new QState(displays); + wait->setObjectName("wait"); + + QTimer *waitTimer = new QTimer(wait); + waitTimer->setSingleShot(true); + waitTimer->setInterval(2000); + wait->invokeMethodOnEntry(waitTimer, "start"); + wait->invokeMethodOnExit(waitTimer, "stop"); + + m_timeState->addTransition(m_buttonC, SIGNAL(pressed()), wait); + wait->addTransition(waitTimer, SIGNAL(timeout()), m_updateState); + wait->addTransition(m_buttonC, SIGNAL(released()), m_timeState); + m_timeState->addTransition(m_buttonA, SIGNAL(pressed()), m_alarmState); + out->addTransition(outTimer, SIGNAL(timeout()), m_regularState); +} + +void Clock::initializeAlarmState(QState *alarmState) +{ + QState *offState = new QState(alarmState); + offState->setObjectName("alarmOff"); + offState->setPropertyOnEntry(m_clockDisplay, "alarmEnabled", false); + + QState *onState = new QState(alarmState); + onState->setObjectName("alarmOn"); + onState->setPropertyOnEntry(m_clockDisplay, "alarmEnabled", true); + + QHistoryState *history = alarmState->addHistoryState(); + history->setObjectName("alarmHistory"); + history->setDefaultState(onState); + + offState->addTransition(m_buttonD, SIGNAL(pressed()), onState); + onState->addTransition(m_buttonD, SIGNAL(pressed()), offState); + + QState *intermediate = new QState(alarmState); + intermediate->addTransition(history); + + alarmState->setInitialState(intermediate); +} + +QRectF Clock::boundingRect() const +{ + return shape().boundingRect(); +} + +QPainterPath Clock::shape() const +{ + QPainterPath path; + path.addRoundedRect(QRectF(-140.0, -100.0, 280.0, 200.0), 50.0, 50.0, Qt::RelativeSize); + + return path; +} + +void Clock::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->setPen(Qt::black); + painter->setBrush(Qt::NoBrush); + + // Clock face + painter->drawPath(shape()); +} + +void Clock::updateTime() +{ + int elapsed = m_time.elapsed(); + if (elapsed > 0) { + m_time.restart(); + QDateTime currentTime = m_clockDisplay->currentTime(); + m_clockDisplay->setCurrentTime(currentTime.addMSecs(elapsed)); + + update(); + } +} + +void Clock::playSound() +{ + m_alarmSound->stop(); + m_alarmSound->play(); +} + +void Clock::stopSound() +{ + m_alarmSound->stop(); +} + diff --git a/examples/statemachine/citizenquartz/clock.h b/examples/statemachine/citizenquartz/clock.h new file mode 100644 index 0000000..aee1b55 --- /dev/null +++ b/examples/statemachine/citizenquartz/clock.h @@ -0,0 +1,60 @@ +#ifndef CLOCK_H +#define CLOCK_H + +#include <QGraphicsItem> +#include <QTime> + +class ClockButton ; +class ClockDisplay ; +class QStateMachine ; +class QState ; +class QTimerState ; +class QSound ; + +class Clock: public QObject, public QGraphicsItem +{ + Q_OBJECT +public: + Clock(QGraphicsItem *parent = 0); + + void initializeUi(); + void initializeStateMachine(); + + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +signals: + void alarm(); + void anyButtonPressed(); + +public slots: + void updateTime(); + void playSound(); + void stopSound(); + +private: + void initializeDisplaysState(QState *displays); + void initializeAlarmState(QState *alarmState); + void initializeRegularState(QState *regular); + void initializeUpdateState(QState *update); + void initializeOutState(QState *out); + void initializeAlarmUpdateState(QState *update); + + QStateMachine *m_stateMachine; + ClockDisplay *m_clockDisplay; + ClockButton *m_buttonA; + ClockButton *m_buttonB; + ClockButton *m_buttonC; + ClockButton *m_buttonD; + + QState *m_alarmState; + QState *m_timeState; + QState *m_updateState; + QState *m_regularState; + + QSound *m_alarmSound; + QTime m_time; +}; + +#endif // CLOCK_H diff --git a/examples/statemachine/citizenquartz/clockbutton.cpp b/examples/statemachine/citizenquartz/clockbutton.cpp new file mode 100644 index 0000000..7b86891 --- /dev/null +++ b/examples/statemachine/citizenquartz/clockbutton.cpp @@ -0,0 +1,39 @@ +#include "clockbutton.h" + +#include <QPainter> + +ClockButton::ClockButton(const QString &name, QGraphicsItem *parent) : QGraphicsItem(parent) +{ + setObjectName(name); + setToolTip(name); + setAcceptedMouseButtons(Qt::LeftButton); +} + +QRectF ClockButton::boundingRect() const +{ + return QRectF(-10.0, -10.0, 20.0, 20.0); +} + +QPainterPath ClockButton::shape() const +{ + QPainterPath path; + path.addRoundedRect(boundingRect(), 15.0, 15.0, Qt::RelativeSize); + + return path; +} + +void ClockButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->setBrush(Qt::black); + painter->drawPath(shape()); +} + +void ClockButton::mousePressEvent(QGraphicsSceneMouseEvent *) +{ + emit pressed(); +} + +void ClockButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + emit released(); +}
\ No newline at end of file diff --git a/examples/statemachine/citizenquartz/clockbutton.h b/examples/statemachine/citizenquartz/clockbutton.h new file mode 100644 index 0000000..02a7ccd --- /dev/null +++ b/examples/statemachine/citizenquartz/clockbutton.h @@ -0,0 +1,25 @@ +#ifndef CLOCKBUTTON_H +#define CLOCKBUTTON_H + +#include <QGraphicsItem> + +class ClockButton: public QObject, public QGraphicsItem +{ + Q_OBJECT +public: + ClockButton(const QString &name, QGraphicsItem *parent = 0); + + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + +protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +signals: + void pressed(); + void released(); +}; + +#endif //CLOCKBUTTON_H diff --git a/examples/statemachine/citizenquartz/clockdisplay.cpp b/examples/statemachine/citizenquartz/clockdisplay.cpp new file mode 100644 index 0000000..717b881 --- /dev/null +++ b/examples/statemachine/citizenquartz/clockdisplay.cpp @@ -0,0 +1,140 @@ +#include "clockdisplay.h" + +#include <QPainter> +#include <QTimer> + +ClockDisplay::ClockDisplay(QGraphicsItem *parent) + : QGraphicsItem(parent), + m_displayMode(CurrentTimeMode), + m_currentTime(QDate(1970, 1, 1), QTime(0, 0)), + m_alarm(0, 0), + m_alarmEnabled(false), + m_blink(false) + +{ + m_text = new QGraphicsTextItem(this); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(toggleBlinkFlag())); + timer->start(500); + + QFont font = m_text->font(); + font.setPointSizeF(20.0); + m_text->setFont(font); + + m_text->translate(-100.0, -20.0); + + QPixmap pm(":/images/alarm.png"); + m_alarmSymbol = new QGraphicsPixmapItem(pm, this); + m_alarmSymbol->translate(-100.0, -60.0); + m_alarmSymbol->setOffset(5.0, 5.0); + m_alarmSymbol->scale(0.5, 0.5); +} + +ClockDisplay::~ClockDisplay() +{ +} + +void ClockDisplay::toggleBlinkFlag() +{ + m_blink = !m_blink; + update(); +} + +void ClockDisplay::updateText() +{ + switch (m_displayMode) { + case EditSecondMode: + if (m_blink) { + m_text->setHtml(m_currentTime.toString("hh:mm:'<font color=\"transparent\">'ss'</font>'")); + break; + } + // fall throoough + case EditMinuteMode: + if (m_blink) { + m_text->setHtml(m_currentTime.toString("hh:'<font color=\"transparent\">'mm'</font>':ss")); + break; + } + + // fall throoough + case EditHourMode: + if (m_blink) { + m_text->setHtml(m_currentTime.toString("'<font color=\"transparent\">'hh'</font>':mm:ss")); + break; + } + + // fall throoough + case CurrentTimeMode: + m_text->setHtml(m_currentTime.toString("hh:mm:ss")); + break; + + case EditMonthMode: + if (m_blink) { + m_text->setHtml(m_currentTime.toString("yyyy.'<font color=\"transparent\">'MM'</font>'.dd")); + break; + } + + // fall throoough + case EditDayMode: + if (m_blink) { + m_text->setHtml(m_currentTime.toString("yyyy.MM.'<font color=\"transparent\">'dd'</font>'")); + break; + } + + // fall throoough + case EditYearMode: + if (m_blink) { + m_text->setHtml(m_currentTime.toString("'<font color=\"transparent\">'yyyy'</font>'.MM.dd")); + break; + } + + // fall throoough + case CurrentDateMode: + m_text->setHtml(m_currentTime.toString("yyyy.MM.dd")); + break; + + case EditAlarmHourMode: + if (m_blink) { + m_text->setHtml(m_alarm.toString("'<font color=\"transparent\">'hh'</font>':mm")); + break; + } + + // fall throooough + case EditAlarmTenMinuteMode: + case EditAlarmMinuteMode: + if (m_blink) { + m_text->setHtml(m_alarm.toString("hh:'<font color=\"transparent\">'mm'</font>'")); + break; + } + + // fall throoough + case AlarmMode: + m_text->setHtml(m_alarm.toString("hh:mm")); + break; + + default: + m_text->setHtml("Not implemented"); + }; +} + +QRectF ClockDisplay::boundingRect() const +{ + return QRectF(-100.0, -60.0, 200.0, 120.0); +} + +void ClockDisplay::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + if (m_alarmEnabled) + m_alarmSymbol->setVisible(true); + + updateText(); + + // Screen + painter->drawRoundedRect(boundingRect(), 15.0, 15.0, Qt::RelativeSize); + + // Button grid + painter->drawLine(QPointF(-100.0, -20.0), QPointF(100.0, -20.0)); + painter->drawLine(QPointF(-50.0, -60.0), QPointF(-50.0, -20.0)); + painter->drawLine(QPointF(0.0, -60.0), QPointF(0.0, -20.0)); + painter->drawLine(QPointF(50.0, -60.0), QPointF(50.0, -20.0)); +} diff --git a/examples/statemachine/citizenquartz/clockdisplay.h b/examples/statemachine/citizenquartz/clockdisplay.h new file mode 100644 index 0000000..e0ac8bb --- /dev/null +++ b/examples/statemachine/citizenquartz/clockdisplay.h @@ -0,0 +1,75 @@ +#ifndef CLOCKDISPLAY_H +#define CLOCKDISPLAY_H + +#include <QObject> +#include <QGraphicsItem> +#include <QDateTime> + +class ClockDisplay: public QObject, public QGraphicsItem +{ + Q_OBJECT + Q_ENUMS(DisplayMode) + Q_PROPERTY(DisplayMode displayMode READ displayMode WRITE setDisplayMode) + Q_PROPERTY(QDateTime currentTime READ currentTime WRITE setCurrentTime) + Q_PROPERTY(QTime alarm READ alarm WRITE setAlarm) + Q_PROPERTY(bool alarmEnabled READ alarmEnabled WRITE setAlarmEnabled) +public: + enum DisplayMode { + CurrentTimeMode, + EditSecondMode, + EditMinuteMode, + EditHourMode, + + CurrentDateMode, + EditMonthMode, + EditDayMode, + EditYearMode, + + AlarmMode, + EditAlarmHourMode, + EditAlarmTenMinuteMode, + EditAlarmMinuteMode, + + ChimeMode, + StopWatchMode, + ModeCount + }; + + ClockDisplay(QGraphicsItem *parent = 0); + virtual ~ClockDisplay(); + + void setDisplayMode(DisplayMode displayMode) { m_displayMode = displayMode; update(); } + DisplayMode displayMode() const { return m_displayMode; } + + QDateTime currentTime() const { return m_currentTime; } + void setCurrentTime(const QDateTime &time) { m_currentTime = time; update(); } + + QTime alarm() const { return m_alarm; } + void setAlarm(const QTime &time) { m_alarm = time; update(); } + + bool alarmEnabled() const { return m_alarmEnabled; } + void setAlarmEnabled(bool enabled) { m_alarmEnabled = enabled; update(); } + + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + +private slots: + void toggleBlinkFlag(); + +private: + void updateText(); + + DisplayMode m_displayMode; + + QDateTime m_currentTime; + QTime m_alarm; + + QGraphicsTextItem *m_text; + QGraphicsPixmapItem *m_alarmSymbol; + + uint m_alarmEnabled : 1; + uint m_blink : 1; + uint m_reserved : 30; +}; + +#endif diff --git a/examples/statemachine/citizenquartz/images/alarm.png b/examples/statemachine/citizenquartz/images/alarm.png Binary files differnew file mode 100644 index 0000000..a19778d --- /dev/null +++ b/examples/statemachine/citizenquartz/images/alarm.png diff --git a/examples/statemachine/citizenquartz/main.cpp b/examples/statemachine/citizenquartz/main.cpp new file mode 100644 index 0000000..2c6b14c --- /dev/null +++ b/examples/statemachine/citizenquartz/main.cpp @@ -0,0 +1,23 @@ +#include <QApplication> +#include <QGraphicsScene> +#include <QGraphicsView> + +#include "clock.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + QGraphicsScene scene; + + Clock *clock = new Clock; + clock->initializeUi(); + clock->initializeStateMachine(); + scene.addItem(clock); + + QGraphicsView view(&scene); + view.setRenderHint(QPainter::Antialiasing); + view.show(); + + return app.exec(); +} diff --git a/examples/statemachine/citizenquartz/propertyaddstate.cpp b/examples/statemachine/citizenquartz/propertyaddstate.cpp new file mode 100644 index 0000000..f129c8d --- /dev/null +++ b/examples/statemachine/citizenquartz/propertyaddstate.cpp @@ -0,0 +1,46 @@ +#include "PropertyAddState.h" +#include "timeperiod.h" + +#include <QDateTime> +#include <QDebug> + +PropertyAddState::PropertyAddState(QState *parent) + : QState(parent) +{ +} + +void PropertyAddState::addToProperty(QObject *object, const char *propertyName, + const QVariant &valueToAdd) +{ + m_propertyAdditions.append(PropertyAdder(object, propertyName, valueToAdd)); +} + +QVariant PropertyAddState::addProperties(const QVariant ¤t, const QVariant &toAdd) const +{ + QVariant result; + switch (current.type()) { + case QVariant::DateTime: + result = current.toDateTime() + qvariant_cast<TimePeriod>(toAdd); + break; + case QVariant::Time: + result = current.toTime() + qvariant_cast<TimePeriod>(toAdd); + break; + default: + qWarning("PropertyAddState::addProperties: QVariant type '%s' not supported", + current.typeName()); + }; + + return result; +} + +void PropertyAddState::onEntry() +{ + foreach (PropertyAdder propertyAdder, m_propertyAdditions) { + QObject *object = propertyAdder.object; + const char *propertyName = propertyAdder.propertyName; + QVariant toAdd = propertyAdder.valueToAdd; + QVariant current = object->property(propertyName); + + object->setProperty(propertyName, addProperties(current, toAdd)); + } +} diff --git a/examples/statemachine/citizenquartz/propertyaddstate.h b/examples/statemachine/citizenquartz/propertyaddstate.h new file mode 100644 index 0000000..96f45fc --- /dev/null +++ b/examples/statemachine/citizenquartz/propertyaddstate.h @@ -0,0 +1,33 @@ +#ifndef PropertyAddState_H +#define PropertyAddState_H + +#include <qstate.h> + +#include <QVariant> +#include <QList> + +class PropertyAddState: public QState +{ +public: + PropertyAddState(QState *parent = 0); + + void addToProperty(QObject *object, const char *propertyName, const QVariant &valueToAdd); + virtual void onEntry(); + +private: + QVariant addProperties(const QVariant ¤t, const QVariant &toAdd) const; + + struct PropertyAdder { + PropertyAdder(QObject *_object, const char *_propertyName, const QVariant &_valueToAdd) + : object(_object), propertyName(_propertyName), valueToAdd(_valueToAdd) + { + } + + QObject *object; + const char *propertyName; + QVariant valueToAdd; + }; + QList<PropertyAdder> m_propertyAdditions; +}; + +#endif // PropertyAddState_H diff --git a/examples/statemachine/citizenquartz/sound/alarm.wav b/examples/statemachine/citizenquartz/sound/alarm.wav Binary files differnew file mode 100644 index 0000000..1d9486f --- /dev/null +++ b/examples/statemachine/citizenquartz/sound/alarm.wav diff --git a/examples/statemachine/citizenquartz/timeperiod.h b/examples/statemachine/citizenquartz/timeperiod.h new file mode 100644 index 0000000..a64c17c --- /dev/null +++ b/examples/statemachine/citizenquartz/timeperiod.h @@ -0,0 +1,84 @@ +#ifndef TIMEPERIOD_H +#define TIMEPERIOD_H + +#include <QDateTime> +#include <QTime> +#include <QDebug> + +class TimePeriod +{ +public: + TimePeriod() : m_seconds(0), m_minutes(0), m_hours(0), m_days(0), m_months(0), m_years(0) + { + } + + TimePeriod &setSeconds(int seconds) { m_seconds = seconds; return *this; } + int seconds() const { return m_seconds; } + + TimePeriod &setMinutes(int minutes) { m_minutes = minutes; return *this; } + int minutes() const { return m_minutes; } + + TimePeriod &setHours(int hours) { m_hours = hours; return *this; } + int hours() const { return m_hours; } + + TimePeriod &setDays(int days) { m_days = days; return *this; } + int days() const { return m_days; } + + TimePeriod &setMonths(int months) { m_months = months; return *this; } + int months() const { return m_months; } + + TimePeriod &setYears(int years) { m_years = years; return *this; } + int years() const { return m_years; } + + operator QVariant() const + { + QVariant v; + qVariantSetValue<TimePeriod>(v, *this); + return v; + } + +private: + int m_seconds; + int m_minutes; + int m_hours; + int m_days; + int m_months; + int m_years; +}; + +inline void operator+=(QDateTime &dateTime, const TimePeriod &timePeriod) +{ + dateTime = dateTime.addSecs(timePeriod.seconds()); + dateTime = dateTime.addSecs(timePeriod.minutes() * 60); + dateTime = dateTime.addSecs(timePeriod.hours() * 3600); + dateTime = dateTime.addDays(timePeriod.days()); + dateTime = dateTime.addMonths(timePeriod.months()); + dateTime = dateTime.addYears(timePeriod.years()); +} + +inline QDateTime operator+(const QDateTime &dateTime, const TimePeriod &timePeriod) +{ + QDateTime result(dateTime); + result += timePeriod; + + return result; +} + +inline void operator+=(QTime &time, const TimePeriod &timePeriod) +{ + time = time.addSecs(timePeriod.seconds()); + time = time.addSecs(timePeriod.minutes() * 60); + time = time.addSecs(timePeriod.hours() * 3600); +} + +inline QTime operator+(const QTime &time, const TimePeriod &timePeriod) +{ + QTime result(time); + result += timePeriod; + + return time; +} + +Q_DECLARE_METATYPE(TimePeriod) + +#endif \\ TIMEPERIOD_H diff --git a/examples/statemachine/clockticking/clockticking.pro b/examples/statemachine/clockticking/clockticking.pro new file mode 100644 index 0000000..bff9cb8 --- /dev/null +++ b/examples/statemachine/clockticking/clockticking.pro @@ -0,0 +1,10 @@ +QT = core +TEMPLATE = app +TARGET = +win32: CONFIG += console +mac:CONFIG -= app_bundle +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/clockticking/main.cpp b/examples/statemachine/clockticking/main.cpp new file mode 100644 index 0000000..e903988 --- /dev/null +++ b/examples/statemachine/clockticking/main.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <stdio.h> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstatemachine.h> +#include <qstate.h> +#include <qtransition.h> +#endif + +class ClockEvent : public QEvent +{ +public: + ClockEvent() : QEvent(QEvent::Type(QEvent::User+2)) + {} +}; + +class ClockState : public QState +{ +public: + ClockState(QStateMachine *machine, QState *parent) + : QState(parent), m_machine(machine) {} + +protected: + virtual void onEntry() + { + fprintf(stdout, "ClockState entered; posting the initial tick\n"); + m_machine->postEvent(new ClockEvent()); + } + +private: + QStateMachine *m_machine; +}; + +class ClockTransition : public QAbstractTransition +{ +public: + ClockTransition(QStateMachine *machine) + : QAbstractTransition(), m_machine(machine) { } + +protected: + virtual bool eventTest(QEvent *e) const { + return (e->type() == QEvent::User+2); + } + virtual void onTransition() + { + fprintf(stdout, "ClockTransition triggered; posting another tick with a delay of 1 second\n"); + m_machine->postEvent(new ClockEvent(), 1000); + } + +private: + QStateMachine *m_machine; +}; + +class ClockListener : public QAbstractTransition +{ +public: + ClockListener() + : QAbstractTransition() {} + +protected: + virtual bool eventTest(QEvent *e) const { + return (e->type() == QEvent::User+2); + } + virtual void onTransition() + { + fprintf(stdout, "ClockListener heard a tick!\n"); + } +}; + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + QStateMachine machine; + QState *group = new QState(QState::ParallelGroup); + group->setObjectName("group"); + + ClockState *clock = new ClockState(&machine, group); + clock->setObjectName("clock"); + clock->addTransition(new ClockTransition(&machine)); + + QState *listener = new QState(group); + listener->setObjectName("listener"); + listener->addTransition(new ClockListener()); + + machine.addState(group); + machine.setInitialState(group); + machine.start(); + + return app.exec(); +} diff --git a/examples/statemachine/composition/composition.pro b/examples/statemachine/composition/composition.pro new file mode 100644 index 0000000..6a976cb --- /dev/null +++ b/examples/statemachine/composition/composition.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/composition/main.cpp b/examples/statemachine/composition/main.cpp new file mode 100644 index 0000000..892542d --- /dev/null +++ b/examples/statemachine/composition/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstatemachine.h> +#include <qstate.h> +#include <qfinalstate.h> +#endif + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + QLabel label; + label.setAlignment(Qt::AlignCenter); + + QStateMachine machine; + + QState *s1 = new QState(); + s1->setObjectName("s1"); + s1->setPropertyOnEntry(&label, "text", "In S1, hang on..."); + s1->setPropertyOnEntry(&label, "geometry", QRect(100, 100, 200, 100)); + + QState *s1_timer = new QState(s1); + s1_timer->setObjectName("s1_timer"); + QTimer t1; + t1.setInterval(2000); + s1_timer->invokeMethodOnEntry(&t1, "start"); + QFinalState *s1_done = new QFinalState(s1); + s1_done->setObjectName("s1_done"); + s1_timer->addTransition(&t1, SIGNAL(timeout()), s1_done); + s1->setInitialState(s1_timer); + + QState *s2 = new QState(); + s2->setObjectName("s2"); + s2->setPropertyOnEntry(&label, "text", "In S2, I'm gonna quit on you..."); + s2->setPropertyOnEntry(&label, "geometry", QRect(300, 300, 300, 100)); +// s2->invokeMethodOnEntry(&label, "setNum", QList<QVariant>() << 123); +// s2->invokeMethodOnEntry(&label, "showMaximized"); + + QState *s2_timer = new QState(s2); + s2_timer->setObjectName("s2_timer"); + QTimer t2; + t2.setInterval(2000); + s2_timer->invokeMethodOnEntry(&t2, "start"); + QFinalState *s2_done = new QFinalState(s2); + s2_done->setObjectName("s2_done"); + s2_timer->addTransition(&t2, SIGNAL(timeout()), s2_done); + s2->setInitialState(s2_timer); + + s1->addFinishedTransition(s2); + + QFinalState *s3 = new QFinalState(); + s3->setObjectName("s3"); + s2->addFinishedTransition(s3); + + machine.addState(s1); + machine.addState(s2); + machine.addState(s3); + machine.setInitialState(s1); + QObject::connect(&machine, SIGNAL(finished()), &app, SLOT(quit())); + machine.start(); + + label.show(); + return app.exec(); +} diff --git a/examples/statemachine/eventtransitions/eventtransitions.pro b/examples/statemachine/eventtransitions/eventtransitions.pro new file mode 100644 index 0000000..6a976cb --- /dev/null +++ b/examples/statemachine/eventtransitions/eventtransitions.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/eventtransitions/main.cpp b/examples/statemachine/eventtransitions/main.cpp new file mode 100644 index 0000000..51b2d82 --- /dev/null +++ b/examples/statemachine/eventtransitions/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstatemachine.h> +#include <qstate.h> +#include <qeventtransition.h> +#endif + +class Window : public QWidget +{ +public: + Window(QWidget *parent = 0) + : QWidget(parent) + { + QPushButton *button = new QPushButton(this); + button->setGeometry(QRect(100, 100, 100, 100)); + + QStateMachine *machine = new QStateMachine(this); + + QState *s1 = new QState(); + s1->setPropertyOnEntry(button, "text", "Outside"); + + QState *s2 = new QState(); + s2->setPropertyOnEntry(button, "text", "Inside"); + + QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter); + enterTransition->setTargetState(s2); + s1->addTransition(enterTransition); + + QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave); + leaveTransition->setTargetState(s1); + s2->addTransition(leaveTransition); + + QState *s3 = new QState(); + s3->setPropertyOnEntry(button, "text", "Pressing..."); + + QEventTransition *pressTransition = new QEventTransition(button, QEvent::MouseButtonPress); + pressTransition->setTargetState(s3); + s2->addTransition(pressTransition); + + QEventTransition *releaseTransition = new QEventTransition(button, QEvent::MouseButtonRelease); + releaseTransition->setTargetState(s2); + s3->addTransition(releaseTransition); + + machine->addState(s1); + machine->addState(s2); + machine->addState(s3); + machine->setInitialState(s1); + QObject::connect(machine, SIGNAL(finished()), qApp, SLOT(quit())); + machine->start(); + } +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window window; + window.resize(300, 300); + window.show(); + + return app.exec(); +} diff --git a/examples/statemachine/factorial/factorial.pro b/examples/statemachine/factorial/factorial.pro new file mode 100644 index 0000000..ac79117 --- /dev/null +++ b/examples/statemachine/factorial/factorial.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +QT = core +win32: CONFIG += console +mac:CONFIG -= app_bundle +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp new file mode 100644 index 0000000..985b09f --- /dev/null +++ b/examples/statemachine/factorial/main.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <stdio.h> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstatemachine.h> +#include <qstate.h> +#include <qsignaltransition.h> +#include <qfinalstate.h> +#endif + +class Factorial : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x READ x WRITE setX) + Q_PROPERTY(int fac READ fac WRITE setFac) +public: + Factorial(QObject *parent = 0) + : QObject(parent) + { + m_fac = 1; + m_x = -1; + } + + int x() const + { + return m_x; + } + + void setX(int x) + { + if (x == m_x) + return; + m_x = x; + emit xChanged(); + } + + int fac() const + { + return m_fac; + } + + void setFac(int fac) + { + m_fac = fac; + } + +Q_SIGNALS: + void xChanged(); + +private: + int m_x; + int m_fac; +}; + +class FactorialLoopTransition : public QSignalTransition +{ +public: + FactorialLoopTransition(Factorial *fact) + : QSignalTransition(fact, SIGNAL(xChanged())), m_fact(fact) + {} + + virtual bool eventTest(QEvent *) const + { + return m_fact->property("x").toInt() > 1; + } + + virtual void onTransition() + { + int x = m_fact->property("x").toInt(); + int fac = m_fact->property("fac").toInt(); + m_fact->setProperty("fac", x * fac); + m_fact->setProperty("x", x - 1); + } + +private: + Factorial *m_fact; +}; + +class FactorialDoneTransition : public QSignalTransition +{ +public: + FactorialDoneTransition(Factorial *fact) + : QSignalTransition(fact, SIGNAL(xChanged())), m_fact(fact) + {} + + virtual bool eventTest(QEvent *) const + { + return m_fact->property("x").toInt() <= 1; + } + + virtual void onTransition() + { + fprintf(stdout, "%d\n", m_fact->property("fac").toInt()); + } + +private: + Factorial *m_fact; +}; + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + Factorial factorial; + + QStateMachine machine; + + QState *computing = new QState(machine.rootState()); + computing->addTransition(new FactorialLoopTransition(&factorial)); + + QFinalState *done = new QFinalState(machine.rootState()); + FactorialDoneTransition *doneTransition = new FactorialDoneTransition(&factorial); + doneTransition->setTargetState(done); + computing->addTransition(doneTransition); + + QState *initialize = new QState(machine.rootState()); + initialize->setPropertyOnEntry(&factorial, "x", 6); + FactorialLoopTransition *enterLoopTransition = new FactorialLoopTransition(&factorial); + enterLoopTransition->setTargetState(computing); + initialize->addTransition(enterLoopTransition); + + QObject::connect(&machine, SIGNAL(finished()), &app, SLOT(quit())); + + machine.setInitialState(initialize); + machine.start(); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/statemachine/helloworld/helloworld.pro b/examples/statemachine/helloworld/helloworld.pro new file mode 100644 index 0000000..ac79117 --- /dev/null +++ b/examples/statemachine/helloworld/helloworld.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +QT = core +win32: CONFIG += console +mac:CONFIG -= app_bundle +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/helloworld/main.cpp b/examples/statemachine/helloworld/main.cpp new file mode 100644 index 0000000..a124623 --- /dev/null +++ b/examples/statemachine/helloworld/main.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstatemachine.h> +#include <qstate.h> +#include <qfinalstate.h> +#endif + +class S0 : public QState +{ +public: + S0(QState *parent = 0) + : QState(parent) {} + + virtual void onEntry() + { + fprintf(stdout, "Hello world!\n"); + } +}; + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + QStateMachine machine; + QState *s0 = new S0(); + QFinalState *s1 = new QFinalState(); + s0->addTransition(s1); + + machine.addState(s0); + machine.addState(s1); + machine.setInitialState(s0); + + QObject::connect(&machine, SIGNAL(finished()), QCoreApplication::instance(), SLOT(quit())); + machine.start(); + + return app.exec(); +} diff --git a/examples/statemachine/pauseandresume/main.cpp b/examples/statemachine/pauseandresume/main.cpp new file mode 100644 index 0000000..7aed84b --- /dev/null +++ b/examples/statemachine/pauseandresume/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstatemachine.h> +#include <qstate.h> +#include <qfinalstate.h> +#include <qhistorystate.h> +#endif + +class Window : public QWidget +{ +public: + Window(QWidget *parent = 0) + : QWidget(parent) + { + QPushButton *pb = new QPushButton("Go"); + QPushButton *pauseButton = new QPushButton("Pause"); + QPushButton *quitButton = new QPushButton("Quit"); + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->addWidget(pb); + vbox->addWidget(pauseButton); + vbox->addWidget(quitButton); + + QStateMachine *machine = new QStateMachine(this); + + QState *process = new QState(machine->rootState()); + process->setObjectName("process"); + + QState *s1 = new QState(process); + s1->setObjectName("s1"); + QState *s2 = new QState(process); + s2->setObjectName("s2"); + s1->addTransition(pb, SIGNAL(clicked()), s2); + s2->addTransition(pb, SIGNAL(clicked()), s1); + + QHistoryState *h = process->addHistoryState(); + h->setDefaultState(s1); + + QState *interrupted = new QState(machine->rootState()); + interrupted->setObjectName("interrupted"); + QFinalState *terminated = new QFinalState(machine->rootState()); + terminated->setObjectName("terminated"); + interrupted->addTransition(pauseButton, SIGNAL(clicked()), h); + interrupted->addTransition(quitButton, SIGNAL(clicked()), terminated); + + process->addTransition(pauseButton, SIGNAL(clicked()), interrupted); + process->addTransition(quitButton, SIGNAL(clicked()), terminated); + + process->setInitialState(s1); + machine->setInitialState(process); + QObject::connect(machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); + machine->start(); + } +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window win; + win.show(); + return app.exec(); +} diff --git a/examples/statemachine/pauseandresume/pauseandresume.pro b/examples/statemachine/pauseandresume/pauseandresume.pro new file mode 100644 index 0000000..6a976cb --- /dev/null +++ b/examples/statemachine/pauseandresume/pauseandresume.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/pingpong/main.cpp b/examples/statemachine/pingpong/main.cpp new file mode 100644 index 0000000..d749076 --- /dev/null +++ b/examples/statemachine/pingpong/main.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <stdio.h> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstate.h> +#include <qstatemachine.h> +#include <qtransition.h> +#endif + +class PingEvent : public QEvent +{ +public: + PingEvent() : QEvent(QEvent::Type(QEvent::User+2)) + {} +}; + +class PongEvent : public QEvent +{ +public: + PongEvent() : QEvent(QEvent::Type(QEvent::User+3)) + {} +}; + +class Pinger : public QState +{ +public: + Pinger(QStateMachine *machine, QState *parent) + : QState(parent), m_machine(machine) {} + +protected: + virtual void onEntry() + { + m_machine->postEvent(new PingEvent()); + fprintf(stdout, "ping?\n"); + } + +private: + QStateMachine *m_machine; +}; + +class PongTransition : public QAbstractTransition +{ +public: + PongTransition(QStateMachine *machine) + : QAbstractTransition(), m_machine(machine) {} + +protected: + virtual bool eventTest(QEvent *e) const { + return (e->type() == QEvent::User+3); + } + virtual void onTransition() + { + m_machine->postEvent(new PingEvent(), 500); + fprintf(stdout, "ping?\n"); + } + +private: + QStateMachine *m_machine; +}; + +class PingTransition : public QAbstractTransition +{ +public: + PingTransition(QStateMachine *machine) + : QAbstractTransition(), m_machine(machine) {} + +protected: + virtual bool eventTest(QEvent *e) const { + return (e->type() == QEvent::User+2); + } + virtual void onTransition() + { + m_machine->postEvent(new PongEvent(), 500); + fprintf(stdout, "pong!\n"); + } + +private: + QStateMachine *m_machine; +}; + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + QStateMachine machine; + QState *group = new QState(QState::ParallelGroup); + group->setObjectName("group"); + + Pinger *pinger = new Pinger(&machine, group); + pinger->setObjectName("pinger"); + pinger->addTransition(new PongTransition(&machine)); + + QState *ponger = new QState(group); + ponger->setObjectName("ponger"); + ponger->addTransition(new PingTransition(&machine)); + + machine.addState(group); + machine.setInitialState(group); + machine.start(); + + return app.exec(); +} diff --git a/examples/statemachine/pingpong/pingpong.pro b/examples/statemachine/pingpong/pingpong.pro new file mode 100644 index 0000000..bff9cb8 --- /dev/null +++ b/examples/statemachine/pingpong/pingpong.pro @@ -0,0 +1,10 @@ +QT = core +TEMPLATE = app +TARGET = +win32: CONFIG += console +mac:CONFIG -= app_bundle +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/examples/statemachine/statemachine.pro b/examples/statemachine/statemachine.pro new file mode 100644 index 0000000..ba32c12 --- /dev/null +++ b/examples/statemachine/statemachine.pro @@ -0,0 +1,17 @@ +TEMPLATE = subdirs +SUBDIRS = \ + clockticking \ + composition \ + eventtransitions \ + factorial \ + helloworld \ + pauseandresume \ + pingpong \ + trafficlight \ + twowaybutton + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS statemachine.pro README +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine +INSTALLS += target sources diff --git a/examples/statemachine/trafficlight/main.cpp b/examples/statemachine/trafficlight/main.cpp new file mode 100644 index 0000000..fbb6b68 --- /dev/null +++ b/examples/statemachine/trafficlight/main.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstate.h> +#include <qstatemachine.h> +#include <qfinalstate.h> +#endif + +//! [0] +class LightWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(bool on READ isOn WRITE setOn) +public: + LightWidget(const QColor &color, QWidget *parent = 0) + : QWidget(parent), m_color(color), m_on(false) {} + + bool isOn() const + { return m_on; } + void setOn(bool on) + { + if (on == m_on) + return; + m_on = on; + update(); + } + +protected: + virtual void paintEvent(QPaintEvent *) + { + if (!m_on) + return; + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setBrush(m_color); + painter.drawEllipse(0, 0, width(), height()); + } + +private: + QColor m_color; + bool m_on; +}; +//! [0] + +//! [1] +class LightState : public QState +{ +public: + LightState(LightWidget *light, int duration, QState *parent = 0) + : QState(parent) + { + QTimer *timer = new QTimer(this); + timer->setInterval(duration); + timer->setSingleShot(true); + QState *timing = new QState(this); + timing->setPropertyOnEntry(light, "on", true); + timing->invokeMethodOnEntry(timer, "start"); + timing->setPropertyOnExit(light, "on", false); + QFinalState *done = new QFinalState(this); + timing->addTransition(timer, SIGNAL(timeout()), done); + setInitialState(timing); + } +}; +//! [1] + +//! [2] +class TrafficLightWidget : public QWidget +{ +public: + TrafficLightWidget(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout *vbox = new QVBoxLayout(this); + m_red = new LightWidget(Qt::red); + vbox->addWidget(m_red); + m_yellow = new LightWidget(Qt::yellow); + vbox->addWidget(m_yellow); + m_green = new LightWidget(Qt::green); + vbox->addWidget(m_green); + QPalette pal = palette(); + pal.setColor(QPalette::Background, Qt::black); + setPalette(pal); + setAutoFillBackground(true); + } + + LightWidget *redLight() const + { return m_red; } + LightWidget *yellowLight() const + { return m_yellow; } + LightWidget *greenLight() const + { return m_green; } + +private: + LightWidget *m_red; + LightWidget *m_yellow; + LightWidget *m_green; +}; +//! [2] + +//! [3] +class TrafficLight : public QWidget +{ +public: + TrafficLight(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout *vbox = new QVBoxLayout(this); + TrafficLightWidget *widget = new TrafficLightWidget(); + vbox->addWidget(widget); + + QStateMachine *machine = new QStateMachine(this); + LightState *redGoingYellow = new LightState(widget->redLight(), 3000); + redGoingYellow->setObjectName("redGoingYellow"); + LightState *yellowGoingGreen = new LightState(widget->yellowLight(), 1000); + yellowGoingGreen->setObjectName("yellowGoingGreen"); + redGoingYellow->addFinishedTransition(yellowGoingGreen); + LightState *greenGoingYellow = new LightState(widget->greenLight(), 3000); + greenGoingYellow->setObjectName("greenGoingYellow"); + yellowGoingGreen->addFinishedTransition(greenGoingYellow); + LightState *yellowGoingRed = new LightState(widget->yellowLight(), 1000); + yellowGoingRed->setObjectName("yellowGoingRed"); + greenGoingYellow->addFinishedTransition(yellowGoingRed); + yellowGoingRed->addFinishedTransition(redGoingYellow); + + machine->addState(redGoingYellow); + machine->addState(yellowGoingGreen); + machine->addState(greenGoingYellow); + machine->addState(yellowGoingRed); + machine->setInitialState(redGoingYellow); + machine->start(); + } +}; +//! [3] + +//! [4] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + TrafficLight widget; + widget.resize(120, 300); + widget.show(); + + return app.exec(); +} +//! [4] + +#include "main.moc" diff --git a/examples/statemachine/trafficlight/trafficlight.pro b/examples/statemachine/trafficlight/trafficlight.pro new file mode 100644 index 0000000..730bd75 --- /dev/null +++ b/examples/statemachine/trafficlight/trafficlight.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +SOURCES += main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trafficlight.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight +INSTALLS += target sources diff --git a/examples/statemachine/twowaybutton/main.cpp b/examples/statemachine/twowaybutton/main.cpp new file mode 100644 index 0000000..eab0b3d --- /dev/null +++ b/examples/statemachine/twowaybutton/main.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#ifdef QT_STATEMACHINE_SOLUTION +#include <qstate.h> +#include <qstatemachine.h> +#endif + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + QPushButton button; + + QStateMachine machine; + QState *first = new QState(); + first->setObjectName("first"); + + QState *off = new QState(); + off->setPropertyOnEntry(&button, "text", "Off"); + off->setObjectName("off"); + first->addTransition(off); + + QState *on = new QState(); + on->setObjectName("on"); + on->setPropertyOnEntry(&button, "text", "On"); + off->addTransition(&button, SIGNAL(clicked()), on); + on->addTransition(&button, SIGNAL(clicked()), off); + + machine.addState(first); + machine.addState(off); + machine.addState(on); + machine.setInitialState(first); + machine.start(); + + button.resize(100, 50); + button.show(); + return app.exec(); +} diff --git a/examples/statemachine/twowaybutton/twowaybutton.pro b/examples/statemachine/twowaybutton/twowaybutton.pro new file mode 100644 index 0000000..6a976cb --- /dev/null +++ b/examples/statemachine/twowaybutton/twowaybutton.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp |