diff options
62 files changed, 1459 insertions, 208 deletions
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<rs.rows.length; ++i) { + if (i < maxScores) + model.append(rs.rows.item(i)) + } + if (rs.rows.length > 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 Binary files differnew file mode 100644 index 0000000..72dffaa --- /dev/null +++ b/demos/declarative/snake/pics/background.png diff --git a/demos/declarative/snake/pics/blueStar.png b/demos/declarative/snake/pics/blueStar.png Binary files differnew file mode 100644 index 0000000..ba7acab --- /dev/null +++ b/demos/declarative/snake/pics/blueStar.png diff --git a/demos/declarative/snake/pics/blueStone.png b/demos/declarative/snake/pics/blueStone.png Binary files differnew file mode 100644 index 0000000..356affd --- /dev/null +++ b/demos/declarative/snake/pics/blueStone.png diff --git a/demos/declarative/snake/pics/cookie.png b/demos/declarative/snake/pics/cookie.png Binary files differnew file mode 100644 index 0000000..aec2957 --- /dev/null +++ b/demos/declarative/snake/pics/cookie.png 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + width="40" + height="40" + version="1.0" + sodipodi:docname="eyes.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:export-filename="/home/ettrich/dev/research/qml-validate/snake/pics/eyes.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs5"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective9" /> + </defs> + <sodipodi:namedview + inkscape:window-height="838" + inkscape:window-width="907" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + showgrid="false" + inkscape:zoom="12.35" + inkscape:cx="20" + inkscape:cy="20" + inkscape:window-x="117" + inkscape:window-y="45" + inkscape:current-layer="svg2" /> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path2384" + sodipodi:cx="18.056681" + sodipodi:cy="9.5141697" + sodipodi:rx="7.1255059" + sodipodi:ry="11.295547" + d="M 25.182187,9.5141697 A 7.1255059,11.295547 0 1 1 10.931175,9.5141697 A 7.1255059,11.295547 0 1 1 25.182187,9.5141697 z" + transform="matrix(1.0089865,0,0,0.5462656,-4.9233835,3.3301401)" /> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path3158" + sodipodi:cx="18.056681" + sodipodi:cy="9.5141697" + sodipodi:rx="7.1255059" + sodipodi:ry="11.295547" + d="M 25.182187,9.5141697 A 7.1255059,11.295547 0 1 1 10.931175,9.5141697 A 7.1255059,11.295547 0 1 1 25.182187,9.5141697 z" + transform="matrix(1.0089865,0,0,0.5462656,9.6190931,3.3522563)" /> + <path + sodipodi:type="arc" + style="fill:#000000;fill-opacity:1" + id="path3182" + sodipodi:cx="16.275303" + sodipodi:cy="12.307693" + sodipodi:rx="2.2672064" + sodipodi:ry="3.4008098" + d="M 18.542509,12.307693 A 2.2672064,3.4008098 0 0 1 14.008446,12.367372" + sodipodi:start="0" + sodipodi:end="3.1240432" + transform="translate(11.65992,-9.740891)" + sodipodi:open="true" /> + <rect + style="fill:#000000;fill-opacity:0" + id="rect2382" + width="40" + height="40" + x="0" + y="-7.1054274e-15" + inkscape:export-filename="/home/ettrich/dev/research/qml-validate/snake/pics/eyes.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> + <path + sodipodi:type="arc" + style="fill:#000000;fill-opacity:1" + id="path2383" + sodipodi:cx="16.275303" + sodipodi:cy="12.307693" + sodipodi:rx="2.2672064" + sodipodi:ry="3.4008098" + d="M 18.542509,12.307693 A 2.2672064,3.4008098 0 0 1 14.008446,12.367372" + sodipodi:start="0" + sodipodi:end="3.1240432" + transform="translate(-3.3200119,-9.821862)" + sodipodi:open="true" /> +</svg> diff --git a/demos/declarative/snake/pics/head.png b/demos/declarative/snake/pics/head.png Binary files differnew file mode 100644 index 0000000..550e002 --- /dev/null +++ b/demos/declarative/snake/pics/head.png 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + width="40" + height="40" + version="1.0" + sodipodi:docname="head.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:export-filename="/home/ettrich/dev/research/qml-validate/snake/pics/head.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs5"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective9" /> + <inkscape:perspective + id="perspective2444" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 526.18109 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <sodipodi:namedview + inkscape:window-height="838" + inkscape:window-width="907" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + showgrid="false" + inkscape:zoom="12.35" + inkscape:cx="20" + inkscape:cy="20" + inkscape:window-x="117" + inkscape:window-y="45" + inkscape:current-layer="svg2" /> + <image + y="0.21862352" + x="-0.048582077" + id="image2446" + height="40" + width="40" + sodipodi:absref="/home/ettrich/dev/research/qml-validate/snake/pics/redStone.png" + xlink:href="redStone.png" /> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path2384" + sodipodi:cx="18.056681" + sodipodi:cy="9.5141697" + sodipodi:rx="7.1255059" + sodipodi:ry="11.295547" + d="M 25.182187,9.5141697 A 7.1255059,11.295547 0 1 1 10.931175,9.5141697 A 7.1255059,11.295547 0 1 1 25.182187,9.5141697 z" + transform="matrix(1.0089865,0,0,0.5462656,-4.9233835,3.3301401)" /> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path3158" + sodipodi:cx="18.056681" + sodipodi:cy="9.5141697" + sodipodi:rx="7.1255059" + sodipodi:ry="11.295547" + d="M 25.182187,9.5141697 A 7.1255059,11.295547 0 1 1 10.931175,9.5141697 A 7.1255059,11.295547 0 1 1 25.182187,9.5141697 z" + transform="matrix(1.0089865,0,0,0.5462656,9.6190931,3.3522563)" /> + <path + sodipodi:type="arc" + style="fill:#000000;fill-opacity:1" + id="path3182" + sodipodi:cx="16.275303" + sodipodi:cy="12.307693" + sodipodi:rx="2.2672064" + sodipodi:ry="3.4008098" + d="M 18.542509,12.307693 A 2.2672064,3.4008098 0 0 1 14.008446,12.367372" + sodipodi:start="0" + sodipodi:end="3.1240432" + transform="translate(11.65992,-9.740891)" + sodipodi:open="true" /> + <rect + style="fill:#000000;fill-opacity:0" + id="rect2382" + width="40" + height="40" + x="0" + y="-7.1054274e-15" + inkscape:export-filename="/home/ettrich/dev/research/qml-validate/snake/pics/eyes.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> + <path + sodipodi:type="arc" + style="fill:#000000;fill-opacity:1" + id="path2383" + sodipodi:cx="16.275303" + sodipodi:cy="12.307693" + sodipodi:rx="2.2672064" + sodipodi:ry="3.4008098" + d="M 18.542509,12.307693 A 2.2672064,3.4008098 0 0 1 14.008446,12.367372" + sodipodi:start="0" + sodipodi:end="3.1240432" + transform="translate(-3.3200119,-9.821862)" + sodipodi:open="true" /> +</svg> diff --git a/demos/declarative/snake/pics/redStar.png b/demos/declarative/snake/pics/redStar.png Binary files differnew file mode 100644 index 0000000..cd06854 --- /dev/null +++ b/demos/declarative/snake/pics/redStar.png diff --git a/demos/declarative/snake/pics/redStone.png b/demos/declarative/snake/pics/redStone.png Binary files differnew file mode 100644 index 0000000..9bb7fe4 --- /dev/null +++ b/demos/declarative/snake/pics/redStone.png diff --git a/demos/declarative/snake/pics/skull.png b/demos/declarative/snake/pics/skull.png Binary files differnew file mode 100644 index 0000000..6318616 --- /dev/null +++ b/demos/declarative/snake/pics/skull.png diff --git a/demos/declarative/snake/pics/snake.jpg b/demos/declarative/snake/pics/snake.jpg Binary files differnew file mode 100644 index 0000000..e91a784 --- /dev/null +++ b/demos/declarative/snake/pics/snake.jpg diff --git a/demos/declarative/snake/pics/star.png b/demos/declarative/snake/pics/star.png Binary files differnew file mode 100644 index 0000000..defbde5 --- /dev/null +++ b/demos/declarative/snake/pics/star.png diff --git a/demos/declarative/snake/pics/stoneShadow.png b/demos/declarative/snake/pics/stoneShadow.png Binary files differnew file mode 100644 index 0000000..1bd56af --- /dev/null +++ b/demos/declarative/snake/pics/stoneShadow.png diff --git a/demos/declarative/snake/pics/yellowStone.png b/demos/declarative/snake/pics/yellowStone.png Binary files differnew file mode 100644 index 0000000..c56124a --- /dev/null +++ b/demos/declarative/snake/pics/yellowStone.png 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; +} 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/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/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/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/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 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/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/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/extending.qdoc b/doc/src/declarative/extending.qdoc index 7a9de60..056b8ab 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, @@ -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 @@ -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 @@ -714,11 +715,12 @@ binding, the alias reference syntax is highly restricted. An alias reference takes one of the following forms \code - <Id>.<property> - <Id> + <id>.<property> + <id> \endcode -where <Id> must refer to an object id within the same component as the type -declaring the alias, and, optionally, <property> refers to a property on that object. + +where <id> must refer to an object id within the same component as the type +declaring the alias, and, optionally, <property> refers to a property on that object. Here is the property definition example rewritten to use property aliases. \code @@ -843,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 8061a7c..46bfc38 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: @@ -65,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 {} } } @@ -305,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/doc/src/declarative/qmlstates.qdoc b/doc/src/declarative/qmlstates.qdoc index ddb0fc8..abf3c93 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,51 @@ 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, thus moving the rectangle. -\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 + +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. -To animate state changes, you can use \l{state-transitions}{transitions}. Other things you can do in a state change: \list 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 <QtDeclarative> +\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. + */ 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/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] } 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 diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 61b6ecc..8642476 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -349,9 +349,13 @@ 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; + emit fillChanged(); return; } if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){ @@ -361,10 +365,15 @@ void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) d->remDepend(d->fill); d->fill = f; d->addDepend(d->fill); - + emit fillChanged(); d->fillChanged(); } +void QmlGraphicsAnchors::resetFill() +{ + setFill(0); +} + QmlGraphicsItem *QmlGraphicsAnchors::centerIn() const { Q_D(const QmlGraphicsAnchors); @@ -374,9 +383,13 @@ 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; + emit centerInChanged(); return; } if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){ @@ -387,10 +400,15 @@ void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) d->remDepend(d->centerIn); d->centerIn = c; d->addDepend(d->centerIn); - + emit centerInChanged(); d->centerInChanged(); } +void QmlGraphicsAnchors::resetCenterIn() +{ + setCenterIn(0); +} + bool QmlGraphicsAnchorsPrivate::calcStretch(const QmlGraphicsAnchorLine &edge1, const QmlGraphicsAnchorLine &edge2, int offset1, @@ -553,7 +571,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 +584,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 +594,7 @@ void QmlGraphicsAnchors::resetTop() d->usedAnchors &= ~HasTopAnchor; d->remDepend(d->top.item); d->top = QmlGraphicsAnchorLine(); + emit topChanged(); d->updateVerticalAnchors(); } @@ -587,7 +607,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 +620,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 +630,7 @@ void QmlGraphicsAnchors::resetBottom() d->usedAnchors &= ~HasBottomAnchor; d->remDepend(d->bottom.item); d->bottom = QmlGraphicsAnchorLine(); + emit bottomChanged(); d->updateVerticalAnchors(); } @@ -621,7 +643,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 +656,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 +666,7 @@ void QmlGraphicsAnchors::resetVerticalCenter() d->usedAnchors &= ~HasVCenterAnchor; d->remDepend(d->vCenter.item); d->vCenter = QmlGraphicsAnchorLine(); + emit verticalCenterChanged(); d->updateVerticalAnchors(); } @@ -655,7 +679,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 +692,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 +702,7 @@ void QmlGraphicsAnchors::resetBaseline() d->usedAnchors &= ~HasBaselineAnchor; d->remDepend(d->baseline.item); d->baseline = QmlGraphicsAnchorLine(); + emit baselineChanged(); d->updateVerticalAnchors(); } @@ -689,7 +715,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 +728,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 +738,7 @@ void QmlGraphicsAnchors::resetLeft() d->usedAnchors &= ~HasLeftAnchor; d->remDepend(d->left.item); d->left = QmlGraphicsAnchorLine(); + emit leftChanged(); d->updateHorizontalAnchors(); } @@ -723,7 +751,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 +764,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 +774,7 @@ void QmlGraphicsAnchors::resetRight() d->usedAnchors &= ~HasRightAnchor; d->remDepend(d->right.item); d->right = QmlGraphicsAnchorLine(); + emit rightChanged(); d->updateHorizontalAnchors(); } @@ -758,7 +787,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 +800,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 +810,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..507b4d8 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 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; @@ -155,6 +157,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) 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/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); 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/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/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 7242498..ba62898 100644 --- a/src/declarative/qml/qmlscript.cpp +++ b/src/declarative/qml/qmlscript.cpp @@ -43,40 +43,45 @@ /*! \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 { function debugMyComponent() { - print(text.text); - print(otherinterestingitem.property); + console.log(text.text); + console.log(otherinterestingitem.property); } } 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/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 */ 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<Signal>" 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<Signal> 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 { 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."; diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index 6ac4e32..9b54337 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; }; /*! @@ -88,6 +89,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) @@ -95,8 +102,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); } @@ -145,6 +151,7 @@ void QmlTimer::setRunning(bool running) Q_D(QmlTimer); if (d->running != running) { d->running = running; + d->firstTick = true; emit runningChanged(); update(); } @@ -232,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); @@ -239,10 +260,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); } @@ -270,18 +292,20 @@ 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->running = false; + d->firstTick = false; + emit runningChanged(); } QT_END_NAMESPACE diff --git a/src/declarative/util/qmltimer_p.h b/src/declarative/util/qmltimer_p.h index bd96d4a..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(); @@ -95,7 +96,7 @@ private: private Q_SLOTS: void ticked(); - void stateChanged(QAbstractAnimation::State,QAbstractAnimation::State); + void finished(); }; QT_END_NAMESPACE 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); 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<QmlGraphicsImage*>(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" 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/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp index cf54647..d681fbb 100644 --- a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -42,6 +42,7 @@ #include <QtDeclarative/qmlengine.h> #include <QtDeclarative/qmlcomponent.h> #include <private/qmltimer_p.h> +#include <QDebug> class tst_qmltimer : public QObject { @@ -56,6 +57,8 @@ private slots: void noTriggerIfNotRunning(); void triggeredOnStart(); void triggeredOnStartRepeat(); + void changeDuration(); + void restart(); }; class TimerHelper : public QObject @@ -102,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() @@ -123,6 +127,9 @@ void tst_qmltimer::notRepeatingStart() QCOMPARE(helper.count, 1); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 1); + QVERIFY(timer->isRunning() == false); + + delete timer; } void tst_qmltimer::repeat() @@ -142,11 +149,16 @@ 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; } void tst_qmltimer::triggeredOnStart() @@ -166,6 +178,9 @@ void tst_qmltimer::triggeredOnStart() QCOMPARE(helper.count, 2); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 2); + QVERIFY(timer->isRunning() == false); + + delete timer; } void tst_qmltimer::triggeredOnStartRepeat() @@ -185,6 +200,9 @@ void tst_qmltimer::triggeredOnStartRepeat() int oldCount = helper.count; QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count > oldCount); + QVERIFY(timer->isRunning()); + + delete timer; } void tst_qmltimer::noTriggerIfNotRunning() @@ -201,6 +219,57 @@ 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<QmlTimer*>(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); + QVERIFY(timer->isRunning()); + + 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<QmlTimer*>(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); + QVERIFY(timer->isRunning()); + + delete timer; } QTEST_MAIN(tst_qmltimer) 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; |