summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-04-09 05:59:31 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-04-09 05:59:31 (GMT)
commit75581e3330916f756462ff6924abf2c62c0d228e (patch)
tree5df732f65ba220fafac5b772229e3101d783f46d
parent4a40a67827c8f259876e906a5a9afd2159ca9028 (diff)
parent79832f2156745ee2c6608ce7425fb2350b56f18d (diff)
downloadQt-75581e3330916f756462ff6924abf2c62c0d228e.zip
Qt-75581e3330916f756462ff6924abf2c62c0d228e.tar.gz
Qt-75581e3330916f756462ff6924abf2c62c0d228e.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
-rw-r--r--doc/src/declarative/dynamicobjects.qdoc16
-rw-r--r--doc/src/declarative/modules.qdoc2
-rw-r--r--doc/src/declarative/qdeclarativemodels.qdoc24
-rw-r--r--examples/declarative/tutorials/samegame/samegame1/Button.qml3
-rw-r--r--examples/declarative/tutorials/samegame/samegame2/Button.qml3
-rw-r--r--examples/declarative/tutorials/samegame/samegame2/samegame.js42
-rw-r--r--examples/declarative/tutorials/samegame/samegame3/Button.qml3
-rw-r--r--examples/declarative/tutorials/samegame/samegame3/samegame.js153
-rw-r--r--examples/declarative/tutorials/samegame/samegame4/content/Button.qml3
-rwxr-xr-xexamples/declarative/tutorials/samegame/samegame4/content/samegame.js194
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp13
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp3
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp3
14 files changed, 234 insertions, 229 deletions
diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc
index 63f697d..4cb5198 100644
--- a/doc/src/declarative/dynamicobjects.qdoc
+++ b/doc/src/declarative/dynamicobjects.qdoc
@@ -62,15 +62,11 @@ item which you want to manage dynamic instances of, and creating an item from
a string of QML is intended for when the QML itself is generated at runtime.
If you have a component specified in a QML file, you can dynamically load it with
-the createComponent function on the \l{QML Global Object}.
+the \l {createComponent(url file)}{createComponent()} function on the \l{QML Global Object}.
This function takes the URL of the QML file as its only argument and returns
a component object which can be used to create and load that QML file.
-You can also create a component by placing your QML inside a Component element.
-Referencing that component element by id will be the same as referencing the variable
-which you save the result of createComponent into.
-
-Once you have a component you can use its createObject method to create an instance of
+Once you have a component you can use its \c createObject() method to create an instance of
the component. Example QML script is below. Remember that QML files that might be loaded
over the network cannot be expected to be ready immediately.
\code
@@ -116,10 +112,10 @@ the component. Example QML script is below. Remember that QML files that might b
After creating the item, remember to set its parent to an item within the scene.
Otherwise your dynamically created item will not appear in the scene. When using files with relative paths, the path should
-be relative to the file where createComponent is executed.
+be relative to the file where \c createComponent() is executed.
If the QML does not exist until runtime, you can create a QML item from
-a string of QML using the createQmlObject function, as in the following example:
+a string of QML using the \l{createQmlObject(string qml, object parent, string filepath)}{createQmlObject()} function, as in the following example:
\code
newObject = createQmlObject('import Qt 4.7; Rectangle { color: "red"; width: 20; height: 20 }',
@@ -139,9 +135,9 @@ will not have an id in QML.
A restriction which you need to manage with dynamically created items,
is that the creation context must outlive the
-created item. The creation context is the QDeclarativeContext in which createComponent
+created item. The creation context is the QDeclarativeContext in which \c createComponent()
was called, or the context in which the Component element, or the item used as the
-second argument to createQmlObject, was specified. If the creation
+second argument to \c createQmlObject(), was specified. If the creation
context is destroyed before the dynamic item is, then bindings in the dynamic item will
fail to work.
diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc
index 0e332d4..0c69930 100644
--- a/doc/src/declarative/modules.qdoc
+++ b/doc/src/declarative/modules.qdoc
@@ -158,7 +158,7 @@ To import a module into a namespace:
import Qt 4.7 as TheQtLibrary
\endcode
-Types from Qt 4.6 may then be used, but only by qualifying them with the namespace:
+Types from the Qt 4.7 module may then be used, but only by qualifying them with the namespace:
\code
TheQtLibrary.Rectangle { ... }
diff --git a/doc/src/declarative/qdeclarativemodels.qdoc b/doc/src/declarative/qdeclarativemodels.qdoc
index e80824d..d8b2a5d 100644
--- a/doc/src/declarative/qdeclarativemodels.qdoc
+++ b/doc/src/declarative/qdeclarativemodels.qdoc
@@ -54,7 +54,7 @@ delegate may bind to. The roles are exposed as properties of the
\e model context property, though this property is set as a default property
of the delegate so, unless there is a naming clash with a
property in the delegate, the roles are usually accessed unqualified. The
-example below would have a clash between he \e color role of the model and
+example below would have a clash between the \e color role of the model and
the \e color property of the Rectangle. The clash is avoided by referencing
the \e color property of the model by its full name: \e model.color.
@@ -309,13 +309,21 @@ There are no data roles.
The following example creates a ListView with five elements:
\code
-Component {
- id: itemDelegate
- Text { text: "I am item number: " + index }
-}
-ListView {
- model: 5
- delegate: itemDelegate
+Item {
+ width: 200
+ height: 250
+
+ Component {
+ id: itemDelegate
+ Text { text: "I am item number: " + index }
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: 5
+ delegate: itemDelegate
+ }
+
}
\endcode
diff --git a/examples/declarative/tutorials/samegame/samegame1/Button.qml b/examples/declarative/tutorials/samegame/samegame1/Button.qml
index 6798c32..8ad7c0f 100644
--- a/examples/declarative/tutorials/samegame/samegame1/Button.qml
+++ b/examples/declarative/tutorials/samegame/samegame1/Button.qml
@@ -14,7 +14,8 @@ Rectangle {
gradient: Gradient {
GradientStop {
position: 0.0
- color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light } }
+ color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light }
+ }
GradientStop { position: 1.0; color: activePalette.button }
}
diff --git a/examples/declarative/tutorials/samegame/samegame2/Button.qml b/examples/declarative/tutorials/samegame/samegame2/Button.qml
index 04d1d1f..cf4c61b 100644
--- a/examples/declarative/tutorials/samegame/samegame2/Button.qml
+++ b/examples/declarative/tutorials/samegame/samegame2/Button.qml
@@ -13,7 +13,8 @@ Rectangle {
gradient: Gradient {
GradientStop {
position: 0.0
- color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light } }
+ color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light }
+ }
GradientStop { position: 1.0; color: activePalette.button }
}
diff --git a/examples/declarative/tutorials/samegame/samegame2/samegame.js b/examples/declarative/tutorials/samegame/samegame2/samegame.js
index 3f12561..9809c1d 100644
--- a/examples/declarative/tutorials/samegame/samegame2/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame2/samegame.js
@@ -2,59 +2,58 @@
var blockSize = 40;
var maxColumn = 10;
var maxRow = 15;
-var maxIndex = maxColumn*maxRow;
+var maxIndex = maxColumn * maxRow;
var board = new Array(maxIndex);
var component;
//Index function used instead of a 2D array
-function index(column,row) {
+function index(column, row) {
return column + (row * maxColumn);
}
-function startNewGame()
-{
+function startNewGame() {
//Delete blocks from previous game
- for(var i = 0; i<maxIndex; i++){
- if(board[i] != null)
+ for (var i = 0; i < maxIndex; i++) {
+ if (board[i] != null)
board[i].destroy();
}
//Calculate board size
- maxColumn = Math.floor(background.width/blockSize);
- maxRow = Math.floor(background.height/blockSize);
- maxIndex = maxRow*maxColumn;
+ maxColumn = Math.floor(background.width / blockSize);
+ maxRow = Math.floor(background.height / blockSize);
+ maxIndex = maxRow * maxColumn;
//Initialize Board
board = new Array(maxIndex);
- for(var column=0; column<maxColumn; column++){
- for(var row=0; row<maxRow; row++){
- board[index(column,row)] = null;
- createBlock(column,row);
+ for (var column = 0; column < maxColumn; column++) {
+ for (var row = 0; row < maxRow; row++) {
+ board[index(column, row)] = null;
+ createBlock(column, row);
}
}
}
-function createBlock(column,row){
- if(component==null)
+function createBlock(column, row) {
+ if (component == null)
component = createComponent("Block.qml");
// Note that if Block.qml was not a local file, component.isReady would be
// false and we should wait for the component's statusChanged() signal to
// know when the file is downloaded and fully loaded before calling createObject().
- if(component.isReady){
+ if (component.isReady) {
var dynamicObject = component.createObject();
- if(dynamicObject == null){
+ if (dynamicObject == null) {
print("error creating block");
print(component.errorsString());
return false;
}
dynamicObject.parent = background;
- dynamicObject.x = column*blockSize;
- dynamicObject.y = row*blockSize;
+ dynamicObject.x = column * blockSize;
+ dynamicObject.y = row * blockSize;
dynamicObject.width = blockSize;
dynamicObject.height = blockSize;
- board[index(column,row)] = dynamicObject;
- }else{
+ board[index(column, row)] = dynamicObject;
+ } else {
print("error loading block component");
print(component.errorsString());
return false;
@@ -62,3 +61,4 @@ function createBlock(column,row){
return true;
}
//![0]
+
diff --git a/examples/declarative/tutorials/samegame/samegame3/Button.qml b/examples/declarative/tutorials/samegame/samegame3/Button.qml
index 04d1d1f..cf4c61b 100644
--- a/examples/declarative/tutorials/samegame/samegame3/Button.qml
+++ b/examples/declarative/tutorials/samegame/samegame3/Button.qml
@@ -13,7 +13,8 @@ Rectangle {
gradient: Gradient {
GradientStop {
position: 0.0
- color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light } }
+ color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light }
+ }
GradientStop { position: 1.0; color: activePalette.button }
}
diff --git a/examples/declarative/tutorials/samegame/samegame3/samegame.js b/examples/declarative/tutorials/samegame/samegame3/samegame.js
index 9620e25..c12def7 100644
--- a/examples/declarative/tutorials/samegame/samegame3/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame3/samegame.js
@@ -1,21 +1,20 @@
/* This script file handles the game logic */
var maxColumn = 10;
var maxRow = 15;
-var maxIndex = maxColumn*maxRow;
+var maxIndex = maxColumn * maxRow;
var board = new Array(maxIndex);
var component;
//Index function used instead of a 2D array
-function index(column,row) {
+function index(column, row) {
return column + (row * maxColumn);
}
-function startNewGame()
-{
+function startNewGame() {
//Calculate board size
- maxColumn = Math.floor(gameCanvas.width/gameCanvas.blockSize);
- maxRow = Math.floor(gameCanvas.height/gameCanvas.blockSize);
- maxIndex = maxRow*maxColumn;
+ maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize);
+ maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize);
+ maxIndex = maxRow * maxColumn;
//Close dialogs
dialog.forceClose();
@@ -23,36 +22,36 @@ function startNewGame()
//Initialize Board
board = new Array(maxIndex);
gameCanvas.score = 0;
- for(var column=0; column<maxColumn; column++){
- for(var row=0; row<maxRow; row++){
- board[index(column,row)] = null;
- createBlock(column,row);
+ for (var column = 0; column < maxColumn; column++) {
+ for (var row = 0; row < maxRow; row++) {
+ board[index(column, row)] = null;
+ createBlock(column, row);
}
}
}
-function createBlock(column,row){
- if(component==null)
+function createBlock(column, row) {
+ if (component == null)
component = createComponent("Block.qml");
// Note that if Block.qml was not a local file, component.isReady would be
// false and we should wait for the component's statusChanged() signal to
// know when the file is downloaded and fully loaded before calling createObject().
- if(component.isReady){
+ if (component.isReady) {
var dynamicObject = component.createObject();
- if(dynamicObject == null){
+ if (dynamicObject == null) {
print("error creating block");
print(component.errorsString());
return false;
}
dynamicObject.type = Math.floor(Math.random() * 3);
dynamicObject.parent = gameCanvas;
- dynamicObject.x = column*gameCanvas.blockSize;
- dynamicObject.y = row*gameCanvas.blockSize;
+ dynamicObject.x = column * gameCanvas.blockSize;
+ dynamicObject.y = row * gameCanvas.blockSize;
dynamicObject.width = gameCanvas.blockSize;
dynamicObject.height = gameCanvas.blockSize;
- board[index(column,row)] = dynamicObject;
- }else{
+ board[index(column, row)] = dynamicObject;
+ } else {
print("error loading block component");
print(component.errorsString());
return false;
@@ -60,21 +59,21 @@ function createBlock(column,row){
return true;
}
-var fillFound;//Set after a floodFill call to the number of blocks found
-var floodBoard;//Set to 1 if the floodFill reaches off that node
-
+var fillFound;
+//Set after a floodFill call to the number of blocks found
+var floodBoard;
+//Set to 1 if the floodFill reaches off that node
//![1]
-function handleClick(xPos,yPos)
-{
- var column = Math.floor(xPos/gameCanvas.blockSize);
- var row = Math.floor(yPos/gameCanvas.blockSize);
- if(column >= maxColumn || column < 0 || row >= maxRow || row < 0)
+function handleClick(xPos, yPos) {
+ var column = Math.floor(xPos / gameCanvas.blockSize);
+ var row = Math.floor(yPos / gameCanvas.blockSize);
+ if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
return;
- if(board[index(column, row)] == null)
+ if (board[index(column, row)] == null)
return;
//If it's a valid block, remove it and all connected (does nothing if it's not connected)
- floodFill(column,row, -1);
- if(fillFound <= 0)
+ floodFill(column, row, -1);
+ if (fillFound <= 0)
return;
gameCanvas.score += (fillFound - 1) * (fillFound - 1);
shuffleDown();
@@ -82,67 +81,65 @@ function handleClick(xPos,yPos)
}
//![1]
-function floodFill(column,row,type)
-{
- if(board[index(column, row)] == null)
+function floodFill(column, row, type) {
+ if (board[index(column, row)] == null)
return;
var first = false;
- if(type == -1){
+ if (type == -1) {
first = true;
- type = board[index(column,row)].type;
-
+ type = board[index(column, row)].type;
+
//Flood fill initialization
fillFound = 0;
floodBoard = new Array(maxIndex);
}
- if(column >= maxColumn || column < 0 || row >= maxRow || row < 0)
+ if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
return;
- if(floodBoard[index(column, row)] == 1 || (!first && type != board[index(column,row)].type))
+ if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type))
return;
floodBoard[index(column, row)] = 1;
- floodFill(column+1,row,type);
- floodFill(column-1,row,type);
- floodFill(column,row+1,type);
- floodFill(column,row-1,type);
- if(first==true && fillFound == 0)
- return;//Can't remove single blocks
- board[index(column,row)].opacity = 0;
- board[index(column,row)] = null;
+ floodFill(column + 1, row, type);
+ floodFill(column - 1, row, type);
+ floodFill(column, row + 1, type);
+ floodFill(column, row - 1, type);
+ if (first == true && fillFound == 0)
+ return; //Can't remove single blocks
+ board[index(column, row)].opacity = 0;
+ board[index(column, row)] = null;
fillFound += 1;
}
-function shuffleDown()
-{
+function shuffleDown() {
//Fall down
- for(var column=0; column<maxColumn; column++){
+ for (var column = 0; column < maxColumn; column++) {
var fallDist = 0;
- for(var row=maxRow-1; row>=0; row--){
- if(board[index(column,row)] == null){
+ for (var row = maxRow - 1; row >= 0; row--) {
+ if (board[index(column, row)] == null) {
fallDist += 1;
- }else{
- if(fallDist > 0){
- var obj = board[index(column,row)];
+ } else {
+ if (fallDist > 0) {
+ var obj = board[index(column, row)];
obj.y += fallDist * gameCanvas.blockSize;
- board[index(column,row+fallDist)] = obj;
- board[index(column,row)] = null;
+ board[index(column, row + fallDist)] = obj;
+ board[index(column, row)] = null;
}
}
}
}
//Fall to the left
var fallDist = 0;
- for(var column=0; column<maxColumn; column++){
- if(board[index(column, maxRow - 1)] == null){
+ for (var column = 0; column < maxColumn; column++) {
+ if (board[index(column, maxRow - 1)] == null) {
fallDist += 1;
- }else{
- if(fallDist > 0){
- for(var row=0; row<maxRow; row++){
- var obj = board[index(column,row)];
- if(obj == null)
+ } else {
+ if (fallDist > 0) {
+ for (var row = 0; row < maxRow; row++) {
+ var obj = board[index(column, row)];
+ if (obj == null)
continue;
obj.x -= fallDist * gameCanvas.blockSize;
- board[index(column-fallDist,row)] = obj;
- board[index(column,row)] = null;
+ board[index(column - fallDist, row)] = obj;
+ board[index(column, row)] = null;
}
}
}
@@ -150,32 +147,30 @@ function shuffleDown()
}
//![2]
-function victoryCheck()
-{
+function victoryCheck() {
//Award bonus points if no blocks left
var deservesBonus = true;
- for(var column=maxColumn-1; column>=0; column--)
- if(board[index(column, maxRow - 1)] != null)
- deservesBonus = false;
- if(deservesBonus)
+ for (var column = maxColumn - 1; column >= 0; column--)
+ if (board[index(column, maxRow - 1)] != null)
+ deservesBonus = false;
+ if (deservesBonus)
gameCanvas.score += 500;
//Check whether game has finished
- if(deservesBonus || !(floodMoveCheck(0,maxRow-1, -1)))
+ if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1)))
dialog.show("Game Over. Your score is " + gameCanvas.score);
}
//![2]
//only floods up and right, to see if it can find adjacent same-typed blocks
-function floodMoveCheck(column, row, type)
-{
- if(column >= maxColumn || column < 0 || row >= maxRow || row < 0)
+function floodMoveCheck(column, row, type) {
+ if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
return false;
- if(board[index(column, row)] == null)
+ if (board[index(column, row)] == null)
return false;
var myType = board[index(column, row)].type;
- if(type == myType)
+ if (type == myType)
return true;
- return floodMoveCheck(column + 1, row, myType) ||
- floodMoveCheck(column, row - 1, board[index(column,row)].type);
+ return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type);
}
+
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/Button.qml b/examples/declarative/tutorials/samegame/samegame4/content/Button.qml
index 04d1d1f..cf4c61b 100644
--- a/examples/declarative/tutorials/samegame/samegame4/content/Button.qml
+++ b/examples/declarative/tutorials/samegame/samegame4/content/Button.qml
@@ -13,7 +13,8 @@ Rectangle {
gradient: Gradient {
GradientStop {
position: 0.0
- color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light } }
+ color: if (mouseArea.pressed) { activePalette.dark } else { activePalette.light }
+ }
GradientStop { position: 1.0; color: activePalette.button }
}
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
index 0b1c6d6..47985de 100755
--- a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
@@ -1,29 +1,28 @@
/* This script file handles the game logic */
var maxColumn = 10;
var maxRow = 15;
-var maxIndex = maxColumn*maxRow;
+var maxIndex = maxColumn * maxRow;
var board = new Array(maxIndex);
var component;
var scoresURL = "";
var gameDuration;
//Index function used instead of a 2D array
-function index(column,row) {
+function index(column, row) {
return column + (row * maxColumn);
}
-function startNewGame()
-{
- for(var i = 0; i<maxIndex; i++){
+function startNewGame() {
+ for (var i = 0; i < maxIndex; i++) {
//Delete blocks from previous game
- if(board[i] != null)
+ if (board[i] != null)
board[i].destroy();
}
//Calculate board size
- maxColumn = Math.floor(gameCanvas.width/gameCanvas.blockSize);
- maxRow = Math.floor(gameCanvas.height/gameCanvas.blockSize);
- maxIndex = maxRow*maxColumn;
+ maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize);
+ maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize);
+ maxIndex = maxRow * maxColumn;
//Close dialogs
nameInputDialog.forceClose();
@@ -32,40 +31,40 @@ function startNewGame()
//Initialize Board
board = new Array(maxIndex);
gameCanvas.score = 0;
- for(var column=0; column<maxColumn; column++){
- for(var row=0; row<maxRow; row++){
- board[index(column,row)] = null;
- createBlock(column,row);
+ for (var column = 0; column < maxColumn; column++) {
+ for (var row = 0; row < maxRow; row++) {
+ board[index(column, row)] = null;
+ createBlock(column, row);
}
}
gameDuration = new Date();
}
-function createBlock(column,row){
- if(component==null)
+function createBlock(column, row) {
+ if (component == null)
component = createComponent("content/BoomBlock.qml");
// Note that if Block.qml was not a local file, component.isReady would be
// false and we should wait for the component's statusChanged() signal to
// know when the file is downloaded and fully loaded before calling createObject().
- if(component.isReady){
+ if (component.isReady) {
var dynamicObject = component.createObject();
- if(dynamicObject == null){
+ if (dynamicObject == null) {
print("error creating block");
print(component.errorsString());
return false;
}
dynamicObject.type = Math.floor(Math.random() * 3);
dynamicObject.parent = gameCanvas;
- dynamicObject.x = column*gameCanvas.blockSize;
- dynamicObject.targetX = column*gameCanvas.blockSize;
- dynamicObject.targetY = row*gameCanvas.blockSize;
+ dynamicObject.x = column * gameCanvas.blockSize;
+ dynamicObject.targetX = column * gameCanvas.blockSize;
+ dynamicObject.targetY = row * gameCanvas.blockSize;
dynamicObject.width = gameCanvas.blockSize;
dynamicObject.height = gameCanvas.blockSize;
dynamicObject.spawned = true;
- board[index(column,row)] = dynamicObject;
- }else{
+ board[index(column, row)] = dynamicObject;
+ } else {
print("error loading block component");
print(component.errorsString());
return false;
@@ -73,158 +72,148 @@ function createBlock(column,row){
return true;
}
-var fillFound;//Set after a floodFill call to the number of blocks found
-var floodBoard;//Set to 1 if the floodFill reaches off that node
-
-function handleClick(xPos,yPos)
-{
- var column = Math.floor(xPos/gameCanvas.blockSize);
- var row = Math.floor(yPos/gameCanvas.blockSize);
- if(column >= maxColumn || column < 0 || row >= maxRow || row < 0)
+var fillFound;
+//Set after a floodFill call to the number of blocks found
+var floodBoard;
+//Set to 1 if the floodFill reaches off that node
+function handleClick(xPos, yPos) {
+ var column = Math.floor(xPos / gameCanvas.blockSize);
+ var row = Math.floor(yPos / gameCanvas.blockSize);
+ if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
return;
- if(board[index(column, row)] == null)
+ if (board[index(column, row)] == null)
return;
//If it's a valid block, remove it and all connected (does nothing if it's not connected)
- floodFill(column,row, -1);
- if(fillFound <= 0)
+ floodFill(column, row, -1);
+ if (fillFound <= 0)
return;
gameCanvas.score += (fillFound - 1) * (fillFound - 1);
shuffleDown();
victoryCheck();
}
-function floodFill(column,row,type)
-{
- if(board[index(column, row)] == null)
+function floodFill(column, row, type) {
+ if (board[index(column, row)] == null)
return;
var first = false;
- if(type == -1){
+ if (type == -1) {
first = true;
- type = board[index(column,row)].type;
+ type = board[index(column, row)].type;
//Flood fill initialization
fillFound = 0;
floodBoard = new Array(maxIndex);
}
- if(column >= maxColumn || column < 0 || row >= maxRow || row < 0)
+ if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
return;
- if(floodBoard[index(column, row)] == 1 || (!first && type != board[index(column,row)].type))
+ if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type))
return;
floodBoard[index(column, row)] = 1;
- floodFill(column+1,row,type);
- floodFill(column-1,row,type);
- floodFill(column,row+1,type);
- floodFill(column,row-1,type);
- if(first==true && fillFound == 0)
- return;//Can't remove single blocks
- board[index(column,row)].dying = true;
- board[index(column,row)] = null;
+ floodFill(column + 1, row, type);
+ floodFill(column - 1, row, type);
+ floodFill(column, row + 1, type);
+ floodFill(column, row - 1, type);
+ if (first == true && fillFound == 0)
+ return; //Can't remove single blocks
+ board[index(column, row)].dying = true;
+ board[index(column, row)] = null;
fillFound += 1;
}
-function shuffleDown()
-{
+function shuffleDown() {
//Fall down
- for(var column=0; column<maxColumn; column++){
+ for (var column = 0; column < maxColumn; column++) {
var fallDist = 0;
- for(var row=maxRow-1; row>=0; row--){
- if(board[index(column,row)] == null){
+ for (var row = maxRow - 1; row >= 0; row--) {
+ if (board[index(column, row)] == null) {
fallDist += 1;
- }else{
- if(fallDist > 0){
- var obj = board[index(column,row)];
+ } else {
+ if (fallDist > 0) {
+ var obj = board[index(column, row)];
obj.targetY += fallDist * gameCanvas.blockSize;
- board[index(column,row+fallDist)] = obj;
- board[index(column,row)] = null;
+ board[index(column, row + fallDist)] = obj;
+ board[index(column, row)] = null;
}
}
}
}
//Fall to the left
fallDist = 0;
- for(column=0; column<maxColumn; column++){
- if(board[index(column, maxRow - 1)] == null){
+ for (column = 0; column < maxColumn; column++) {
+ if (board[index(column, maxRow - 1)] == null) {
fallDist += 1;
- }else{
- if(fallDist > 0){
- for(row=0; row<maxRow; row++){
- obj = board[index(column,row)];
- if(obj == null)
+ } else {
+ if (fallDist > 0) {
+ for (row = 0; row < maxRow; row++) {
+ obj = board[index(column, row)];
+ if (obj == null)
continue;
obj.targetX -= fallDist * gameCanvas.blockSize;
- board[index(column-fallDist,row)] = obj;
- board[index(column,row)] = null;
+ board[index(column - fallDist, row)] = obj;
+ board[index(column, row)] = null;
}
}
}
}
}
-function victoryCheck()
-{
+function victoryCheck() {
//Award bonus points if no blocks left
var deservesBonus = true;
- for(var column=maxColumn-1; column>=0; column--)
- if(board[index(column, maxRow - 1)] != null)
- deservesBonus = false;
- if(deservesBonus)
+ for (var column = maxColumn - 1; column >= 0; column--)
+ if (board[index(column, maxRow - 1)] != null)
+ deservesBonus = false;
+ if (deservesBonus)
gameCanvas.score += 500;
//Check whether game has finished
- if(deservesBonus || !(floodMoveCheck(0,maxRow-1, -1))){
+ if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) {
gameDuration = new Date() - gameDuration;
nameInputDialog.show("You won! Please enter your name: ");
}
}
//only floods up and right, to see if it can find adjacent same-typed blocks
-function floodMoveCheck(column, row, type)
-{
- if(column >= maxColumn || column < 0 || row >= maxRow || row < 0)
+function floodMoveCheck(column, row, type) {
+ if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
return false;
- if(board[index(column, row)] == null)
+ if (board[index(column, row)] == null)
return false;
var myType = board[index(column, row)].type;
- if(type == myType)
+ if (type == myType)
return true;
- return floodMoveCheck(column + 1, row, myType) ||
- floodMoveCheck(column, row - 1, board[index(column,row)].type);
+ return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type);
}
//![2]
function saveHighScore(name) {
- if(scoresURL!="")
+ if (scoresURL != "")
sendHighScore(name);
- //OfflineStorage
- var db = openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores",100);
+
+ var db = openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores", 100);
var dataStr = "INSERT INTO Scores VALUES(?, ?, ?, ?)";
- var data = [name, gameCanvas.score, maxColumn+"x"+maxRow ,Math.floor(gameDuration/1000)];
- db.transaction(
- function(tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)');
- tx.executeSql(dataStr, data);
-
- var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "12x17" ORDER BY score desc LIMIT 10');
- var r = "\nHIGH SCORES for a standard sized grid\n\n"
- for(var i = 0; i < rs.rows.length; i++){
- r += (i+1)+". " + rs.rows.item(i).name +' got '
- + rs.rows.item(i).score + ' points in '
- + rs.rows.item(i).time + ' seconds.\n';
- }
- dialog.show(r);
+ var data = [name, gameCanvas.score, maxColumn + "x" + maxRow, Math.floor(gameDuration / 1000)];
+ db.transaction(function(tx) {
+ tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)');
+ tx.executeSql(dataStr, data);
+
+ var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "12x17" ORDER BY score desc LIMIT 10');
+ var r = "\nHIGH SCORES for a standard sized grid\n\n"
+ for (var i = 0; i < rs.rows.length; i++) {
+ r += (i + 1) + ". " + rs.rows.item(i).name + ' got ' + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n';
}
- );
+ dialog.show(r);
+ });
}
//![2]
//![1]
function sendHighScore(name) {
var postman = new XMLHttpRequest()
- var postData = "name="+name+"&score="+gameCanvas.score
- +"&gridSize="+maxColumn+"x"+maxRow +"&time="+Math.floor(gameDuration/1000);
+ var postData = "name=" + name + "&score=" + gameCanvas.score + "&gridSize=" + maxColumn + "x" + maxRow + "&time=" + Math.floor(gameDuration / 1000);
postman.open("POST", scoresURL, true);
postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- postman.onreadystatechange = function() {
+ postman.onreadystatechange = function() {
if (postman.readyState == postman.DONE) {
dialog.show("Your score has been uploaded.");
}
@@ -232,3 +221,4 @@ function sendHighScore(name) {
postman.send(postData);
}
//![1]
+
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index caf680e..9e137b5 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -107,6 +107,10 @@ class QDeclarativeWorkerScriptEnginePrivate : public QObject
{
Q_OBJECT
public:
+ enum WorkerEventTypes {
+ WorkerDestroyEvent = QEvent::User + 100
+ };
+
QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *eng);
struct ScriptEngine : public QDeclarativeScriptEngine
@@ -159,6 +163,9 @@ public:
static QScriptValue onMessage(QScriptContext *ctxt, QScriptEngine *engine);
static QScriptValue sendMessage(QScriptContext *ctxt, QScriptEngine *engine);
+signals:
+ void stopThread();
+
protected:
virtual bool event(QEvent *);
@@ -246,6 +253,9 @@ bool QDeclarativeWorkerScriptEnginePrivate::event(QEvent *event)
WorkerLoadEvent *workerEvent = static_cast<WorkerLoadEvent *>(event);
processLoad(workerEvent->workerId(), workerEvent->url());
return true;
+ } else if (event->type() == (QEvent::Type)WorkerDestroyEvent) {
+ emit stopThread();
+ return true;
} else {
return QObject::event(event);
}
@@ -429,6 +439,7 @@ QDeclarativeWorkerScriptEngine::QDeclarativeWorkerScriptEngine(QDeclarativeEngin
: QThread(parent), d(new QDeclarativeWorkerScriptEnginePrivate(parent))
{
d->m_lock.lock();
+ connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection);
start(QThread::LowPriority);
d->m_wait.wait(&d->m_lock);
d->moveToThread(this);
@@ -440,8 +451,10 @@ QDeclarativeWorkerScriptEngine::~QDeclarativeWorkerScriptEngine()
d->m_lock.lock();
qDeleteAll(d->workers);
d->workers.clear();
+ QCoreApplication::postEvent(d, new QEvent((QEvent::Type)QDeclarativeWorkerScriptEnginePrivate::WorkerDestroyEvent));
d->m_lock.unlock();
+ wait();
d->deleteLater();
}
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 28bd852..37bbb14 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -264,6 +264,9 @@ QDeclarativeListModel::QDeclarativeListModel(bool workerCopy, QObject *parent)
QDeclarativeListModel::~QDeclarativeListModel()
{
+ if (m_agent)
+ m_agent->release();
+
delete m_nested;
delete m_flat;
}
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
index b6a643b..53d30c2 100644
--- a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
@@ -66,7 +66,6 @@ QT_MODULE(Declarative)
class QDeclarativeListModel;
-// Currently this will leak as no-one releases it in the worker thread
class QDeclarativeListModelWorkerAgent : public QObject
{
Q_OBJECT
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index 8214723..5962a42 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -337,7 +337,6 @@ void tst_QDeclarativeListModel::dynamic_worker()
}
delete item;
- QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running");
qApp->processEvents();
}
@@ -367,7 +366,6 @@ void tst_QDeclarativeListModel::convertNestedToFlat_fail()
QCOMPARE(model.count(), 2);
delete item;
- QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running");
qApp->processEvents();
}
@@ -427,7 +425,6 @@ void tst_QDeclarativeListModel::convertNestedToFlat_ok()
QCOMPARE(model.count(), count+1);
delete item;
- QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running");
qApp->processEvents();
}