From 3c5f26079d20ffb6bac924e3686e717f499afbf7 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 25 Nov 2009 14:07:15 +1000 Subject: Fix changing Timer interval while running. Task-number: QTBUG-6201 --- src/declarative/util/qmltimer.cpp | 30 +++++++++++++-------- src/declarative/util/qmltimer_p.h | 2 +- tests/auto/declarative/qmltimer/tst_qmltimer.cpp | 34 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index 0be62f4..d2198f2 100644 --- a/src/declarative/util/qmltimer.cpp +++ b/src/declarative/util/qmltimer.cpp @@ -55,7 +55,7 @@ class QmlTimerPrivate : public QObjectPrivate public: QmlTimerPrivate() : interval(1000), running(false), repeating(false), triggeredOnStart(false) - , classBegun(false), componentComplete(false) {} + , classBegun(false), componentComplete(false), firstTick(true) {} int interval; QPauseAnimation pause; bool running : 1; @@ -63,6 +63,7 @@ public: bool triggeredOnStart : 1; bool classBegun : 1; bool componentComplete : 1; + bool firstTick : 1; }; /*! @@ -85,6 +86,12 @@ public: QmlTimer is synchronized with the animation timer. Since the animation timer is usually set to 60fps, the resolution of QmlTimer will be at best 16ms. + + If the Timer is running and one of its properties is changed, the + elapsed time will be reset. For example, if a Timer with interval of + 1000ms has its \e repeat property changed 500ms after starting, the + elapsed time will be reset to 0, and the Timer will be triggered + 1000ms later. */ QmlTimer::QmlTimer(QObject *parent) @@ -92,8 +99,7 @@ QmlTimer::QmlTimer(QObject *parent) { Q_D(QmlTimer); connect(&d->pause, SIGNAL(currentLoopChanged(int)), this, SLOT(ticked())); - connect(&d->pause, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)) - , this, SLOT(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + connect(&d->pause, SIGNAL(finished()), this, SLOT(finished())); d->pause.setLoopCount(1); d->pause.setDuration(d->interval); } @@ -142,6 +148,7 @@ void QmlTimer::setRunning(bool running) Q_D(QmlTimer); if (d->running != running) { d->running = running; + d->firstTick = true; emit runningChanged(); update(); } @@ -236,10 +243,11 @@ void QmlTimer::update() return; d->pause.stop(); if (d->running) { + d->pause.setCurrentTime(0); d->pause.setLoopCount(d->repeating ? -1 : 1); d->pause.setDuration(d->interval); d->pause.start(); - if (d->triggeredOnStart) { + if (d->triggeredOnStart && d->firstTick) { QCoreApplication::removePostedEvents(this, QEvent::MetaCall); QMetaObject::invokeMethod(this, "ticked", Qt::QueuedConnection); } @@ -267,18 +275,18 @@ void QmlTimer::componentComplete() void QmlTimer::ticked() { Q_D(QmlTimer); - if (d->running) + if (d->running && (d->pause.currentTime() > 0 || (d->triggeredOnStart && d->firstTick))) emit triggered(); + d->firstTick = false; } -void QmlTimer::stateChanged(QAbstractAnimation::State state, QAbstractAnimation::State) +void QmlTimer::finished() { Q_D(QmlTimer); - if (d->running && state != QAbstractAnimation::Running) { - d->running = false; - emit triggered(); - emit runningChanged(); - } + if (d->repeating || !d->running) + return; + emit triggered(); + d->firstTick = false; } QT_END_NAMESPACE diff --git a/src/declarative/util/qmltimer_p.h b/src/declarative/util/qmltimer_p.h index bd96d4a..56ef7a6 100644 --- a/src/declarative/util/qmltimer_p.h +++ b/src/declarative/util/qmltimer_p.h @@ -95,7 +95,7 @@ private: private Q_SLOTS: void ticked(); - void stateChanged(QAbstractAnimation::State,QAbstractAnimation::State); + void finished(); }; QT_END_NAMESPACE diff --git a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp index cf54647..620d53e 100644 --- a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -42,6 +42,7 @@ #include #include #include +#include class tst_qmltimer : public QObject { @@ -56,6 +57,7 @@ private slots: void noTriggerIfNotRunning(); void triggeredOnStart(); void triggeredOnStartRepeat(); + void changeDuration(); }; class TimerHelper : public QObject @@ -123,6 +125,8 @@ void tst_qmltimer::notRepeatingStart() QCOMPARE(helper.count, 1); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 1); + + delete timer; } void tst_qmltimer::repeat() @@ -147,6 +151,8 @@ void tst_qmltimer::repeat() timer->stop(); QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count == oldCount); + + delete timer; } void tst_qmltimer::triggeredOnStart() @@ -166,6 +172,8 @@ void tst_qmltimer::triggeredOnStart() QCOMPARE(helper.count, 2); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 2); + + delete timer; } void tst_qmltimer::triggeredOnStartRepeat() @@ -185,6 +193,8 @@ void tst_qmltimer::triggeredOnStartRepeat() int oldCount = helper.count; QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count > oldCount); + + delete timer; } void tst_qmltimer::noTriggerIfNotRunning() @@ -201,6 +211,30 @@ void tst_qmltimer::noTriggerIfNotRunning() QVERIFY(item != 0); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(item->property("ok").toBool(), true); + + delete item; +} + +void tst_qmltimer::changeDuration() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 200; repeat: true; running: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(500); + QCOMPARE(helper.count, 2); + + timer->setInterval(500); + + QTest::qWait(600); + QCOMPARE(helper.count, 3); + + delete timer; } QTEST_MAIN(tst_qmltimer) -- cgit v0.12 From b5dc7443889313acfa12cb83239cdf00f7a0e009 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 25 Nov 2009 14:33:05 +1000 Subject: Make sure initial state gets set correctly. Fixes regression introduced by 3ec86e388a35b850573b8fd8b58c93113bb8bd3. --- src/declarative/util/qmlstategroup.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qmlstategroup.cpp b/src/declarative/util/qmlstategroup.cpp index 4dfa34a..f206f5c 100644 --- a/src/declarative/util/qmlstategroup.cpp +++ b/src/declarative/util/qmlstategroup.cpp @@ -331,8 +331,10 @@ void QmlStateGroupPrivate::setCurrentStateInternal(const QString &state, bool ignoreTrans) { Q_Q(QmlStateGroup); - if (!componentComplete) + if (!componentComplete) { + currentState = state; return; + } if (applyingState) { qWarning() << "Can't apply a state change as part of a state definition."; -- cgit v0.12 From 14877e418b3223ab7eacf49523eed2b10ce7721b Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 25 Nov 2009 14:36:19 +1000 Subject: Add NOTIFYs for anchor properties. Requested for Bauhaus. --- .../graphicsitems/qmlgraphicsanchors.cpp | 39 ++++++++++++++++------ .../graphicsitems/qmlgraphicsanchors_p.h | 27 ++++++++++----- .../graphicsitems/qmlgraphicsanchors_p_p.h | 7 ++++ 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 61b6ecc..f26fbf5 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -349,6 +349,9 @@ QmlGraphicsItem *QmlGraphicsAnchors::fill() const void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) { Q_D(QmlGraphicsAnchors); + if (d->fill == f) + return; + if (!f) { d->remDepend(d->fill); d->fill = f; @@ -361,7 +364,7 @@ void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) d->remDepend(d->fill); d->fill = f; d->addDepend(d->fill); - + emit fillChanged(); d->fillChanged(); } @@ -374,6 +377,9 @@ QmlGraphicsItem *QmlGraphicsAnchors::centerIn() const void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) { Q_D(QmlGraphicsAnchors); + if (d->centerIn == c) + return; + if (!c) { d->remDepend(d->centerIn); d->centerIn = c; @@ -387,7 +393,7 @@ void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) d->remDepend(d->centerIn); d->centerIn = c; d->addDepend(d->centerIn); - + emit centerInChanged(); d->centerInChanged(); } @@ -553,7 +559,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::top() const void QmlGraphicsAnchors::setTop(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->top == edge) return; d->usedAnchors |= HasTopAnchor; @@ -566,6 +572,7 @@ void QmlGraphicsAnchors::setTop(const QmlGraphicsAnchorLine &edge) d->remDepend(d->top.item); d->top = edge; d->addDepend(d->top.item); + emit topChanged(); d->updateVerticalAnchors(); } @@ -575,6 +582,7 @@ void QmlGraphicsAnchors::resetTop() d->usedAnchors &= ~HasTopAnchor; d->remDepend(d->top.item); d->top = QmlGraphicsAnchorLine(); + emit topChanged(); d->updateVerticalAnchors(); } @@ -587,7 +595,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::bottom() const void QmlGraphicsAnchors::setBottom(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->bottom == edge) return; d->usedAnchors |= HasBottomAnchor; @@ -600,6 +608,7 @@ void QmlGraphicsAnchors::setBottom(const QmlGraphicsAnchorLine &edge) d->remDepend(d->bottom.item); d->bottom = edge; d->addDepend(d->bottom.item); + emit bottomChanged(); d->updateVerticalAnchors(); } @@ -609,6 +618,7 @@ void QmlGraphicsAnchors::resetBottom() d->usedAnchors &= ~HasBottomAnchor; d->remDepend(d->bottom.item); d->bottom = QmlGraphicsAnchorLine(); + emit bottomChanged(); d->updateVerticalAnchors(); } @@ -621,7 +631,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::verticalCenter() const void QmlGraphicsAnchors::setVerticalCenter(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->vCenter == edge) return; d->usedAnchors |= HasVCenterAnchor; @@ -634,6 +644,7 @@ void QmlGraphicsAnchors::setVerticalCenter(const QmlGraphicsAnchorLine &edge) d->remDepend(d->vCenter.item); d->vCenter = edge; d->addDepend(d->vCenter.item); + emit verticalCenterChanged(); d->updateVerticalAnchors(); } @@ -643,6 +654,7 @@ void QmlGraphicsAnchors::resetVerticalCenter() d->usedAnchors &= ~HasVCenterAnchor; d->remDepend(d->vCenter.item); d->vCenter = QmlGraphicsAnchorLine(); + emit verticalCenterChanged(); d->updateVerticalAnchors(); } @@ -655,7 +667,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::baseline() const void QmlGraphicsAnchors::setBaseline(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->baseline == edge) return; d->usedAnchors |= HasBaselineAnchor; @@ -668,6 +680,7 @@ void QmlGraphicsAnchors::setBaseline(const QmlGraphicsAnchorLine &edge) d->remDepend(d->baseline.item); d->baseline = edge; d->addDepend(d->baseline.item); + emit baselineChanged(); d->updateVerticalAnchors(); } @@ -677,6 +690,7 @@ void QmlGraphicsAnchors::resetBaseline() d->usedAnchors &= ~HasBaselineAnchor; d->remDepend(d->baseline.item); d->baseline = QmlGraphicsAnchorLine(); + emit baselineChanged(); d->updateVerticalAnchors(); } @@ -689,7 +703,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::left() const void QmlGraphicsAnchors::setLeft(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkHAnchorValid(edge)) + if (!d->checkHAnchorValid(edge) || d->left == edge) return; d->usedAnchors |= HasLeftAnchor; @@ -702,6 +716,7 @@ void QmlGraphicsAnchors::setLeft(const QmlGraphicsAnchorLine &edge) d->remDepend(d->left.item); d->left = edge; d->addDepend(d->left.item); + emit leftChanged(); d->updateHorizontalAnchors(); } @@ -711,6 +726,7 @@ void QmlGraphicsAnchors::resetLeft() d->usedAnchors &= ~HasLeftAnchor; d->remDepend(d->left.item); d->left = QmlGraphicsAnchorLine(); + emit leftChanged(); d->updateHorizontalAnchors(); } @@ -723,7 +739,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::right() const void QmlGraphicsAnchors::setRight(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkHAnchorValid(edge)) + if (!d->checkHAnchorValid(edge) || d->right == edge) return; d->usedAnchors |= HasRightAnchor; @@ -736,7 +752,7 @@ void QmlGraphicsAnchors::setRight(const QmlGraphicsAnchorLine &edge) d->remDepend(d->right.item); d->right = edge; d->addDepend(d->right.item); - + emit rightChanged(); d->updateHorizontalAnchors(); } @@ -746,6 +762,7 @@ void QmlGraphicsAnchors::resetRight() d->usedAnchors &= ~HasRightAnchor; d->remDepend(d->right.item); d->right = QmlGraphicsAnchorLine(); + emit rightChanged(); d->updateHorizontalAnchors(); } @@ -758,7 +775,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::horizontalCenter() const void QmlGraphicsAnchors::setHorizontalCenter(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkHAnchorValid(edge)) + if (!d->checkHAnchorValid(edge) || d->hCenter == edge) return; d->usedAnchors |= HasHCenterAnchor; @@ -771,6 +788,7 @@ void QmlGraphicsAnchors::setHorizontalCenter(const QmlGraphicsAnchorLine &edge) d->remDepend(d->hCenter.item); d->hCenter = edge; d->addDepend(d->hCenter.item); + emit horizontalCenterChanged(); d->updateHorizontalAnchors(); } @@ -780,6 +798,7 @@ void QmlGraphicsAnchors::resetHorizontalCenter() d->usedAnchors &= ~HasHCenterAnchor; d->remDepend(d->hCenter.item); d->hCenter = QmlGraphicsAnchorLine(); + emit horizontalCenterChanged(); d->updateHorizontalAnchors(); } diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h index bdddafe..e432428 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h @@ -58,13 +58,13 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsAnchors : public QObject { Q_OBJECT - Q_PROPERTY(QmlGraphicsAnchorLine left READ left WRITE setLeft RESET resetLeft) - Q_PROPERTY(QmlGraphicsAnchorLine right READ right WRITE setRight RESET resetRight) - Q_PROPERTY(QmlGraphicsAnchorLine horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter) - Q_PROPERTY(QmlGraphicsAnchorLine top READ top WRITE setTop RESET resetTop) - Q_PROPERTY(QmlGraphicsAnchorLine bottom READ bottom WRITE setBottom RESET resetBottom) - Q_PROPERTY(QmlGraphicsAnchorLine verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter) - Q_PROPERTY(QmlGraphicsAnchorLine baseline READ baseline WRITE setBaseline RESET resetBaseline) + Q_PROPERTY(QmlGraphicsAnchorLine left READ left WRITE setLeft RESET resetLeft NOTIFY leftChanged) + Q_PROPERTY(QmlGraphicsAnchorLine right READ right WRITE setRight RESET resetRight NOTIFY rightChanged) + Q_PROPERTY(QmlGraphicsAnchorLine horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter NOTIFY horizontalCenterChanged) + Q_PROPERTY(QmlGraphicsAnchorLine top READ top WRITE setTop RESET resetTop NOTIFY topChanged) + Q_PROPERTY(QmlGraphicsAnchorLine bottom READ bottom WRITE setBottom RESET resetBottom NOTIFY bottomChanged) + Q_PROPERTY(QmlGraphicsAnchorLine verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter NOTIFY verticalCenterChanged) + Q_PROPERTY(QmlGraphicsAnchorLine baseline READ baseline WRITE setBaseline RESET resetBaseline NOTIFY baselineChanged) Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged) Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged) Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged()) @@ -72,8 +72,8 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsAnchors : public QObject Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged) Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged()) Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged()) - Q_PROPERTY(QmlGraphicsItem *fill READ fill WRITE setFill) - Q_PROPERTY(QmlGraphicsItem *centerIn READ centerIn WRITE setCenterIn) + Q_PROPERTY(QmlGraphicsItem *fill READ fill WRITE setFill NOTIFY fillChanged) + Q_PROPERTY(QmlGraphicsItem *centerIn READ centerIn WRITE setCenterIn NOTIFY centerInChanged) public: QmlGraphicsAnchors(QObject *parent=0); @@ -155,6 +155,15 @@ public: void componentComplete(); Q_SIGNALS: + void leftChanged(); + void rightChanged(); + void topChanged(); + void bottomChanged(); + void verticalCenterChanged(); + void horizontalCenterChanged(); + void baselineChanged(); + void fillChanged(); + void centerInChanged(); void leftMarginChanged(); void rightMarginChanged(); void topMarginChanged(); diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h index d21d9c5..2156565 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h @@ -80,9 +80,16 @@ public: QmlGraphicsItem *item; AnchorLine anchorLine; + + bool operator==(const QmlGraphicsAnchorLine& other) const + { + return item == other.item && anchorLine == other.anchorLine; + } }; Q_DECLARE_METATYPE(QmlGraphicsAnchorLine) + + class QmlGraphicsAnchorsPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlGraphicsAnchors) -- cgit v0.12 From 4e8ee5429339ec3c56656858ec7edc8ca726bd5c Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 25 Nov 2009 14:41:25 +1000 Subject: Test for pixmap property of Image. --- src/declarative/graphicsitems/qmlgraphicsimage.cpp | 1 + .../qmlgraphicsimage/tst_qmlgraphicsimage.cpp | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/declarative/graphicsitems/qmlgraphicsimage.cpp b/src/declarative/graphicsitems/qmlgraphicsimage.cpp index 9d59796..38df0c7 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimage.cpp @@ -171,6 +171,7 @@ void QmlGraphicsImagePrivate::setPixmap(const QPixmap &pixmap) q->setImplicitWidth(pix.width()); q->setImplicitHeight(pix.height()); + status = pix.isNull() ? QmlGraphicsImageBase::Null : QmlGraphicsImageBase::Ready; q->update(); emit q->pixmapChanged(); diff --git a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp index 784ad42..c8a2d3f 100644 --- a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp +++ b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp @@ -81,6 +81,7 @@ private slots: void clearSource(); void resized(); void smooth(); + void pixmap(); private: QmlEngine engine; @@ -207,6 +208,35 @@ void tst_qmlgraphicsimage::smooth() delete obj; } +void tst_qmlgraphicsimage::pixmap() +{ + QString componentStr = "import Qt 4.6\nImage { pixmap: testPixmap }"; + + QPixmap pixmap; + QmlContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("testPixmap", pixmap); + + QmlComponent component(&engine, componentStr.toLatin1(), QUrl("file://")); + + QmlGraphicsImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->source(), QUrl()); + QVERIFY(obj->status() == QmlGraphicsImage::Null); + QCOMPARE(obj->width(), 0.); + QCOMPARE(obj->height(), 0.); + QCOMPARE(obj->fillMode(), QmlGraphicsImage::Stretch); + QCOMPARE(obj->progress(), 0.0); + QVERIFY(obj->pixmap().isNull()); + + pixmap = QPixmap(SRCDIR "/data/colors.png"); + ctxt->setContextProperty("testPixmap", pixmap); + QCOMPARE(obj->width(), 120.); + QCOMPARE(obj->height(), 120.); + QVERIFY(obj->status() == QmlGraphicsImage::Ready); + + delete obj; +} + QTEST_MAIN(tst_qmlgraphicsimage) #include "tst_qmlgraphicsimage.moc" -- cgit v0.12 From 120433c1eac10ba431204a0cfa464bcbfe41a07d Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 25 Nov 2009 14:54:26 +1000 Subject: Add Timer reset() method. --- src/declarative/util/qmltimer.cpp | 14 +++++++++++++ src/declarative/util/qmltimer_p.h | 1 + tests/auto/declarative/qmltimer/tst_qmltimer.cpp | 26 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index 0a2448a..da60193 100644 --- a/src/declarative/util/qmltimer.cpp +++ b/src/declarative/util/qmltimer.cpp @@ -239,6 +239,20 @@ void QmlTimer::stop() setRunning(false); } +/*! + \qmlmethod Timer::restart() + \brief Restarts the timer. + + If the Timer is not running it will be started, otherwise it will be + stopped, reset to initial state and started. The \c running property + will be true following a call to \c restart(). +*/ +void QmlTimer::restart() +{ + setRunning(false); + setRunning(true); +} + void QmlTimer::update() { Q_D(QmlTimer); diff --git a/src/declarative/util/qmltimer_p.h b/src/declarative/util/qmltimer_p.h index 56ef7a6..50cae2b 100644 --- a/src/declarative/util/qmltimer_p.h +++ b/src/declarative/util/qmltimer_p.h @@ -85,6 +85,7 @@ protected: public Q_SLOTS: void start(); void stop(); + void restart(); Q_SIGNALS: void triggered(); diff --git a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp index 620d53e..63a9a09 100644 --- a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -58,6 +58,7 @@ private slots: void triggeredOnStart(); void triggeredOnStartRepeat(); void changeDuration(); + void restart(); }; class TimerHelper : public QObject @@ -237,6 +238,31 @@ void tst_qmltimer::changeDuration() delete timer; } +void tst_qmltimer::restart() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 500; repeat: true; running: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(600); + QCOMPARE(helper.count, 1); + + QTest::qWait(300); + + timer->restart(); + + QTest::qWait(700); + + QCOMPARE(helper.count, 2); + + delete timer; +} + QTEST_MAIN(tst_qmltimer) #include "tst_qmltimer.moc" -- cgit v0.12 From 9eb6102693c3d73259a236becb6701a0787bb4e3 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 25 Nov 2009 14:58:35 +1000 Subject: use right type --- examples/declarative/tutorials/helloworld/Cell.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/declarative/tutorials/helloworld/Cell.qml b/examples/declarative/tutorials/helloworld/Cell.qml index ab6e565..c38b40e 100644 --- a/examples/declarative/tutorials/helloworld/Cell.qml +++ b/examples/declarative/tutorials/helloworld/Cell.qml @@ -8,7 +8,7 @@ Item { property alias color: rectangle.color //![4] //![5] - signal clicked(string color) + signal clicked(color color) //![5] width: 40; height: 25 -- cgit v0.12 From 0e1883e4c4a6d5b3b14d5cf37862fee651da16d3 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 25 Nov 2009 14:59:14 +1000 Subject: add target --- doc/src/declarative/extending.qdoc | 39 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 7a9de60..d0beafc 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -531,7 +531,7 @@ in the bind engine for allowing an object to access the binding directly. If a binding is assigned to a property with a type of QmlBinding pointer (ie. \c {QmlBinding *}), each time the binding value changes, -a QmlBinding instance is assigned to that property. The QmlBinding instance +a QmlBinding instance is assigned to that property. The QmlBinding instance allows the object to read the binding and to evaluate the binding's current value. \section1 Extension Objects @@ -548,16 +548,16 @@ directly, if this is either not possible or is complicated by some other concerns, extension objects allow limited extension possibilities without direct modifications. -Extension objects are used to add additional properties to an existing type. -Extension objects can only add properties, not signals or methods. An extended -type definition allows the programmer to supply an additional type - known as the -extension type - when registering the target class whose properties are +Extension objects are used to add additional properties to an existing type. +Extension objects can only add properties, not signals or methods. An extended +type definition allows the programmer to supply an additional type - known as the +extension type - when registering the target class whose properties are transparently merged with the original target class when used from within QML. -An extension class is a regular QObject, with a constructor that takes a QObject -pointer. When needed (extension classes are delay created until the first extended -property is accessed) the extension class is created and the target object is -passed in as the parent. When an extended property on the original is accessed, +An extension class is a regular QObject, with a constructor that takes a QObject +pointer. When needed (extension classes are delay created until the first extended +property is accessed) the extension class is created and the target object is +passed in as the parent. When an extended property on the original is accessed, the appropriate property on the extension object is used instead. When an extended type is installed, one of the @@ -565,22 +565,22 @@ When an extended type is installed, one of the #define QML_DEFINE_EXTENDED_TYPE(URI, VMAJ, VFROM, VTO, QmlName,T, ExtendedT) #define QML_DEFINE_EXTENDED_NOCREATE_TYPE(T, ExtendedT) \endcode -macros should be used instead of the regular \c QML_DEFINE_TYPE or -\c QML_DEFINE_NOCREATE_TYPE. The arguments are identical to the corresponding -non-extension object macro, except for the ExtendedT parameter which is the type +macros should be used instead of the regular \c QML_DEFINE_TYPE or +\c QML_DEFINE_NOCREATE_TYPE. The arguments are identical to the corresponding +non-extension object macro, except for the ExtendedT parameter which is the type of the extension object. \section1 Optimization -Often to develop high performance elements it is helpful to know more about the -status of the QML engine. For example, it might be beneficial to delay -initializing some costly data structures until after all the properties have been +Often to develop high performance elements it is helpful to know more about the +status of the QML engine. For example, it might be beneficial to delay +initializing some costly data structures until after all the properties have been set. The QML engine defines an interface class called QmlParserStatus, which contains a -number of virtual methods that are invoked at various stages during component -instantiation. To receive these notifications, an element implementation inherits -QmlParserStatus and notifies the Qt meta system using the Q_INTERFACES() macro. +number of virtual methods that are invoked at various stages during component +instantiation. To receive these notifications, an element implementation inherits +QmlParserStatus and notifies the Qt meta system using the Q_INTERFACES() macro. For example, @@ -691,6 +691,7 @@ controls the color of the inner rectangle. } \endcode +\target qml-property-aliases \section2 Property aliases Property aliases are a more advanced form of property declaration. Unlike a @@ -718,7 +719,7 @@ An alias reference takes one of the following forms \endcode where must refer to an object id within the same component as the type -declaring the alias, and, optionally, refers to a property on that object. +declaring the alias, and, optionally, refers to a property on that object. Here is the property definition example rewritten to use property aliases. \code -- cgit v0.12 From 03de177e4f4d028ac75c2100060ab5d7389d3a2c Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 25 Nov 2009 15:00:05 +1000 Subject: slideswitch example fixes --- doc/src/declarative/example-slideswitch.qdoc | 3 +++ examples/declarative/slideswitch/slideswitch.qml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc index a8376eb..492a8ea 100644 --- a/doc/src/declarative/example-slideswitch.qdoc +++ b/doc/src/declarative/example-slideswitch.qdoc @@ -131,4 +131,7 @@ In order for the the knob to move smoothly we add a transition that will animate For more information on transitions see \l{state-transitions}{QML Transitions}. +\section1 Usage +The switch can be used in a QML file, like this: +\snippet examples/declarative/slideswitch/slideswitch.qml 0 */ diff --git a/examples/declarative/slideswitch/slideswitch.qml b/examples/declarative/slideswitch/slideswitch.qml index 9b46cd1..396749f 100644 --- a/examples/declarative/slideswitch/slideswitch.qml +++ b/examples/declarative/slideswitch/slideswitch.qml @@ -5,7 +5,7 @@ Rectangle { color: "white" width: 400; height: 250 - Switch { - anchors.centerIn: parent - } +//![0] + Switch { anchors.centerIn: parent; on: false } +//![0] } -- cgit v0.12 From 20504e30096f2942abcadb966b26c834a6062ea5 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 25 Nov 2009 15:05:55 +1000 Subject: Doc improvments --- doc/src/declarative/animation.qdoc | 2 ++ doc/src/declarative/extending.qdoc | 8 ++--- doc/src/declarative/focus.qdoc | 2 ++ doc/src/declarative/qmlstates.qdoc | 29 +++++++++++++----- doc/src/declarative/scope.qdoc | 2 ++ src/declarative/qml/qmlscript.cpp | 31 +++++++++++-------- src/declarative/util/qmlconnection.cpp | 55 ++++++++++++++++++---------------- 7 files changed, 79 insertions(+), 50 deletions(-) diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index d05a444..bf5907d 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -49,6 +49,8 @@ real, int, color, rect, point, and size can all be animated. QML supports three different forms of animation - basic property animation, transitions, and property behaviors. +\tableofcontents + \section1 Basic Property Animation The simplest form of animation is directly using \l PropertyAnimation, which can animate all of the property diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 7a9de60..5985494 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -636,7 +636,7 @@ declaring a new property, and the corresponding C++ type. \row \o variant \o QVariant \endtable -QML supports two methods for adding a new property to a type - a new property +QML supports two methods for adding a new property to a type: a new property definition, and a property alias. \section2 Property definitions @@ -714,10 +714,10 @@ binding, the alias reference syntax is highly restricted. An alias reference takes one of the following forms \code - . - + . + \endcode -where must refer to an object id within the same component as the type +where must refer to an object id within the same component as the type declaring the alias, and, optionally, refers to a property on that object. Here is the property definition example rewritten to use property aliases. diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc index 8061a7c..924f590 100644 --- a/doc/src/declarative/focus.qdoc +++ b/doc/src/declarative/focus.qdoc @@ -49,6 +49,8 @@ focused QML \l Item. To facilitate the construction of reusable components and to address some of the cases unique to fluid user interfaces, the QML items add a \e scope based extension to Qt's traditional keyboard focus model. +\tableofcontents + \section1 Key Handling Overview When the user presses or releases a key, the following occurs: diff --git a/doc/src/declarative/qmlstates.qdoc b/doc/src/declarative/qmlstates.qdoc index ddb0fc8..245a57f 100644 --- a/doc/src/declarative/qmlstates.qdoc +++ b/doc/src/declarative/qmlstates.qdoc @@ -3,6 +3,8 @@ \target qmlstates \title QML States +\section1 Overview + QML states typically describe user interface configurations, including: \list \o What UI elements are present @@ -14,10 +16,12 @@ A state can also be thought of as a set of batched changes from a default config Examples of states in modern UI: \list -\o A Contacts application has a 'View Contact' state and an 'Edit Contact' State. In the first state the information presented is static (using labels), and in the second it is editable (using editors). -\o A button has a pressed and unpressed state. When pressed the text moves down and to the right, and the button has a slightly darker appearance. +\o An Address Book application with a 'View Contact' state and an 'Edit Contact' State. In the first state the contact information presented is read-only (using labels), and in the second it is editable (using editors). +\o A button with a pressed and unpressed state. When pressed the text moves slightly down and to the right, and the button has a slightly darker appearance. \endlist +\section1 States in QML + In QML: \list \o Any object can use states. @@ -25,29 +29,38 @@ In QML: \o A state can affect the properties of other objects, not just the object owning the state (and not just that object's children). \endlist -The following example shows a simple use of states. In the default state \c myrect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. +Here is an example of using states. In the default state \c myRect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. Clicking within the mouse region changes the state from the default state to the 'moved' state. -\code +\qml Item { + id: myItem + Rectangle { - id: myrect + id: myRect width: 100 height: 100 + color: "red" } + states: [ State { name: "moved" PropertyChanges { - target: myrect + target: myRect x: 50 y: 50 } } ] + + MouseRegion { + anchors.fill: parent + onClicked: myItem.state = 'moved' + } } -\endcode +\endqml -To animate state changes, you can use \l{state-transitions}{transitions}. +State changes can be animated using \l{state-transitions}{transitions}. Other things you can do in a state change: \list diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index f7f25f5..ef30f94 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -43,6 +43,8 @@ \page qmlscope.html \title QML Scope +\tableofcontents + \l {Property Binding}s and \l {ECMAScript Blocks} are executed in a scope chain automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped} language. Different object instances instantiated from the same component can exist in diff --git a/src/declarative/qml/qmlscript.cpp b/src/declarative/qml/qmlscript.cpp index 7242498..eb0b858 100644 --- a/src/declarative/qml/qmlscript.cpp +++ b/src/declarative/qml/qmlscript.cpp @@ -43,12 +43,13 @@ /*! \qmlclass Script QmlScript - \brief The Script element adds JavaScript snippets. + \brief The Script element provides a way to add JavaScript code snippets in QML. \ingroup group_utility - QmlScript is used to add convenient JavaScript "glue" methods to - your Qt Declarative application or component. While you can have any JavaScript code - within a QmlScript, it is best to limit yourself to defining functions. + The Script element is used to add convenient JavaScript "glue" methods to + your Qt Declarative application or component. + + An example: \qml Script { @@ -60,23 +61,27 @@ MouseRegion { onClicked: debugMyComponent() } \endqml - \note QmlScript executes JavaScript as soon as it is specified. - When defining a component, this may be before the execution context is - fully specified. As a result some properties or items may not be - accessible. By limiting your JavaScript to defining functions that are - only executed later once the context is fully defined, this problem is - avoided. + \note While it is possible to use any JavaScript code within a Script element, + it is recommended that the code be limited to defining functions. The Script + element executes JavaScript as soon as it is specified, so + when defining a component, this may be done before the execution context is + fully specified. As a result, some properties or items may not be + accessible. You can avoid this problem by limiting your JavaScript to + defining functions that are only executed later once the context is fully + defined. + + \sa {ECMAScript Blocks} */ /*! \qmlproperty string Script::script \default - JavaScript code to execute. + The JavaScript code to be executed. */ /*! \qmlproperty url Script::source - Setting this property causes the Script element to read JavaScript code from - the file specified. + Specifies a source file containing JavaScript code. This can be used instead + of providing inline JavaScript code in the Script element. */ diff --git a/src/declarative/util/qmlconnection.cpp b/src/declarative/util/qmlconnection.cpp index b1771d4..3e72ab8 100644 --- a/src/declarative/util/qmlconnection.cpp +++ b/src/declarative/util/qmlconnection.cpp @@ -65,7 +65,18 @@ public: \qmlclass Connection QmlConnection \brief A Connection object describes generalized connections to signals. - JavaScript-in-HTML style signal properties do not allow: + When connecting to signals in QML, the usual way is to create an + "on" handler that reacts when a signal is received, like this: + + \qml + MouseRegion { + onClicked: { foo(x+123,y+456) } + } + \endqml + + However, in some cases, it is not possible to connect to a signal in this + way. For example, JavaScript-in-HTML style signal properties do not allow: + \list \i connecting to signals with the same name but different parameters \i conformance checking that parameters are correctly named @@ -74,39 +85,33 @@ public: \i signals in classes with coincidentally-named on properties \endlist - When any of these is needed, the Connection object can be used instead. - Where a signal could be connected like this: + When any of these are needed, the Connection object can be used instead. - \qml -MouseRegion { - onClicked: { foo(x+123,y+456) } -} - \endqml - - An equivalent binding can be made with a Connection object: + For example, the above code can be changed to use a Connection object, + like this: \qml -MouseRegion { - Connection { - signal: "clicked(x,y)" - script: { foo(x+123,y+456) } + MouseRegion { + Connection { + signal: "clicked(x,y)" + script: { foo(x+123,y+456) } + } } -} \endqml More generally, the Connection object can be a child of some other object than the sender of the signal, and the script is the default attribute: \qml -MouseRegion { - id: mr -} -... -Connection { - sender: mr - signal: "clicked(x,y)" - script: { foo(x+123,y+456) } -} + MouseRegion { + id: mr + } + ... + Connection { + sender: mr + signal: "clicked(x,y)" + script: { foo(x+123,y+456) } + } \endqml */ @@ -249,7 +254,7 @@ void QmlConnection::setScript(const QmlScriptString& script) \qmlproperty string Connection::signal This property holds the signal from the sender to which the script is attached. - The signal must have its formal parameter names given in parentheses: + The signal's formal parameter names must be given in parentheses: \qml Connection { -- cgit v0.12 From ad543e4edbe69c7111542e5c57f7470e9499cffc Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 25 Nov 2009 15:26:41 +1000 Subject: Notify of any change to pixmap property. --- src/declarative/graphicsitems/qmlgraphicsimage_p.h | 1 - src/declarative/graphicsitems/qmlgraphicsimagebase.cpp | 3 +++ src/declarative/graphicsitems/qmlgraphicsimagebase_p.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsimage_p.h b/src/declarative/graphicsitems/qmlgraphicsimage_p.h index 81e10ab..47cdcd6 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimage_p.h @@ -74,7 +74,6 @@ public: Q_SIGNALS: void fillModeChanged(); - void pixmapChanged(); protected: QmlGraphicsImage(QmlGraphicsImagePrivate &dd, QmlGraphicsItem *parent); diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp b/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp index 6cd1c05..8374c9f 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp @@ -106,6 +106,7 @@ void QmlGraphicsImageBase::setSource(const QUrl &url) setImplicitHeight(0); emit statusChanged(d->status); emit sourceChanged(d->url); + emit pixmapChanged(); update(); } else { d->status = Loading; @@ -131,6 +132,7 @@ void QmlGraphicsImageBase::setSource(const QUrl &url) emit statusChanged(d->status); emit sourceChanged(d->url); emit progressChanged(d->progress); + emit pixmapChanged(); update(); } } @@ -155,6 +157,7 @@ void QmlGraphicsImageBase::requestFinished() emit statusChanged(d->status); emit sourceChanged(d->url); emit progressChanged(1.0); + emit pixmapChanged(); update(); } diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h b/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h index bab93b7..4936794 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h @@ -71,6 +71,7 @@ Q_SIGNALS: void sourceChanged(const QUrl &); void statusChanged(Status); void progressChanged(qreal progress); + void pixmapChanged(); protected: QmlGraphicsImageBase(QmlGraphicsImageBasePrivate &dd, QmlGraphicsItem *parent); -- cgit v0.12 From 1c9dcb09b79d77bc7d4958e1393437597892bb0b Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 25 Nov 2009 15:51:31 +1000 Subject: Add reset function for anchors.fill and anchors.centerIn. Task-number: QTBUG-5337 --- .../graphicsitems/qmlgraphicsanchors.cpp | 12 ++++++++++++ .../graphicsitems/qmlgraphicsanchors_p.h | 6 ++++-- tests/auto/declarative/anchors/tst_anchors.cpp | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index f26fbf5..8642476 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -355,6 +355,7 @@ void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) if (!f) { d->remDepend(d->fill); d->fill = f; + emit fillChanged(); return; } if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){ @@ -368,6 +369,11 @@ void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) d->fillChanged(); } +void QmlGraphicsAnchors::resetFill() +{ + setFill(0); +} + QmlGraphicsItem *QmlGraphicsAnchors::centerIn() const { Q_D(const QmlGraphicsAnchors); @@ -383,6 +389,7 @@ void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) if (!c) { d->remDepend(d->centerIn); d->centerIn = c; + emit centerInChanged(); return; } if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){ @@ -397,6 +404,11 @@ void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) d->centerInChanged(); } +void QmlGraphicsAnchors::resetCenterIn() +{ + setCenterIn(0); +} + bool QmlGraphicsAnchorsPrivate::calcStretch(const QmlGraphicsAnchorLine &edge1, const QmlGraphicsAnchorLine &edge2, int offset1, diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h index e432428..507b4d8 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h @@ -72,8 +72,8 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsAnchors : public QObject Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged) Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged()) Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged()) - Q_PROPERTY(QmlGraphicsItem *fill READ fill WRITE setFill NOTIFY fillChanged) - Q_PROPERTY(QmlGraphicsItem *centerIn READ centerIn WRITE setCenterIn NOTIFY centerInChanged) + Q_PROPERTY(QmlGraphicsItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged) + Q_PROPERTY(QmlGraphicsItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) public: QmlGraphicsAnchors(QObject *parent=0); @@ -143,9 +143,11 @@ public: QmlGraphicsItem *fill() const; void setFill(QmlGraphicsItem *); + void resetFill(); QmlGraphicsItem *centerIn() const; void setCenterIn(QmlGraphicsItem *); + void resetCenterIn(); UsedAnchors usedAnchors() const; diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp index 3011fdc..44e812a 100644 --- a/tests/auto/declarative/anchors/tst_anchors.cpp +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -67,6 +67,7 @@ private slots: void illegalSets_data(); void reset(); void reset_data(); + void resetConvenience(); void nullItem(); void nullItem_data(); void crash1(); @@ -312,6 +313,27 @@ void tst_anchors::reset_data() QTest::newRow("baseline") << "baseline" << QmlGraphicsAnchorLine::Baseline << QmlGraphicsAnchors::HasBaselineAnchor; } +void tst_anchors::resetConvenience() +{ + QmlGraphicsItem *baseItem = new QmlGraphicsItem; + QmlGraphicsItem *item = new QmlGraphicsItem; + + //fill + item->anchors()->setFill(baseItem); + QVERIFY(item->anchors()->fill() == baseItem); + item->anchors()->resetFill(); + QVERIFY(item->anchors()->fill() == 0); + + //centerIn + item->anchors()->setCenterIn(baseItem); + QVERIFY(item->anchors()->centerIn() == baseItem); + item->anchors()->resetCenterIn(); + QVERIFY(item->anchors()->centerIn() == 0); + + delete item; + delete baseItem; +} + void tst_anchors::nullItem() { QFETCH(QString, side); -- cgit v0.12 From b74e226c09bc37043a06b24029e0e22e4f3cdd16 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 25 Nov 2009 16:28:38 +1000 Subject: Small doc fixes. --- doc/src/declarative/advtutorial2.qdoc | 2 +- doc/src/declarative/ecmascriptblocks.qdoc | 4 ++-- doc/src/declarative/extending.qdoc | 2 +- doc/src/declarative/focus.qdoc | 4 ++-- doc/src/declarative/globalobject.qdoc | 2 +- doc/src/declarative/qmlintro.qdoc | 6 +++--- src/declarative/graphicsitems/qmlgraphicsitem.cpp | 18 +++++++++++------- src/declarative/qml/qmlcomponent.cpp | 4 ++-- src/declarative/qml/qmlscript.cpp | 4 ++-- src/declarative/qml/qmlscriptstring.cpp | 4 ++-- 10 files changed, 27 insertions(+), 23 deletions(-) diff --git a/doc/src/declarative/advtutorial2.qdoc b/doc/src/declarative/advtutorial2.qdoc index 40a760d..dcc7c70 100644 --- a/doc/src/declarative/advtutorial2.qdoc +++ b/doc/src/declarative/advtutorial2.qdoc @@ -93,7 +93,7 @@ To hook this code up to the \e{New Game} button, you alter it as below: \snippet declarative/tutorials/samegame/samegame2/samegame.qml 1 -We have just replaced the \c{onClicked: print("Implement me!")} with \c{onClicked: initBoard()}. +We have just replaced the \c{onClicked: console.log("Implement me!")} with \c{onClicked: initBoard()}. Note that in order to have the function available, you'll need to include the script in the main file, by adding a script element to it. diff --git a/doc/src/declarative/ecmascriptblocks.qdoc b/doc/src/declarative/ecmascriptblocks.qdoc index 815c68c..6ee5a8e 100644 --- a/doc/src/declarative/ecmascriptblocks.qdoc +++ b/doc/src/declarative/ecmascriptblocks.qdoc @@ -168,7 +168,7 @@ is illegal in QML. // Illegal modification of undeclared variable a = 1; for (var ii = 1; ii < 10; ++ii) a = a * ii; -print("Result: " + a); + console.log("Result: " + a); \endcode It can be trivially modified to this legal code. @@ -176,7 +176,7 @@ It can be trivially modified to this legal code. \code var a = 1; for (var ii = 1; ii < 10; ++ii) a = a * ii; -print("Result: " + a); + console.log("Result: " + a); \endcode Any attempt to modify the global object - either implicitly or explicitly - will diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 0233aa7..056b8ab 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -845,7 +845,7 @@ This example adds a new method that behaves like a child: \code Item { function say(text) { - print("You said " + text); + console.log("You said " + text); } } \endcode diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc index 924f590..46bfc38 100644 --- a/doc/src/declarative/focus.qdoc +++ b/doc/src/declarative/focus.qdoc @@ -67,7 +67,7 @@ item and thus subsequently be \l {QEvent::ignore()}{ignored}. \code Item { Item { - Keys.onPressed: if (event.key == Qt.Key_A) { print('Key A was pressed'); event.accepted = true } + Keys.onPressed: if (event.key == Qt.Key_A) { console.log('Key A was pressed'); event.accepted = true } Rectangle {} } } @@ -307,7 +307,7 @@ Rectangle { Text { focus: true text: name - Keys.onReturnPressed: print(name) + Keys.onReturnPressed: console.log(name) } } } diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index e3c8b9a..3eadec2 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -182,7 +182,7 @@ such as ListView, \l Repeater and \l Loader. sprite = component.createObject(); if(sprite == 0){ // Error Handling - print(component.errorsString()); + console.log(component.errorsString()); }else{ sprite.parent = page; sprite.x = 200; diff --git a/doc/src/declarative/qmlintro.qdoc b/doc/src/declarative/qmlintro.qdoc index 78462db..76d915f 100644 --- a/doc/src/declarative/qmlintro.qdoc +++ b/doc/src/declarative/qmlintro.qdoc @@ -311,7 +311,7 @@ any visual Item, for example: \code Item { focus: true - Keys.onSelectPressed: print("Selected") + Keys.onSelectPressed: console.log("Selected") } \endcode @@ -323,7 +323,7 @@ and click: \code MouseRegion { - onPressed: print("mouse button pressed") + onPressed: console.log("mouse button pressed") } \endcode @@ -335,7 +335,7 @@ the MouseRegion onPressed signal handler has a \e mouse parameter: \code MouseRegion { acceptedButtons: Qt.LeftButton | Qt.RightButton - onPressed: if (mouse.button == Qt.RightButton) print("Right mouse button pressed") + onPressed: if (mouse.button == Qt.RightButton) console.log("Right mouse button pressed") } \endcode diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index 263aea5..5b4f1f1 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -168,7 +168,7 @@ QML_DEFINE_TYPE(Qt,4,6,Rotation,QGraphicsRotation) \qmlproperty real Rotation::axis.z The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis, - as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 0 } }). + as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }). For a typical 3D-like rotation you will usually specify both the origin and the axis. @@ -656,7 +656,7 @@ void QmlGraphicsKeyNavigationAttached::keyReleased(QKeyEvent *event) focus: true Keys.onPressed: { if (event.key == Qt.Key_Left) { - print("move left"); + console.log("move left"); event.accepted = true; } } @@ -670,7 +670,7 @@ void QmlGraphicsKeyNavigationAttached::keyReleased(QKeyEvent *event) \code Item { focus: true - Keys.onLeftPressed: print("move left") + Keys.onLeftPressed: console.log("move left") } \endcode @@ -1359,11 +1359,11 @@ QmlGraphicsKeysAttached *QmlGraphicsKeysAttached::qmlAttachedProperties(QObject focus: true Keys.onPressed: { if (event.key == Qt.Key_Left) { - print("move left"); + console.log("move left"); event.accepted = true; } } - Keys.onSelectPressed: print("Selected"); + Keys.onSelectPressed: console.log("Selected"); } \endqml @@ -1943,8 +1943,8 @@ void QmlGraphicsItem::setClip(bool c) Whether the item is visible. By default this is true. - \note visible is not linked to actual visibility; if you item - goes off screen, or the opacity changes to 0, etc this will + \note visible is not linked to actual visibility; if an item + moves off screen, or the opacity changes to 0, this will not affect the visible property. */ @@ -2930,6 +2930,8 @@ bool QmlGraphicsItem::heightValid() const \qmlproperty bool Item::wantsFocus This property indicates whether the item has has an active focus request. + + \sa {qmlfocus}{Keyboard Focus} */ /*! \internal */ @@ -2942,6 +2944,8 @@ bool QmlGraphicsItem::wantsFocus() const \qmlproperty bool Item::focus This property indicates whether the item has keyboard input focus. Set this property to true to request focus. + + \sa {qmlfocus}{Keyboard Focus} */ /*! \internal */ diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 7f8836a..5f8b816 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -112,9 +112,9 @@ Item { \qml Rectangle { - Component.onCompleted: print("Completed Running!") + Component.onCompleted: console.log("Completed Running!") Rectangle { - Component.onCompleted: print("Nested Completed Running!") + Component.onCompleted: console.log("Nested Completed Running!") } } \endqml diff --git a/src/declarative/qml/qmlscript.cpp b/src/declarative/qml/qmlscript.cpp index eb0b858..ba62898 100644 --- a/src/declarative/qml/qmlscript.cpp +++ b/src/declarative/qml/qmlscript.cpp @@ -54,8 +54,8 @@ \qml Script { function debugMyComponent() { - print(text.text); - print(otherinterestingitem.property); + console.log(text.text); + console.log(otherinterestingitem.property); } } MouseRegion { onClicked: debugMyComponent() } diff --git a/src/declarative/qml/qmlscriptstring.cpp b/src/declarative/qml/qmlscriptstring.cpp index 6f669d5..1ccad53 100644 --- a/src/declarative/qml/qmlscriptstring.cpp +++ b/src/declarative/qml/qmlscriptstring.cpp @@ -60,12 +60,12 @@ public: The QmlScriptString is used by properties that want to accept a script "assignment" from QML. Normally, the following code would result in a binding being established for the \c script -property. If the property had a type of QmlScriptString, the script - \e {print(1921)} - itself +property. If the property had a type of QmlScriptString, the script - \e {console.log(1921)} - itself would be passed to the property and it could choose how to handle it. \code MyType { - script: print(1921) + script: console.log(1921) } \endcode */ -- cgit v0.12 From 75dc9f4475f93e149376c680cc23655b16774174 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 25 Nov 2009 17:48:49 +1000 Subject: Doc --- doc/src/declarative/declarativeui.qdoc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 7df87c5..b383836 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -46,11 +46,12 @@ \brief The Qt Declarative module provides a declarative framework for building highly dynamic, custom user interfaces. -Qt Declarative aids programmers and designers in building the animation rich, -highly fluid user interfaces that are becoming common in portable consumer -electronics devices, such as mobile phones, media players, set-top boxes and -netbooks. The Qt Declarative module provides an engine for interpreting the -declarative QML language, and a rich set of \l {QML Elements}{QML elements} that can be used +Qt Declarative UI provides a declarative framework for building highly dynamic, custom +user interfaces. Declarative UI helps programmers and designers collaborate to build +the animation rich, fluid user interfaces that are becoming common in portable +consumer devices, such as mobile phones, media players, set-top boxes and netbooks. +The Qt Declarative module provides an engine for interpreting the declarative QML +language, and a rich set of \l {QML Elements}{QML elements} that can be used from QML. QML is an extension to \l {http://www.ecma-international.org/publications/standards/Ecma-262.htm} @@ -85,12 +86,12 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \o \l {ECMAScript Blocks} \o \l {QML Scope} \o \l {Network Transparency} -\o \l {qmlmodels}{Data Models} -\o \l {anchor-layout}{Anchor-based Layout} -\o \l {qmlstates}{States} +\o \l {Data Models} +\o \l {anchor-layout.html}{Anchor-based Layout} +\o \l {qmlstates.html}{States} \o \l {qmlanimation.html}{Animation} \o \l {qmlmodules.html}{Modules} -\o \l {qmlfocus}{Keyboard Focus} +\o \l {qmlfocus.html}{Keyboard Focus} \o \l {Extending types from QML} \endlist -- cgit v0.12 From 10d689d226d5d221e8c6bc34ce0e0af4ed5b73d6 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 25 Nov 2009 12:04:25 +0100 Subject: added a snake demo --- demos/declarative/snake/Button.qml | 25 +++ demos/declarative/snake/Cookie.qml | 48 +++++ demos/declarative/snake/HighScoreModel.qml | 100 +++++++++ demos/declarative/snake/Link.qml | 75 +++++++ demos/declarative/snake/Skull.qml | 21 ++ demos/declarative/snake/Snake.qml | 189 ++++++++++++++++ demos/declarative/snake/pics/README | 1 + demos/declarative/snake/pics/background.png | Bin 0 -> 144508 bytes demos/declarative/snake/pics/blueStar.png | Bin 0 -> 272 bytes demos/declarative/snake/pics/blueStone.png | Bin 0 -> 3139 bytes demos/declarative/snake/pics/cookie.png | Bin 0 -> 2729 bytes demos/declarative/snake/pics/eyes.svg | 118 ++++++++++ demos/declarative/snake/pics/head.png | Bin 0 -> 3473 bytes demos/declarative/snake/pics/head.svg | 134 ++++++++++++ demos/declarative/snake/pics/redStar.png | Bin 0 -> 273 bytes demos/declarative/snake/pics/redStone.png | Bin 0 -> 3456 bytes demos/declarative/snake/pics/skull.png | Bin 0 -> 2543 bytes demos/declarative/snake/pics/snake.jpg | Bin 0 -> 663901 bytes demos/declarative/snake/pics/star.png | Bin 0 -> 262 bytes demos/declarative/snake/pics/stoneShadow.png | Bin 0 -> 1699 bytes demos/declarative/snake/pics/yellowStone.png | Bin 0 -> 2667 bytes demos/declarative/snake/snake.js | 308 +++++++++++++++++++++++++++ 22 files changed, 1019 insertions(+) create mode 100644 demos/declarative/snake/Button.qml create mode 100644 demos/declarative/snake/Cookie.qml create mode 100644 demos/declarative/snake/HighScoreModel.qml create mode 100644 demos/declarative/snake/Link.qml create mode 100644 demos/declarative/snake/Skull.qml create mode 100644 demos/declarative/snake/Snake.qml create mode 100644 demos/declarative/snake/pics/README create mode 100644 demos/declarative/snake/pics/background.png create mode 100644 demos/declarative/snake/pics/blueStar.png create mode 100644 demos/declarative/snake/pics/blueStone.png create mode 100644 demos/declarative/snake/pics/cookie.png create mode 100644 demos/declarative/snake/pics/eyes.svg create mode 100644 demos/declarative/snake/pics/head.png create mode 100644 demos/declarative/snake/pics/head.svg create mode 100644 demos/declarative/snake/pics/redStar.png create mode 100644 demos/declarative/snake/pics/redStone.png create mode 100644 demos/declarative/snake/pics/skull.png create mode 100644 demos/declarative/snake/pics/snake.jpg create mode 100644 demos/declarative/snake/pics/star.png create mode 100644 demos/declarative/snake/pics/stoneShadow.png create mode 100644 demos/declarative/snake/pics/yellowStone.png create mode 100644 demos/declarative/snake/snake.js diff --git a/demos/declarative/snake/Button.qml b/demos/declarative/snake/Button.qml new file mode 100644 index 0000000..63cd555 --- /dev/null +++ b/demos/declarative/snake/Button.qml @@ -0,0 +1,25 @@ +import Qt 4.6 + +Rectangle { + id: container + + signal clicked + property string text: "Button" + + color: activePalette.button; smooth: true + width: txtItem.width + 20; height: txtItem.height + 6 + border.width: 1; border.color: Qt.darker(activePalette.button); radius: 8; + + gradient: Gradient { + GradientStop { + id: topGrad; position: 0.0 + color: if (mr.pressed) { activePalette.dark } else { activePalette.light } } + GradientStop { position: 1.0; color: activePalette.button } + } + + MouseRegion { id: mr; anchors.fill: parent; onClicked: container.clicked() } + + Text { + id: txtItem; text: container.text; anchors.centerIn: container; color: activePalette.buttonText + } +} diff --git a/demos/declarative/snake/Cookie.qml b/demos/declarative/snake/Cookie.qml new file mode 100644 index 0000000..d1577ca --- /dev/null +++ b/demos/declarative/snake/Cookie.qml @@ -0,0 +1,48 @@ +import Qt 4.6 + +Item { + id: root + property bool dying: false + property int row; + property int column; + x: margin + column * gridSize + y: margin + row * gridSize + + width: gridSize + height: gridSize + property int value : 1; + + Image { + id: img + anchors.fill: parent + source: "pics/cookie.png" + opacity: 0 + opacity: Behavior { NumberAnimation { duration: 100 } } + Text { + font.bold: true + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + text: value + } + } + + + Particles { id: particles + width:1; height:1; anchors.centerIn: parent; + emissionRate: 0; + lifeSpan: 700; lifeSpanDeviation: 600; + angle: 0; angleDeviation: 360; + velocity: 100; velocityDeviation:30; + source: "pics/greenStar.png"; + } + + states: [ + State{ name: "AliveState"; when: dying == false + PropertyChanges { target: img; opacity: 1 } + }, + State{ name: "DeathState"; when: dying == true + StateChangeScript { script: particles.burst(50); } + PropertyChanges { target: img; opacity: 0 } + } + ] +} diff --git a/demos/declarative/snake/HighScoreModel.qml b/demos/declarative/snake/HighScoreModel.qml new file mode 100644 index 0000000..f585ce8 --- /dev/null +++ b/demos/declarative/snake/HighScoreModel.qml @@ -0,0 +1,100 @@ +import Qt 4.6 + +// Models a high score table. +// +// Use this component like this: +// +// HighScoreModel { +// id: highScores +// game: "MyCoolGame" +// } +// +// Then use either use the top-score properties: +// +// Text { text: "HI: " + highScores.topScore } +// +// or, use the model in a view: +// +// ListView { +// model: highScore +// delegate: Component { +// ... player ... score ... +// } +// } +// +// Add new scores via: +// +// saveScore(newScore) +// +// or: +// +// savePlayerScore(playerName,newScore) +// +// The best maxScore scores added by this method will be retained in an SQL database, +// and presented in the model and in the topScore/topPlayer properties. +// + +ListModel { + id: model + property string game: "" + property int topScore: 0 + property string topPlayer: "" + property int maxScores: 10 + + Script { + function db() + { + return openDatabaseSync("HighScoreModel", "1.0", "Generic High Score Functionality for QML", 1000000); + } + function ensureTables(tx) + { + tx.executeSql('CREATE TABLE IF NOT EXISTS HighScores(game TEXT, score INT, player TEXT)', []); + } + } + + function fillModel() { + db().transaction( + function(tx) { + ensureTables(tx); + var rs = tx.executeSql("SELECT score,player FROM HighScores WHERE game=? ORDER BY score DESC", [game]); + model.clear(); + if (rs.rows.length > 0) { + topScore = rs.rows.item(0).score + topPlayer = rs.rows.item(0).player + for (var i=0; i maxScores) + tx.executeSql("DELETE FROM HighScores WHERE game=? AND score <= ?", + [rs.rows.item(maxScores).score]); + } + } + ) + } + + function savePlayerScore(player,score) { + db().transaction( + function(tx) { + ensureTables(tx); + tx.executeSql("INSERT INTO HighScores VALUES(?,?,?)", [game,score,player]); + fillModel(); + } + ) + } + + function saveScore(score) { + savePlayerScore("player",score); + } + + function clearScores() { + db().transaction( + function(tx) { + tx.executeSql("DELETE FROM HighScores WHERE game=?", [game]); + fillModel(); + } + ) + } + + Component.onCompleted: { fillModel() } +} diff --git a/demos/declarative/snake/Link.qml b/demos/declarative/snake/Link.qml new file mode 100644 index 0000000..1b3f7bf --- /dev/null +++ b/demos/declarative/snake/Link.qml @@ -0,0 +1,75 @@ +import Qt 4.6 + +Item { id:link + property bool dying: false + property bool spawned: false + property int type: 0 + property int row: 0 + property int column: 0 + property int rotation; + + width: 40; + height: 40 + + x: margin - 3 + gridSize * column + y: margin - 3 + gridSize * row + x: Behavior { NumberAnimation { duration: spawned ? heartbeatInterval : 0} } + y: Behavior { NumberAnimation { duration: spawned ? heartbeatInterval : 0 } } + + + Item { + id: img + anchors.fill: parent + Image { + source: { + if(type == 1) { + "pics/blueStone.png"; + } else if (type == 2) { + "pics/head.png"; + } else { + "pics/redStone.png"; + } + } + + transform: Rotation { + id: actualImageRotation + origin.x: width/2; origin.y: height/2; + angle: rotation * 90 + angle: Behavior{ NumberAnimation { duration: spawned ? 200 : 0} } + } + } + + Image { + source: "pics/stoneShadow.png" + } + + opacity: 0 + opacity: Behavior { NumberAnimation { duration: 200 } } + } + + + Particles { id: particles + width:1; height:1; anchors.centerIn: parent; + emissionRate: 0; + lifeSpan: 700; lifeSpanDeviation: 600; + angle: 0; angleDeviation: 360; + velocity: 100; velocityDeviation:30; + source: { + if(type == 1){ + "pics/blueStar.png"; + } else { + "pics/redStar.png"; + } + } + } + + states: [ + State{ name: "AliveState"; when: spawned == true && dying == false + PropertyChanges { target: img; opacity: 1 } + }, + State{ name: "DeathState"; when: dying == true + StateChangeScript { script: particles.burst(50); } + PropertyChanges { target: img; opacity: 0 } + } + ] +} diff --git a/demos/declarative/snake/Skull.qml b/demos/declarative/snake/Skull.qml new file mode 100644 index 0000000..585e7d3 --- /dev/null +++ b/demos/declarative/snake/Skull.qml @@ -0,0 +1,21 @@ +import Qt 4.6 + +Image { + property bool spawned: false + property int row; + property int column; + property int verticalMovement; + property int horizontalMovement; + + x: margin + column * gridSize + 2 + y: margin + row * gridSize - 3 + x: Behavior { NumberAnimation { duration: spawned ? halfbeatInterval : 0} } + y: Behavior { NumberAnimation { duration: spawned ? halfbeatInterval : 0 } } + + opacity: spawned ? 1 : 0 + opacity: Behavior { NumberAnimation { duration: 200 } } + + source: "pics/skull.png" + width: 24 + height: 40 +} diff --git a/demos/declarative/snake/Snake.qml b/demos/declarative/snake/Snake.qml new file mode 100644 index 0000000..a9835d4 --- /dev/null +++ b/demos/declarative/snake/Snake.qml @@ -0,0 +1,189 @@ +import Qt 4.6 + +Rectangle { + id: screen; + SystemPalette { id: activePalette } + color: activePalette.window + + Script { source: "snake.js" } + + property int gridSize : 34 + property int margin: 4 + property int numRowsAvailable: Math.floor((height-32-2*margin)/gridSize) + property int numColumnsAvailable: Math.floor((width-2*margin)/gridSize) + + property int lastScore : 0 + + property int score: 0; + property int heartbeatInterval: 200 + property int halfbeatInterval: 160 + + width: 480 + height: 750 + + property int direction + property int headDirection + + property var head; + + HighScoreModel { + id: highScores + game: "Snake" + } + + Timer { + id: heartbeat; + interval: heartbeatInterval; + repeat: true + onTriggered: { move() } + } + Timer { + id: halfbeat; + interval: halfbeatInterval; + repeat: true + running: heartbeat.running + onTriggered: { moveSkull() } + } + Timer { + id: startNewGameTimer; + interval: 700; + onTriggered: {startNewGame(); } + } + + Timer { + id: startHeartbeatTimer; + interval: 1000 ; + } + + + Image { + Image { + id: title + source: "pics/snake.jpg" + fillMode: "PreserveAspectCrop" + anchors.fill: parent + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + opacity: Behavior { NumberAnimation { duration: 500 } } + + Text { + color: "white" + font.pointSize: 24 + horizontalAlignment: "AlignHCenter" + text: "Last Score:\t" + lastScore + "\nHighscore:\t" + highScores.topScore; + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: gridSize + } + } + + source: "pics/background.png" + fillMode: "PreserveAspectCrop" + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: toolbar.top + + Rectangle { + id: playfield + border.width: 1 + border.color: "white" + color: "transparent" + anchors.horizontalCenter: parent.horizontalCenter + y: (screen.height - 32 - height)/2; + width: numColumnsAvailable * gridSize + 2*margin + height: numRowsAvailable * gridSize + 2*margin + + + Skull { + id: skull + } + + MouseRegion { + anchors.fill: parent + onPressed: { + if (!head || !heartbeat.running) { + startNewGame(); + return; + } + if (direction == 0 || direction == 2) + scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); + else + scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); + } + } + } + + } + + Rectangle { + id: progressBar + opacity: 0 + opacity: Behavior { NumberAnimation { duration: 200 } } + color: "transparent" + border.width: 2 + border.color: "#221edd" + x: 50 + y: 50 + width: 200 + height: 30 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: 40 + + Rectangle { + id: progressIndicator + color: "#221edd"; + width: 0; + width: Behavior { NumberAnimation { duration: startHeartbeatTimer.running ? 1000 : 0}} + height: 30; + } + } + + Rectangle { + id: toolbar + color: activePalette.window + height: 32; width: parent.width + anchors.bottom: screen.bottom + + Button { + id: btnA; text: "New Game"; onClicked: {startNewGame();} + anchors.left: parent.left; anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + } + + Text { + color: activePalette.text + text: "Score: " + score; font.bold: true + anchors.right: parent.right; anchors.rightMargin: 3 + anchors.verticalCenter: parent.verticalCenter + } + } + + focus: true + Keys.onSpacePressed: startNewGame(); + Keys.onLeftPressed: if (state == "starting" || direction != 1) scheduleDirection(3); + Keys.onRightPressed: if (state == "starting" || direction != 3) scheduleDirection(1); + Keys.onUpPressed: if (state == "starting" || direction != 2) scheduleDirection(0); + Keys.onDownPressed: if (state == "starting" || direction != 0) scheduleDirection(2); + + states: [ + State { + name: "starting" + when: startHeartbeatTimer.running; + PropertyChanges {target: progressIndicator; width: 200} + PropertyChanges {target: title; opacity: 0} + PropertyChanges {target: progressBar; opacity: 1} + }, + State { + name: "running" + when: heartbeat.running + PropertyChanges {target: progressIndicator; width: 200} + PropertyChanges {target: title; opacity: 0} + PropertyChanges {target: skull; row: 0; column: 0; } + PropertyChanges {target: skull; spawned: 1} + } + ] + +} diff --git a/demos/declarative/snake/pics/README b/demos/declarative/snake/pics/README new file mode 100644 index 0000000..0215132 --- /dev/null +++ b/demos/declarative/snake/pics/README @@ -0,0 +1 @@ +snake.jpg: This image is based on the picture "Eastern Green Mamba.jpg" from the free media databse Wikimedia Commons and is published under the terms of the GNU Free Documentation License. The original picture was taken by Danleo. diff --git a/demos/declarative/snake/pics/background.png b/demos/declarative/snake/pics/background.png new file mode 100644 index 0000000..72dffaa Binary files /dev/null and b/demos/declarative/snake/pics/background.png differ diff --git a/demos/declarative/snake/pics/blueStar.png b/demos/declarative/snake/pics/blueStar.png new file mode 100644 index 0000000..ba7acab Binary files /dev/null and b/demos/declarative/snake/pics/blueStar.png differ diff --git a/demos/declarative/snake/pics/blueStone.png b/demos/declarative/snake/pics/blueStone.png new file mode 100644 index 0000000..356affd Binary files /dev/null and b/demos/declarative/snake/pics/blueStone.png differ diff --git a/demos/declarative/snake/pics/cookie.png b/demos/declarative/snake/pics/cookie.png new file mode 100644 index 0000000..aec2957 Binary files /dev/null and b/demos/declarative/snake/pics/cookie.png differ diff --git a/demos/declarative/snake/pics/eyes.svg b/demos/declarative/snake/pics/eyes.svg new file mode 100644 index 0000000..1078692 --- /dev/null +++ b/demos/declarative/snake/pics/eyes.svg @@ -0,0 +1,118 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/demos/declarative/snake/pics/head.png b/demos/declarative/snake/pics/head.png new file mode 100644 index 0000000..550e002 Binary files /dev/null and b/demos/declarative/snake/pics/head.png differ diff --git a/demos/declarative/snake/pics/head.svg b/demos/declarative/snake/pics/head.svg new file mode 100644 index 0000000..3bf0bd2 --- /dev/null +++ b/demos/declarative/snake/pics/head.svg @@ -0,0 +1,134 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/demos/declarative/snake/pics/redStar.png b/demos/declarative/snake/pics/redStar.png new file mode 100644 index 0000000..cd06854 Binary files /dev/null and b/demos/declarative/snake/pics/redStar.png differ diff --git a/demos/declarative/snake/pics/redStone.png b/demos/declarative/snake/pics/redStone.png new file mode 100644 index 0000000..9bb7fe4 Binary files /dev/null and b/demos/declarative/snake/pics/redStone.png differ diff --git a/demos/declarative/snake/pics/skull.png b/demos/declarative/snake/pics/skull.png new file mode 100644 index 0000000..6318616 Binary files /dev/null and b/demos/declarative/snake/pics/skull.png differ diff --git a/demos/declarative/snake/pics/snake.jpg b/demos/declarative/snake/pics/snake.jpg new file mode 100644 index 0000000..e91a784 Binary files /dev/null and b/demos/declarative/snake/pics/snake.jpg differ diff --git a/demos/declarative/snake/pics/star.png b/demos/declarative/snake/pics/star.png new file mode 100644 index 0000000..defbde5 Binary files /dev/null and b/demos/declarative/snake/pics/star.png differ diff --git a/demos/declarative/snake/pics/stoneShadow.png b/demos/declarative/snake/pics/stoneShadow.png new file mode 100644 index 0000000..1bd56af Binary files /dev/null and b/demos/declarative/snake/pics/stoneShadow.png differ diff --git a/demos/declarative/snake/pics/yellowStone.png b/demos/declarative/snake/pics/yellowStone.png new file mode 100644 index 0000000..c56124a Binary files /dev/null and b/demos/declarative/snake/pics/yellowStone.png differ diff --git a/demos/declarative/snake/snake.js b/demos/declarative/snake/snake.js new file mode 100644 index 0000000..1cea8b7 --- /dev/null +++ b/demos/declarative/snake/snake.js @@ -0,0 +1,308 @@ + +var snake = new Array; +var board = new Array; +var links = new Array; +var scheduledDirections = new Array; +var numRows = 1; +var numColumns = 1; +var linkComponent = createComponent("Link.qml"); +var cookieComponent = createComponent("Cookie.qml"); +var cookie; +var linksToGrow = 0; +var linksToDie = 0; +var waitForCookie = 0; +var growType = 0; +var skullMovementsBeforeDirectionChange = 0; + + +function rand(n) +{ + return (Math.floor(Math.random() * n)); +} + +function scheduleDirection(dir) +{ + direction = dir; + if(scheduledDirections[scheduledDirections.length-1]!=direction) + scheduledDirections.push(direction); +} + +function startNewGame() +{ + if (state == "starting") + return; + + if (heartbeat.running) { + endGame(); + startNewGameTimer.running = true; + return; + } + numRows = numRowsAvailable; + numColumns = numColumnsAvailable; + board = new Array(numRows * numColumns); + snake = new Array; + scheduledDirections = new Array; + growType = 0; + + skull.z = numRows * numColumns + 1; + + for (var i = 0; i < numRows * numColumns; ++i) { + if (i < links.length) { + var link = links[i]; + link.spawned = false; + link.dying = false; + } else { + if(linkComponent.isReady == false){ + if(linkComponent.isError == true) + print(linkComponent.errorString()); + else + print("Still loading linkComponent"); + continue;//TODO: Better error handling? + } + var link = linkComponent.createObject(); + link.parent = playfield; + link.z = numRows * numColumns + 1 - i; + link.type = i == 0 ? 2 : 0; + link.spawned = false; + link.dying = false; + links.push(link); + } + } + + head = links[0]; + snake.push(head); + head.row = numRows/2 -1; + head.column = numColumns/2 -1; + head.spawned = true; + + linksToGrow = 5; + linksToDie = 0; + waitForCookie = 5; + score = 0; + startHeartbeatTimer.running = true; + heartbeat.running = true; +} + +function endGame() +{ + heartbeat.running = false; + for(var i in snake) + snake[i].dying = true; + if (cookie) { + cookie.dying = true; + cookie = 0; + } + lastScore = score; + highScores.saveScore(lastScore); +} + +function move() { + + if (!head) + return; + + var dir = direction; + + if (scheduledDirections.length) { + dir = scheduledDirections.shift(); + } + + if (state == "starting") { + var turn = (dir - headDirection); + head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); + headDirection = dir; + return; + } + + var row = head.row; + var column = head.column; + + if (dir == 0) { + row = row - 1; + } else if (dir == 1) { + column = column + 1 + } else if (dir == 2) { + row = row + 1; + } else if (dir == 3) { + column = column - 1; + } + + //validate the new position + if (row < 0 || row >= numRows + || column < 0 || column >= numColumns + || (row == skull.row && column == skull.column) + || !isFree(row, column)) { + var turn = (dir - headDirection); + head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); + headDirection = dir; + endGame(); + return; + } + + var newLink; + if (linksToGrow > 0) { + --linksToGrow; + newLink = links[snake.length]; + newLink.spawned = false; + newLink.rotation = snake[snake.length-1].rotation; + newLink.type = growType; + newLink.dying = false; + snake.push(newLink); + } else { + var lastLink = snake[snake.length-1]; + board[lastLink.row * numColumns + lastLink.column] = Undefined; + } + + if (waitForCookie > 0) { + if (--waitForCookie == 0) + createCookie(cookie? (cookie.value+1) : 1); + } + + for (var i = snake.length-1; i > 0; --i) { + snake[i].row = snake[i-1].row; + snake[i].column = snake[i-1].column; + snake[i].rotation = snake[i-1].rotation; + } + + if (newLink) { + newLink.spawned = true; + } + + // move the head + head.row = row; + head.column = column; + board[row * numColumns + column] = head; + + var turn = (dir - headDirection); + head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); + headDirection = dir; + + var value = testCookie(row, column); + if (value > 0) { + linksToGrow += value; + score += value; + } +} + +function isFree(row, column) +{ + return board[row * numColumns + column] == Undefined; +} + +function isHead(row, column) +{ + return head.column == column && head.row == row; +} + +function testCookie(row, column) +{ + if (cookie && !cookie.dying && cookie.row == row && cookie.column == column) { + var value = cookie.value; + waitForCookie = value; + growType = snake[snake.length-1].type == 1 ? 0 : 1; + cookie.dying = true; + cookie.z = numRows * numColumns + 2; + return value; + } + return 0; +} + +function moveSkull() +{ + + if (linksToDie > 0) { + --linksToDie; + var link = snake.pop(); + link.dying = true; + board[link.row * numColumns + link.column] = Undefined; + if (score > 0) + --score; + if (snake.length == 0) { + endGame(); + return; + } + } + + var row = skull.row; + var column = skull.column; + if (isHead(row, column)) { + endGame(); + return; + } + row += skull.verticalMovement; + column += skull.horizontalMovement; + + var attempts = 4; + + while (skullMovementsBeforeDirectionChange == 0 || row < 0 || row >= numRows + || column < 0 || column >= numColumns + || (!isFree(row, column) && !isHead(row, column))) { + var d = rand(8); + skull.verticalMovement = 0; + skull.horizontalMovement = 0; + skullMovementsBeforeDirectionChange = rand(20)+1; + if (d == 0) { + skull.verticalMovement = -1 + } else if (d == 1) { + skull.horizontalMovement = -1; + } else if (d == 2) { + skull.verticalMovement = 1 + } else if (d == 3){ + skull.horizontalMovement = 1; + } else if (cookie) { + var rd = cookie.row - skull.row; + var rc = cookie.column - skull.column; + if (Math.abs(rd) > Math.abs(rc)) { + skull.verticalMovement = rd > 0 ? 1 : -1; + skullMovementsBeforeDirectionChange = Math.abs(rd); + } else { + skull.horizontalMovement= rc > 0 ? 1 : -1; + skullMovementsBeforeDirectionChange = Math.abs(rc); + } + } + row = skull.row + skull.verticalMovement; + column = skull.column + skull.horizontalMovement; + if (--attempts == 0) + return; + } + + skull.row = row; + skull.column = column; + --skullMovementsBeforeDirectionChange; + var value = testCookie(row, column); + if (value > 0) + linksToDie += value/2; + + if (isHead(row, column)) + endGame(); +} + +function createCookie(value) { + if (numRows * numColumns - snake.length < 10) + return; + + var column = rand(numColumns); + var row = rand(numRows); + while (!isFree(row, column)) { + column++; + if (column == numColumns) { + column = 0; + row++; + if (row == numRows) + row = 0; + } + } + + if(cookieComponent.isReady == false){ + if(cookieComponent.isError == true) + print(cookieComponent.errorString()); + else + print("Still loading cookieComponent"); + return;//TODO: Better error handling? + } + cookie = cookieComponent.createObject(); + cookie.parent = head.parent; + cookie.value = value; + cookie.row = row; + cookie.column = column; +} -- cgit v0.12 From 59a0002b1eaedd1961136b364a595c376755e085 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 25 Nov 2009 16:04:00 +0100 Subject: Treat emissionRate=0 like emitting=false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Including stopping the timer because we arenæt emitting anything. Because emissionRate=0 is exactly the same as emitting=false, the emitting property has been removed. Task-number: QTBUG-6209 --- .../graphicsitems/qmlgraphicsparticles.cpp | 54 ++++------------------ .../graphicsitems/qmlgraphicsparticles_p.h | 4 -- .../tst_qmlgraphicsparticles.cpp | 3 -- .../visual/qmlgraphicsparticles/particles.qml | 7 ++- 4 files changed, 16 insertions(+), 52 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp index a0b41e8..f15d9f6 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp @@ -372,7 +372,7 @@ public: , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300) , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.) , addParticleTime(0), addParticleCount(0), lastAdvTime(0) - , emitting(true), motion(0), pendingPixmapCache(false), clock(this) + , motion(0), pendingPixmapCache(false), clock(this) { } @@ -407,7 +407,6 @@ public: int addParticleTime; int addParticleCount; int lastAdvTime; - bool emitting; QmlGraphicsParticleMotion *motion; QmlGraphicsParticlesPainter *paintItem; @@ -443,14 +442,14 @@ void QmlGraphicsParticlesPrivate::tick(int time) } if(emissionRate == -1)//Otherwise leave emission to the emission rate - while(removed-- && ((count == -1) || particles.count() < count) && emitting) + while(removed-- && ((count == -1) || particles.count() < count)) createParticle(time); if (!addParticleTime) addParticleTime = time; //Possibly emit new particles - if (((count == -1) || particles.count() < count) && emitting + if (((count == -1) || particles.count() < count) && emissionRate && !(count==-1 && emissionRate==-1)) { int emissionCount = -1; if (emissionRate != -1){ @@ -497,7 +496,7 @@ void QmlGraphicsParticlesPrivate::tick(int time) lastAdvTime = time; paintItem->updateSize(); paintItem->update(); - if (!(oldCount || particles.count()) && (!count || !emitting) && bursts.isEmpty()) { + if (!(oldCount || particles.count()) && (!count || !emissionRate) && bursts.isEmpty()) { lastAdvTime = 0; clock.stop(); } @@ -733,7 +732,7 @@ void QmlGraphicsParticles::setCount(int cnt) d->count = cnt; d->addParticleTime = 0; d->addParticleCount = d->particles.count(); - if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emitting) { + if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { d->clock.start(); } d->paintItem->updateSize(); @@ -774,6 +773,9 @@ void QmlGraphicsParticles::setEmissionRate(int er) if(er == d->emissionRate) return; d->emissionRate = er; + if (d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) { + d->clock.start(); + } emit emissionRateChanged(); } @@ -1100,42 +1102,6 @@ void QmlGraphicsParticles::setVelocityDeviation(qreal velocity) } /*! - \qmlproperty bool Particles::emitting - This property determines whether new particles are created - - If emitting is set to false no new particles will be created. This means that - when a particle reaches the end of its lifespan it is not replaced. This - property can be used to turn particles on and off with a more natural look. - - The default setting is true. Note that if it initialized to false no particles - will be produced until it is set to true. -*/ -/*! - \property QmlGraphicsParticles::emitting - If emitting is set to false no new particles will be created. This means that - when a particle reaches the end of its lifespan it is not replaced. This - property can be used to turn particles on and off with a more natural look. - - The default setting is true. Note that if it initialized to false no particles - will be produced until it is set to true. -*/ -bool QmlGraphicsParticles::emitting() const -{ - Q_D(const QmlGraphicsParticles); - return d->emitting; -} - -void QmlGraphicsParticles::setEmitting(bool r) -{ - Q_D(QmlGraphicsParticles); - if(d->emitting == r) - return; - d->emitting = r; - if (d->count && r) - d->clock.start(); - emit emittingChanged(); -} -/*! \qmlproperty ParticleMotion Particles::motion This property sets the type of motion to apply to the particles. @@ -1178,7 +1144,7 @@ void QmlGraphicsParticles::setMotion(QmlGraphicsParticleMotion *motion) burst. If the second argument is omitted, it is treated as -1. The burst of particles has a separate emissionRate and count to the normal emission of particles. The burst uses the same values as normal emission for all other - properties, including emissionVariance and emitting. + properties, including emissionVariance. The normal emission of particles will continue during the burst, however the particles created by the burst count towards the maximum number used by @@ -1189,7 +1155,7 @@ void QmlGraphicsParticles::burst(int count, int emissionRate) { Q_D(QmlGraphicsParticles); d->bursts << qMakePair(count, emissionRate); - if (d->clock.state() != QAbstractAnimation::Running && d->emitting) + if (d->clock.state() != QAbstractAnimation::Running) d->clock.start(); } diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h index 02c4e6d..3cb3ff6 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h @@ -157,7 +157,6 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsParticles : public QmlGraphicsItem Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged) Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged) - Q_PROPERTY(bool emitting READ emitting WRITE setEmitting NOTIFY emittingChanged) Q_PROPERTY(QmlGraphicsParticleMotion *motion READ motion WRITE setMotion) Q_CLASSINFO("DefaultProperty", "motion") @@ -201,9 +200,6 @@ public: qreal velocityDeviation() const; void setVelocityDeviation(qreal); - bool emitting() const; - void setEmitting(bool); - QmlGraphicsParticleMotion *motion() const; void setMotion(QmlGraphicsParticleMotion *); diff --git a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp index c8d181b..ed68eaf 100644 --- a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp +++ b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp @@ -96,9 +96,6 @@ void tst_QmlGraphicsParticles::properties() particles->setEmissionRate(12); QCOMPARE(particles->emissionRate(), 12); - - particles->setEmitting(false); - QCOMPARE(particles->emitting(), false); } void tst_QmlGraphicsParticles::runs() diff --git a/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml b/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml index a7a8143..2d481c9 100644 --- a/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml +++ b/tests/auto/declarative/visual/qmlgraphicsparticles/particles.qml @@ -3,7 +3,12 @@ import Qt 4.6 Rectangle { width: 640; height: 480; color: "black" - Particles { emitting: false } + Particles { id:particlesAnotEmitting + y:60; width: 260; height:30; source: "star.png"; + lifeSpan:1000; count: 50; angle:70; angleDeviation:36; + velocity:30; velocityDeviation:10; emissionRate: 0 + ParticleMotionWander { yvariance:5; xvariance:30; pace:100 } + } Particles { id:particlesA y:0; width: 260; height:30; source: "star.png"; lifeSpan:1000; count: 50; angle:70; angleDeviation:36; -- cgit v0.12 From 74aee53beb00f13fdcfcdaa0657aff259d7c962b Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 26 Nov 2009 10:54:45 +1000 Subject: Ensure running is set to false when the timer stops. --- src/declarative/util/qmltimer.cpp | 2 ++ tests/auto/declarative/qmltimer/tst_qmltimer.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index da60193..9b54337 100644 --- a/src/declarative/util/qmltimer.cpp +++ b/src/declarative/util/qmltimer.cpp @@ -303,7 +303,9 @@ void QmlTimer::finished() if (d->repeating || !d->running) return; emit triggered(); + d->running = false; d->firstTick = false; + emit runningChanged(); } QT_END_NAMESPACE diff --git a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp index 63a9a09..d681fbb 100644 --- a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -105,6 +105,7 @@ void tst_qmltimer::notRepeating() QCOMPARE(helper.count, 1); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 1); + QVERIFY(timer->isRunning() == false); } void tst_qmltimer::notRepeatingStart() @@ -126,6 +127,7 @@ void tst_qmltimer::notRepeatingStart() QCOMPARE(helper.count, 1); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 1); + QVERIFY(timer->isRunning() == false); delete timer; } @@ -147,11 +149,14 @@ void tst_qmltimer::repeat() QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count > oldCount); + QVERIFY(timer->isRunning()); oldCount = helper.count; timer->stop(); + QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count == oldCount); + QVERIFY(timer->isRunning() == false); delete timer; } @@ -173,6 +178,7 @@ void tst_qmltimer::triggeredOnStart() QCOMPARE(helper.count, 2); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 2); + QVERIFY(timer->isRunning() == false); delete timer; } @@ -194,6 +200,7 @@ void tst_qmltimer::triggeredOnStartRepeat() int oldCount = helper.count; QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count > oldCount); + QVERIFY(timer->isRunning()); delete timer; } @@ -234,6 +241,7 @@ void tst_qmltimer::changeDuration() QTest::qWait(600); QCOMPARE(helper.count, 3); + QVERIFY(timer->isRunning()); delete timer; } @@ -259,6 +267,7 @@ void tst_qmltimer::restart() QTest::qWait(700); QCOMPARE(helper.count, 2); + QVERIFY(timer->isRunning()); delete timer; } -- cgit v0.12 From 0204bc0a7031d017f8999bc73005fab46cc59d5e Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 26 Nov 2009 13:54:21 +1000 Subject: Doc. --- doc/src/declarative/qtdeclarative.qdoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc index 5947429..6a94b6e 100644 --- a/doc/src/declarative/qtdeclarative.qdoc +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -47,4 +47,21 @@ \brief The Qt Declarative module provides a declarative framework for building highly dynamic, custom user interfaces. +To include the definitions of the module's classes, use the +following directive: + +\code +#include +\endcode + +To link against the module, add this line to your \l qmake \c +.pro file: + +\code +QT += declarative +\endcode + +For more information on the Qt Declarative module, see the +\l{declarativeui.html}{Declarative UI} documentation. + */ -- cgit v0.12 From dbc13c80c8d06af0aa2187946d3fb2bab1654f2e Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 26 Nov 2009 14:10:01 +1000 Subject: doc fixes --- doc/src/declarative/advtutorial.qdoc | 2 +- doc/src/declarative/advtutorial4.qdoc | 4 ++-- doc/src/declarative/anchor-layout.qdoc | 2 +- doc/src/declarative/examples.qdoc | 26 ++++++++++++-------------- doc/src/declarative/qmlstates.qdoc | 17 +++++++++++++++-- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc index 60dc0e6..1456eae9 100644 --- a/doc/src/declarative/advtutorial.qdoc +++ b/doc/src/declarative/advtutorial.qdoc @@ -47,7 +47,7 @@ This tutorial goes step-by-step through creating a full application using just Q It is assumed that you already know basic QML (such as from doing the simple tutorial) and the focus is on showing how to turn that knowledge into a complete and functioning application. -This tutorial involves a significant amount of javascript to implement the game logic. An understanding of javascript is helpful to understand the javascript parts of this tutorial, but if you don't understand javascript you can still get a feel for how to integrate QML elements with backend logic which creates and controls them. From the QML perspective, there is little difference between integrating with backend logic written in C++ and backend logic written in javascript. +This tutorial involves a significant amount of JavaScript to implement the game logic. An understanding of JavaScript is helpful to understand the JavaScript parts of this tutorial, but if you don't understand JavaScript you can still get a feel for how to integrate QML elements with backend logic which creates and controls them. From the QML perspective, there is little difference between integrating with backend logic written in C++ and backend logic written in JavaScript. In this tutorial we recreate, step by step, the Same Game demo in $QTDIR/demos/declarative/samegame.qml. The results of the individual steps are in the $QTDIR/examples/declarative/tutorials/samegame directory. diff --git a/doc/src/declarative/advtutorial4.qdoc b/doc/src/declarative/advtutorial4.qdoc index aaa7293..96e72fc 100644 --- a/doc/src/declarative/advtutorial4.qdoc +++ b/doc/src/declarative/advtutorial4.qdoc @@ -126,7 +126,7 @@ if they exit this dialog without entering it they have a way to opt out of posti \snippet declarative/tutorials/samegame/samegame4/content/samegame.js 2 -For offline storage, we use the HTML 5 offline storage javascript API to maintain a persistant SQL database unique to this application. This first line in this function calls the function for the web-based high scores, described later, if it has been setup. Next we create an offline storage database for the high scores using openDatabase and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrival, and in the db.transaction call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string. For a more detailed explanation of the offline storage API in QML, consult the global object documentation. +For offline storage, we use the HTML 5 offline storage JavaScript API to maintain a persistant SQL database unique to this application. This first line in this function calls the function for the web-based high scores, described later, if it has been setup. Next we create an offline storage database for the high scores using openDatabase and prepare the data and SQL query that we want to use to save it. The offline storage API uses SQL queries for data manipulation and retrival, and in the db.transaction call we use three SQL queries to initialize the database (if necessary), and then add to and retrieve high scores. To use the returned data, we turn it into a string with one line per row returned, and show a dialog containing that string. For a more detailed explanation of the offline storage API in QML, consult the global object documentation. This is one way of storing and displaying high scores locally, but not the only way. A more complex alternative would have been to create a high score dialog component, and pass the results to it for processing and display (instead of resusing the Dialog). This would allow a more themable dialog that could present the high scores better. If your QML is the UI for a C++ application, you could also have passed the score to a C++ function to store it locally in a variety of ways, including a simple format without SQL or in another SQL database. @@ -141,7 +141,7 @@ if the player entered their name we can send the data to the web service in the \snippet declarative/tutorials/samegame/samegame4/content/samegame.js 1 -This is the same \c XMLHttpRequest() as you'll find in browser javascript, and can be used in the same way to dynamically get XML +This is the same \c XMLHttpRequest() as you'll find in browser JavaScript, and can be used in the same way to dynamically get XML or QML from the web service to display the high scores. We don't worry about the response in this case, we just post the high score data to the web server. If it had returned a QML file (or a URL to a QML file) you could instantiate it in much the same way as you did the blocks. diff --git a/doc/src/declarative/anchor-layout.qdoc b/doc/src/declarative/anchor-layout.qdoc index 503b881..4766236 100644 --- a/doc/src/declarative/anchor-layout.qdoc +++ b/doc/src/declarative/anchor-layout.qdoc @@ -44,7 +44,7 @@ \target anchor-layout \title Anchor-based Layout in QML -In addition to the more traditional \l Grid, \l Row, and \l Column, QML also provides a way to layout items using the concept of anchors. Each item can be thought of as having a set of 6 invisible "anchor lines": \e left, \e horizontalCenter, \e right, \e top, \e verticalCenter, and \e bottom. +In addition to the more traditional \l Grid, \l Row, and \l Column, QML also provides a way to layout items using the concept of \e anchors. Each item can be thought of as having a set of 6 invisible "anchor lines": \e left, \e horizontalCenter, \e right, \e top, \e verticalCenter, and \e bottom. \image edges_qml.png diff --git a/doc/src/declarative/examples.qdoc b/doc/src/declarative/examples.qdoc index 7950f66..3288e17 100644 --- a/doc/src/declarative/examples.qdoc +++ b/doc/src/declarative/examples.qdoc @@ -43,33 +43,31 @@ \page qmlexamples.html \title QML Examples and Walkthroughs -\section1 Running Examples +\section1 Running Examples and Demos -A \l {qmlviewer}{viewer} application is included that allows you to quickly explore many of the -examples. It has some useful options, revealed by: +You can find many simple examples in the \c examples/declarative +sub-directory that show how to use various aspects of QML. In addition, the +\c demos/declarative sub-directory contains more sophisticated demos of large +applications. These demos are intended to show integrated functionality +rather than being instructive on specifice elements. + +To run the examples and demos, use the included \l {qmlviewer}{qmlviewer} +application. It has some useful options, revealed by: \code bin/qmlviewer -help \endcode -There are several illustrative QML examples available. From your build -directory, +For example, from your build directory, run: \code - bin/qmlviewer $QT_SOURCE_DIR/demos/declarative/flickr/flickr-desktop.qml + bin/qmlviewer $QTDIR/demos/declarative/flickr/flickr-desktop.qml \endcode or \code - bin/qmlviewer $QT_SOURCE_DIR/demos/declarative/samegame/samegame.qml + bin/qmlviewer $QTDIR/demos/declarative/samegame/samegame.qml \endcode -Many other simple examples can be found under the \c examples/declarative sub -directory. Some can be run directly using the viewer like those above, and -others require you to build and run an executable. More sophisticated demos of -large applications can be found under the \c demos/declarative sub directory. -These are intended to show more integrated functionality rather than to be -instructive on specific elements. - \section1 Examples These will be documented, and demonstrate how to achieve various things in QML. diff --git a/doc/src/declarative/qmlstates.qdoc b/doc/src/declarative/qmlstates.qdoc index 245a57f..abf3c93 100644 --- a/doc/src/declarative/qmlstates.qdoc +++ b/doc/src/declarative/qmlstates.qdoc @@ -29,7 +29,7 @@ In QML: \o A state can affect the properties of other objects, not just the object owning the state (and not just that object's children). \endlist -Here is an example of using states. In the default state \c myRect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. Clicking within the mouse region changes the state from the default state to the 'moved' state. +Here is an example of using states. In the default state \c myRect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. Clicking within the mouse region changes the state from the default state to the 'moved' state, thus moving the rectangle. \qml Item { @@ -60,7 +60,20 @@ Item { } \endqml -State changes can be animated using \l{state-transitions}{transitions}. +State changes can be animated using \l{state-transitions}{Transitions}. + +For example, adding this code to the above \c {Item {}} element animates the transition to the "moved" state: + +\qml + transitions: [ + Transition { + NumberAnimation { matchProperties: "x,y"; duration: 500 } + } + ] +\endqml + +See \l{state-transitions}{Transitions} for more information. + Other things you can do in a state change: \list -- cgit v0.12