Initial bundle support
[profile/ivi/qtdeclarative.git] / src / quick / util / qquicktimer.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquicktimer_p.h"
43
44 #include <QtCore/qcoreapplication.h>
45 #include "private/qpauseanimationjob_p.h"
46 #include <qdebug.h>
47
48 #include <private/qobject_p.h>
49
50 QT_BEGIN_NAMESPACE
51
52
53
54 class QQuickTimerPrivate : public QObjectPrivate, public QAnimationJobChangeListener
55 {
56     Q_DECLARE_PUBLIC(QQuickTimer)
57 public:
58     QQuickTimerPrivate()
59         : interval(1000), running(false), repeating(false), triggeredOnStart(false)
60         , classBegun(false), componentComplete(false), firstTick(true) {}
61
62     virtual void animationFinished(QAbstractAnimationJob *);
63     virtual void animationCurrentLoopChanged(QAbstractAnimationJob *)  { Q_Q(QQuickTimer); q->ticked(); }
64
65     int interval;
66     QPauseAnimationJob pause;
67     bool running : 1;
68     bool repeating : 1;
69     bool triggeredOnStart : 1;
70     bool classBegun : 1;
71     bool componentComplete : 1;
72     bool firstTick : 1;
73 };
74
75 /*!
76     \qmlclass Timer QQuickTimer
77     \inqmlmodule QtQuick 2
78     \ingroup qml-utility-elements
79     \brief The Timer item triggers a handler at a specified interval.
80
81     A Timer can be used to trigger an action either once, or repeatedly
82     at a given interval.
83
84     Here is a Timer that shows the current date and time, and updates
85     the text every 500 milliseconds. It uses the JavaScript \c Date
86     object to access the current time.
87
88     \qml
89     import QtQuick 2.0
90
91     Item {
92         Timer {
93             interval: 500; running: true; repeat: true
94             onTriggered: time.text = Date().toString()
95         }
96
97         Text { id: time }
98     }
99     \endqml
100
101     The Timer element is synchronized with the animation timer.  Since the animation
102     timer is usually set to 60fps, the resolution of Timer will be
103     at best 16ms.
104
105     If the Timer is running and one of its properties is changed, the
106     elapsed time will be reset.  For example, if a Timer with interval of
107     1000ms has its \e repeat property changed 500ms after starting, the
108     elapsed time will be reset to 0, and the Timer will be triggered
109     1000ms later.
110
111     \sa {declarative/toys/clocks}{Clocks example}
112 */
113
114 QQuickTimer::QQuickTimer(QObject *parent)
115     : QObject(*(new QQuickTimerPrivate), parent)
116 {
117     Q_D(QQuickTimer);
118     d->pause.addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentLoop);
119     d->pause.setLoopCount(1);
120     d->pause.setDuration(d->interval);
121 }
122
123 /*!
124     \qmlproperty int QtQuick2::Timer::interval
125
126     Sets the \a interval between triggers, in milliseconds.
127
128     The default interval is 1000 milliseconds.
129 */
130 void QQuickTimer::setInterval(int interval)
131 {
132     Q_D(QQuickTimer);
133     if (interval != d->interval) {
134         d->interval = interval;
135         update();
136         emit intervalChanged();
137     }
138 }
139
140 int QQuickTimer::interval() const
141 {
142     Q_D(const QQuickTimer);
143     return d->interval;
144 }
145
146 /*!
147     \qmlproperty bool QtQuick2::Timer::running
148
149     If set to true, starts the timer; otherwise stops the timer.
150     For a non-repeating timer, \a running is set to false after the
151     timer has been triggered.
152
153     \a running defaults to false.
154
155     \sa repeat
156 */
157 bool QQuickTimer::isRunning() const
158 {
159     Q_D(const QQuickTimer);
160     return d->running;
161 }
162
163 void QQuickTimer::setRunning(bool running)
164 {
165     Q_D(QQuickTimer);
166     if (d->running != running) {
167         d->running = running;
168         d->firstTick = true;
169         emit runningChanged();
170         update();
171     }
172 }
173
174 /*!
175     \qmlproperty bool QtQuick2::Timer::repeat
176
177     If \a repeat is true the timer is triggered repeatedly at the
178     specified interval; otherwise, the timer will trigger once at the
179     specified interval and then stop (i.e. running will be set to false).
180
181     \a repeat defaults to false.
182
183     \sa running
184 */
185 bool QQuickTimer::isRepeating() const
186 {
187     Q_D(const QQuickTimer);
188     return d->repeating;
189 }
190
191 void QQuickTimer::setRepeating(bool repeating)
192 {
193     Q_D(QQuickTimer);
194     if (repeating != d->repeating) {
195         d->repeating = repeating;
196         update();
197         emit repeatChanged();
198     }
199 }
200
201 /*!
202     \qmlproperty bool QtQuick2::Timer::triggeredOnStart
203
204     When a timer is started, the first trigger is usually after the specified
205     interval has elapsed.  It is sometimes desirable to trigger immediately
206     when the timer is started; for example, to establish an initial
207     state.
208
209     If \a triggeredOnStart is true, the timer is triggered immediately
210     when started, and subsequently at the specified interval. Note that if
211     \e repeat is set to false, the timer is triggered twice; once on start,
212     and again at the interval.
213
214     \a triggeredOnStart defaults to false.
215
216     \sa running
217 */
218 bool QQuickTimer::triggeredOnStart() const
219 {
220     Q_D(const QQuickTimer);
221     return d->triggeredOnStart;
222 }
223
224 void QQuickTimer::setTriggeredOnStart(bool triggeredOnStart)
225 {
226     Q_D(QQuickTimer);
227     if (d->triggeredOnStart != triggeredOnStart) {
228         d->triggeredOnStart = triggeredOnStart;
229         update();
230         emit triggeredOnStartChanged();
231     }
232 }
233
234 /*!
235     \qmlmethod QtQuick2::Timer::start()
236     \brief Starts the timer.
237
238     If the timer is already running, calling this method has no effect.  The
239     \c running property will be true following a call to \c start().
240 */
241 void QQuickTimer::start()
242 {
243     setRunning(true);
244 }
245
246 /*!
247     \qmlmethod QtQuick2::Timer::stop()
248     \brief Stops the timer.
249
250     If the timer is not running, calling this method has no effect.  The
251     \c running property will be false following a call to \c stop().
252 */
253 void QQuickTimer::stop()
254 {
255     setRunning(false);
256 }
257
258 /*!
259     \qmlmethod QtQuick2::Timer::restart()
260     \brief Restarts the timer.
261
262     If the Timer is not running it will be started, otherwise it will be
263     stopped, reset to initial state and started.  The \c running property
264     will be true following a call to \c restart().
265 */
266 void QQuickTimer::restart()
267 {
268     setRunning(false);
269     setRunning(true);
270 }
271
272 void QQuickTimer::update()
273 {
274     Q_D(QQuickTimer);
275     if (d->classBegun && !d->componentComplete)
276         return;
277     d->pause.stop();
278     if (d->running) {
279         d->pause.setCurrentTime(0);
280         d->pause.setLoopCount(d->repeating ? -1 : 1);
281         d->pause.setDuration(d->interval);
282         d->pause.start();
283         if (d->triggeredOnStart && d->firstTick) {
284             QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
285             QMetaObject::invokeMethod(this, "ticked", Qt::QueuedConnection);
286         }
287     }
288 }
289
290 void QQuickTimer::classBegin()
291 {
292     Q_D(QQuickTimer);
293     d->classBegun = true;
294 }
295
296 void QQuickTimer::componentComplete()
297 {
298     Q_D(QQuickTimer);
299     d->componentComplete = true;
300     update();
301 }
302
303 /*!
304     \qmlsignal QtQuick2::Timer::onTriggered()
305
306     This handler is called when the Timer is triggered.
307 */
308 void QQuickTimer::ticked()
309 {
310     Q_D(QQuickTimer);
311     if (d->running && (d->pause.currentTime() > 0 || (d->triggeredOnStart && d->firstTick)))
312         emit triggered();
313     d->firstTick = false;
314 }
315
316 void QQuickTimerPrivate::animationFinished(QAbstractAnimationJob *)
317 {
318     Q_Q(QQuickTimer);
319     if (repeating || !running)
320         return;
321     running = false;
322     firstTick = false;
323     emit q->triggered();
324     emit q->runningChanged();
325 }
326
327 QT_END_NAMESPACE