From 60e9ce020e4d3f78a6d96b9cf7c78275a326aef2 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 24 Jun 2009 15:08:10 +1000 Subject: Flesh out the Timer element. --- src/declarative/extra/qmltimer.cpp | 150 +++++++++++++++++++++++++++++++++++-- src/declarative/extra/qmltimer.h | 20 ++++- 2 files changed, 162 insertions(+), 8 deletions(-) diff --git a/src/declarative/extra/qmltimer.cpp b/src/declarative/extra/qmltimer.cpp index 1e1a6de..0c13c4a 100644 --- a/src/declarative/extra/qmltimer.cpp +++ b/src/declarative/extra/qmltimer.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "QtCore/qcoreapplication.h" #include "QtCore/qpauseanimation.h" #include "private/qobject_p.h" #include "qmltimer.h" @@ -52,27 +53,59 @@ class QmlTimerPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlTimer) public: - QmlTimerPrivate() : interval(1000) {} + QmlTimerPrivate() + : interval(1000), running(false), repeating(false), firesOnStart(false) + , componentComplete(false) {} int interval; + bool running; + bool repeating; + bool firesOnStart; QPauseAnimation pause; + bool componentComplete; }; +/*! + \qmlclass Timer QFxTimer + \brief The Timer item triggers a handler at a specified interval. + + A timer can be used to trigger an action either once, or repeatedly + at a given interval. + + \qml + Timer { + interval: 500; running: true; repeat: true + onTriggered: Time.text = Date().toString() + } + Text { + id: Time + } + \endqml + +*/ + QmlTimer::QmlTimer(QObject *parent) : QObject(*(new QmlTimerPrivate), parent) { Q_D(QmlTimer); connect(&d->pause, SIGNAL(currentLoopChanged(int)), this, SLOT(ticked())); - d->pause.setLoopCount(-1); + connect(&d->pause, SIGNAL(finished()), this, SLOT(ticked())); + connect(&d->pause, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)) + , this, SLOT(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + d->pause.setLoopCount(1); d->pause.setDuration(d->interval); } +/*! + \qmlproperty int Timer::interval + + Sets the \a interval between triggering. +*/ void QmlTimer::setInterval(int interval) { Q_D(QmlTimer); if (interval != d->interval) { d->interval = interval; - d->pause.setDuration(d->interval); - d->pause.start(); + update(); } } @@ -82,16 +115,119 @@ int QmlTimer::interval() const return d->interval; } -void QmlTimer::componentComplete() +/*! + \qmlproperty bool Timer::running + + If set to true, starts the timer; otherwise stops the timer. + For a non-repeating timer, \a running will be set to false after the + timer has been triggered. + + \sa repeat +*/ +bool QmlTimer::isRunning() const +{ + Q_D(const QmlTimer); + return d->running; +} + +void QmlTimer::setRunning(bool running) +{ + Q_D(QmlTimer); + if (d->running != running) { + d->running = running; + emit runningChanged(); + update(); + } +} + +/*! + \qmlproperty bool Timer::repeat + + If \a repeat is true the timer will be triggered repeatedly at the + specified interval; otherwise, the timer will trigger once at the + specified interval and then stop (i.e. running will be set to false). + + \sa running +*/ +bool QmlTimer::isRepeating() const +{ + Q_D(const QmlTimer); + return d->repeating; +} + +void QmlTimer::setRepeating(bool repeating) +{ + Q_D(QmlTimer); + if (repeating != d->repeating) { + d->repeating = repeating; + update(); + } +} + +/*! + \qmlproperty bool Timer::firesOnStart + + If \a firesOnStart is true, the timer will be triggered immediately + when started, and subsequently at the specified interval. + + \sa running +*/ +bool QmlTimer::firesOnStart() const +{ + Q_D(const QmlTimer); + return d->firesOnStart; +} + +void QmlTimer::setFiresOnStart(bool firesOnStart) +{ + Q_D(QmlTimer); + if (d->firesOnStart != firesOnStart) { + d->firesOnStart = firesOnStart; + update(); + } +} + +void QmlTimer::update() { Q_D(QmlTimer); - if (d->pause.state() != QAbstractAnimation::Running) + if (!d->componentComplete) + return; + d->pause.stop(); + if (d->running) { + d->pause.setLoopCount(d->repeating ? -1 : 1); + d->pause.setDuration(d->interval); d->pause.start(); + if (d->firesOnStart) { + QCoreApplication::removePostedEvents(this, QEvent::MetaCall); + QMetaObject::invokeMethod(this, "ticked", Qt::QueuedConnection); + } + } +} + +void QmlTimer::componentComplete() +{ + Q_D(QmlTimer); + d->componentComplete = true; + update(); } +/*! + \qmlsignal Timer::onTriggered + + This handler is called when the Timer is triggered. +*/ void QmlTimer::ticked() { - emit timeout(); + emit triggered(); +} + +void QmlTimer::stateChanged(QAbstractAnimation::State, QAbstractAnimation::State state) +{ + Q_D(QmlTimer); + if (d->running && state != QAbstractAnimation::Running) { + d->running = false; + emit runningChanged(); + } } QT_END_NAMESPACE diff --git a/src/declarative/extra/qmltimer.h b/src/declarative/extra/qmltimer.h index 75603c6..8a94395 100644 --- a/src/declarative/extra/qmltimer.h +++ b/src/declarative/extra/qmltimer.h @@ -44,6 +44,7 @@ #include #include +#include #include QT_BEGIN_HEADER @@ -57,6 +58,9 @@ class Q_DECLARATIVE_EXPORT QmlTimer : public QObject, public QmlParserStatus Q_OBJECT Q_DECLARE_PRIVATE(QmlTimer) Q_PROPERTY(int interval READ interval WRITE setInterval) + Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) + Q_PROPERTY(bool repeat READ isRepeating WRITE setRepeating) + Q_PROPERTY(bool firesOnStart READ firesOnStart WRITE setFiresOnStart) public: QmlTimer(QObject *parent=0); @@ -64,14 +68,28 @@ public: void setInterval(int interval); int interval() const; + bool isRunning() const; + void setRunning(bool running); + + bool isRepeating() const; + void setRepeating(bool repeating); + + bool firesOnStart() const; + void setFiresOnStart(bool firesOnStart); + protected: void componentComplete(); Q_SIGNALS: - void timeout(); + void triggered(); + void runningChanged(); + +private: + void update(); private Q_SLOTS: void ticked(); + void stateChanged(QAbstractAnimation::State,QAbstractAnimation::State); }; QML_DECLARE_TYPE(QmlTimer) -- cgit v0.12