summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2010-04-09 03:37:39 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2010-04-09 03:37:39 (GMT)
commitd3baa9ff677c7cee0d79e791d1ffd11e301eb466 (patch)
tree1c0e68dccf8482b29cc884628a9e6b84f317b77c
parente0dcdbd2984299665b9b784b201289219b9978d3 (diff)
parent25f17fb8e566fca0838545941d3e0281698ec355 (diff)
downloadQt-d3baa9ff677c7cee0d79e791d1ffd11e301eb466.zip
Qt-d3baa9ff677c7cee0d79e791d1ffd11e301eb466.tar.gz
Qt-d3baa9ff677c7cee0d79e791d1ffd11e301eb466.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
-rw-r--r--doc/src/declarative/advtutorial.qdoc26
-rw-r--r--doc/src/declarative/javascriptblocks.qdoc2
-rw-r--r--doc/src/declarative/network.qdoc1
-rw-r--r--doc/src/declarative/qdeclarativedocument.qdoc2
-rw-r--r--examples/declarative/layouts/layouts.qml35
-rw-r--r--examples/declarative/tic-tac-toe/content/pics/board.pngbin11208 -> 1423 bytes
-rw-r--r--examples/declarative/tutorials/samegame/samegame2/samegame.js33
-rw-r--r--examples/declarative/tutorials/samegame/samegame2/samegame.qml2
-rw-r--r--examples/declarative/tutorials/samegame/samegame3/Dialog.qml2
-rw-r--r--examples/declarative/tutorials/samegame/samegame3/samegame.js54
-rw-r--r--examples/declarative/tutorials/samegame/samegame3/samegame.qml8
-rw-r--r--examples/declarative/tutorials/samegame/samegame4/content/Dialog.qml2
-rwxr-xr-xexamples/declarative/tutorials/samegame/samegame4/content/samegame.js117
-rw-r--r--examples/declarative/tutorials/samegame/samegame4/samegame.qml8
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri2
-rw-r--r--src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp269
-rw-r--r--src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer_p.h89
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp99
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h6
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h11
-rw-r--r--src/imports/widgets/graphicslayouts_p.h3
-rw-r--r--src/imports/widgets/graphicswidgets.cpp40
-rw-r--r--src/imports/widgets/graphicswidgets_p.h68
-rw-r--r--src/imports/widgets/widgets.cpp70
-rw-r--r--src/imports/widgets/widgets.pro1
-rw-r--r--tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp24
27 files changed, 262 insertions, 714 deletions
diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc
index 598f47b..4d3bfa8 100644
--- a/doc/src/declarative/advtutorial.qdoc
+++ b/doc/src/declarative/advtutorial.qdoc
@@ -160,18 +160,20 @@ we cannot use \l Repeater to define the blocks. Instead, we will
create the blocks in JavaScript.
Here is the JavaScript code for generating the blocks, contained in a new
-file, \c samegame.js:
+file, \c samegame.js. The code is explained below.
\snippet declarative/tutorials/samegame/samegame2/samegame.js 0
-The main function here is \c initBoard(). It creates an array to store all the game
-blocks, then calls \c createBlock() to create enough blocks to fill the game canvas.
+The \c startNewGame() function deletes the blocks created in the previous game and
+calculates the number of rows and columns of blocks required to fill the game window for the new game.
+Then, it creates an array to store all the game
+blocks, and calls \c createBlock() to create enough blocks to fill the game window.
-The \c createBlock() function creates a block using the \c Block.qml file
+The \c createBlock() function creates a block from the \c Block.qml file
and moves the new block to its position on the game canvas. This involves several steps:
\list
-\o \l {createComponent(url file)} is called to generate an element from \c Block.qml.
+\o \l {createComponent(url file)}{createComponent()} is called to generate an element from \c Block.qml.
If the component is ready, we can call \c createObject() to create an instance of the \c Block item.
(If a component is loaded remotely - over HTTP for example - then we would have to wait for the
component to finish loading before calling \c createObject()).
@@ -193,13 +195,13 @@ the JavaScript file as a \l{Modules#QML Modules}{module}:
\snippet declarative/tutorials/samegame/samegame2/samegame.qml 2
This allows us to refer to any functions within \c samegame.js using "SameGame"
-as a prefix: for example, \c SameGame.initBoard() or \c SameGame.createBlock().
-This means we can now connect the New Game button's \c onClicked handler to the \c initBoard()
+as a prefix: for example, \c SameGame.startNewGame() or \c SameGame.createBlock().
+This means we can now connect the New Game button's \c onClicked handler to the \c startNewGame()
function, like this:
\snippet declarative/tutorials/samegame/samegame2/samegame.qml 1
-So, when you click the New Game button, \c initBoard() is called and generates a field of blocks, like this:
+So, when you click the New Game button, \c startNewGame() is called and generates a field of blocks, like this:
\image declarative-adv-tutorial2.png
@@ -247,7 +249,7 @@ To make it easier for the JavaScript code to interface with the QML elements, we
The \c gameCanvas item is the exact size of the board, and has a \c score property and a \l MouseArea for input.
The blocks are now created as its children, and its dimensions are used to determine the board size so that
the application scales to the available screen size.
-Since its size is bound to a multiple of \c tileSize, \c tileSize needs to be moved out of \c samegame.js and into \c samegame.qml as a QML property.
+Since its size is bound to a multiple of \c blockSize, \c blockSize needs to be moved out of \c samegame.js and into \c samegame.qml as a QML property.
Note that it can still be accessed from the script.
The \l MouseArea simply calls \c{handleClick()} in \c samegame.js, which determines whether the player's click should cause any blocks to be removed, and updates \c gameCanvas.score with the current score if necessary. Here is the \c handleClick() function:
@@ -258,7 +260,7 @@ Note that if \c score was a global variable in the \c{samegame.js} file you woul
\section3 Updating the score
-When the player clicks a block and triggers \c handleClick(), \c handleClick() also calls victoryCheck() to update the score and to check whether the player has completed the game. Here is the \c victoryCheck() code:
+When the player clicks a block and triggers \c handleClick(), \c handleClick() also calls \c victoryCheck() to update the score and to check whether the player has completed the game. Here is the \c victoryCheck() code:
\snippet declarative/tutorials/samegame/samegame3/samegame.js 2
@@ -287,7 +289,7 @@ Here is a screenshot of what has been accomplished so far:
\image declarative-adv-tutorial3.png
-Here is the QML code as it is now in \c samegame.qml:
+This is what \c samegame.qml looks like now:
\snippet declarative/tutorials/samegame/samegame3/samegame.qml 0
@@ -439,7 +441,7 @@ By following this tutorial you've seen how you can write a fully functional appl
\o Build your application with \l {{QML Elements}}{QML elements}
\o Add application logic \l{Integrating JavaScript}{with JavaScript code}
\o Add animations with \l {Behavior}{Behaviors} and \l{QML States}{states}
-\o Store persistent application data through online and offline methods
+\o Store persistent application data using the \l{Offline Storage API} or \l XMLHttpRequest
\endlist
There is so much more to learn about QML that we haven't been able to cover in this tutorial. Check out all the
diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc
index c198295..3544bc9 100644
--- a/doc/src/declarative/javascriptblocks.qdoc
+++ b/doc/src/declarative/javascriptblocks.qdoc
@@ -163,7 +163,7 @@ component instance) "startup". While it is tempting to just include the startup
script as \e {global code} in an external script file, this can have severe limitations
as the QML environment may not have been fully established. For example, some objects
might not have been created or some \l {Property Binding}s may not have been run.
-\l {QML Script Restrictions} covers the exact limitations of global script code.
+\l {QML JavaScript Restrictions} covers the exact limitations of global script code.
The QML \l Component element provides an \e attached \c onCompleted property that
can be used to trigger the execution of script code at startup after the
diff --git a/doc/src/declarative/network.qdoc b/doc/src/declarative/network.qdoc
index f1d4db1..0a26c68 100644
--- a/doc/src/declarative/network.qdoc
+++ b/doc/src/declarative/network.qdoc
@@ -64,7 +64,6 @@ Image {
Network transparency is supported throughout QML, for example:
\list
-\o Scripts - the \c source property of \l Script is a URL
\o Fonts - the \c source property of FontLoader is a URL
\o WebViews - the \c url property of WebView (obviously!)
\endlist
diff --git a/doc/src/declarative/qdeclarativedocument.qdoc b/doc/src/declarative/qdeclarativedocument.qdoc
index bf95a29..cf3aae2 100644
--- a/doc/src/declarative/qdeclarativedocument.qdoc
+++ b/doc/src/declarative/qdeclarativedocument.qdoc
@@ -83,7 +83,7 @@ modifies the document prior to presentation to the QML runtime. \c import statem
do not "include" code in the document, but instead instruct the QML runtime on how to
resolve type references found in the document. Any type reference present in a QML
document - such as \c Rectangle and \c ListView - including those made within an
-\l {JavaScript Block} or \l {Property Binding}s, are \e resolved based exclusively on the
+\l {Inline JavaScript}{JavaScript block} or \l {Property Binding}s, are \e resolved based exclusively on the
import statements. QML does not import any modules by default, so at least one \c import
statement must be present or no elements will be available!
diff --git a/examples/declarative/layouts/layouts.qml b/examples/declarative/layouts/layouts.qml
index 231605e..1d34afd 100644
--- a/examples/declarative/layouts/layouts.qml
+++ b/examples/declarative/layouts/layouts.qml
@@ -4,27 +4,22 @@ Item {
id: resizable
width:400
height:400
+ QGraphicsWidget {
+ size.width:parent.width
+ size.height:parent.height
- GraphicsObjectContainer {
- anchors.fill:parent
-
- QGraphicsWidget {
- size.width:parent.width
- size.height:parent.height
-
- layout: QGraphicsLinearLayout {
- LayoutItem {
- minimumSize: "100x100"
- maximumSize: "300x300"
- preferredSize: "100x100"
- Rectangle { color: "yellow"; anchors.fill: parent }
- }
- LayoutItem {
- minimumSize: "100x100"
- maximumSize: "400x400"
- preferredSize: "200x200"
- Rectangle { color: "green"; anchors.fill: parent }
- }
+ layout: QGraphicsLinearLayout {
+ LayoutItem {
+ minimumSize: "100x100"
+ maximumSize: "300x300"
+ preferredSize: "100x100"
+ Rectangle { color: "yellow"; anchors.fill: parent }
+ }
+ LayoutItem {
+ minimumSize: "100x100"
+ maximumSize: "400x400"
+ preferredSize: "200x200"
+ Rectangle { color: "green"; anchors.fill: parent }
}
}
}
diff --git a/examples/declarative/tic-tac-toe/content/pics/board.png b/examples/declarative/tic-tac-toe/content/pics/board.png
index e7a7324..29118a9 100644
--- a/examples/declarative/tic-tac-toe/content/pics/board.png
+++ b/examples/declarative/tic-tac-toe/content/pics/board.png
Binary files differ
diff --git a/examples/declarative/tutorials/samegame/samegame2/samegame.js b/examples/declarative/tutorials/samegame/samegame2/samegame.js
index d7cbd8d..3f12561 100644
--- a/examples/declarative/tutorials/samegame/samegame2/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame2/samegame.js
@@ -1,11 +1,9 @@
//![0]
-//Note that X/Y referred to here are in game coordinates
-var maxColumn = 10;//Nums are for tileSize 40
+var blockSize = 40;
+var maxColumn = 10;
var maxRow = 15;
-var tileSize = 40;
var maxIndex = maxColumn*maxRow;
var board = new Array(maxIndex);
-var tileSrc = "Block.qml";
var component;
//Index function used instead of a 2D array
@@ -13,17 +11,17 @@ function index(column,row) {
return column + (row * maxColumn);
}
-function initBoard()
+function startNewGame()
{
- //Delete old blocks
+ //Delete blocks from previous game
for(var i = 0; i<maxIndex; i++){
if(board[i] != null)
board[i].destroy();
}
//Calculate board size
- maxColumn = Math.floor(background.width/tileSize);
- maxRow = Math.floor(background.height/tileSize);
+ maxColumn = Math.floor(background.width/blockSize);
+ maxRow = Math.floor(background.height/blockSize);
maxIndex = maxRow*maxColumn;
//Initialize Board
@@ -38,12 +36,11 @@ function initBoard()
function createBlock(column,row){
if(component==null)
- component = createComponent(tileSrc);
+ component = createComponent("Block.qml");
- // Note that we don't wait for the component to become ready. This will
- // only work if the block QML is a local file. Otherwise the component will
- // not be ready immediately. There is a statusChanged signal on the
- // component you could use if you want to wait to load remote files.
+ // 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){
var dynamicObject = component.createObject();
if(dynamicObject == null){
@@ -52,12 +49,12 @@ function createBlock(column,row){
return false;
}
dynamicObject.parent = background;
- dynamicObject.x = column*tileSize;
- dynamicObject.y = row*tileSize;
- dynamicObject.width = tileSize;
- dynamicObject.height = tileSize;
+ dynamicObject.x = column*blockSize;
+ dynamicObject.y = row*blockSize;
+ dynamicObject.width = blockSize;
+ dynamicObject.height = blockSize;
board[index(column,row)] = dynamicObject;
- }else{//isError or isLoading
+ }else{
print("error loading block component");
print(component.errorsString());
return false;
diff --git a/examples/declarative/tutorials/samegame/samegame2/samegame.qml b/examples/declarative/tutorials/samegame/samegame2/samegame.qml
index d98d383..e0706c2 100644
--- a/examples/declarative/tutorials/samegame/samegame2/samegame.qml
+++ b/examples/declarative/tutorials/samegame/samegame2/samegame.qml
@@ -27,7 +27,7 @@ Rectangle {
//![1]
Button {
- text: "New Game"; onClicked: SameGame.initBoard();
+ text: "New Game"; onClicked: SameGame.startNewGame();
anchors.left: parent.left; anchors.leftMargin: 3
anchors.verticalCenter: parent.verticalCenter
}
diff --git a/examples/declarative/tutorials/samegame/samegame3/Dialog.qml b/examples/declarative/tutorials/samegame/samegame3/Dialog.qml
index 6c358d6..a76b517 100644
--- a/examples/declarative/tutorials/samegame/samegame3/Dialog.qml
+++ b/examples/declarative/tutorials/samegame/samegame3/Dialog.qml
@@ -12,7 +12,7 @@ Rectangle {
page.opacity = 1;
}
signal closed();
- color: "white"; border.width: 1; width: dialogText.width + 20; height: 60;
+ color: "white"; border.width: 1; width: dialogText.width + 20; height: dialogText.height + 20;
opacity: 0
Behavior on opacity {
NumberAnimation { duration: 1000 }
diff --git a/examples/declarative/tutorials/samegame/samegame3/samegame.js b/examples/declarative/tutorials/samegame/samegame3/samegame.js
index 432e88f..9620e25 100644
--- a/examples/declarative/tutorials/samegame/samegame3/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame3/samegame.js
@@ -1,10 +1,8 @@
/* This script file handles the game logic */
-//Note that X/Y referred to here are in game coordinates
-var maxColumn = 10;//Nums are for tileSize 40
+var maxColumn = 10;
var maxRow = 15;
var maxIndex = maxColumn*maxRow;
var board = new Array(maxIndex);
-var tileSrc = "Block.qml";
var component;
//Index function used instead of a 2D array
@@ -12,11 +10,11 @@ function index(column,row) {
return column + (row * maxColumn);
}
-function initBoard()
+function startNewGame()
{
//Calculate board size
- maxColumn = Math.floor(gameCanvas.width/gameCanvas.tileSize);
- maxRow = Math.floor(gameCanvas.height/gameCanvas.tileSize);
+ maxColumn = Math.floor(gameCanvas.width/gameCanvas.blockSize);
+ maxRow = Math.floor(gameCanvas.height/gameCanvas.blockSize);
maxIndex = maxRow*maxColumn;
//Close dialogs
@@ -35,12 +33,11 @@ function initBoard()
function createBlock(column,row){
if(component==null)
- component = createComponent(tileSrc);
+ component = createComponent("Block.qml");
- // Note that we don't wait for the component to become ready. This will
- // only work if the block QML is a local file. Otherwise the component will
- // not be ready immediately. There is a statusChanged signal on the
- // component you could use if you want to wait to load remote files.
+ // 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){
var dynamicObject = component.createObject();
if(dynamicObject == null){
@@ -50,12 +47,12 @@ function createBlock(column,row){
}
dynamicObject.type = Math.floor(Math.random() * 3);
dynamicObject.parent = gameCanvas;
- dynamicObject.x = column*gameCanvas.tileSize;
- dynamicObject.y = row*gameCanvas.tileSize;
- dynamicObject.width = gameCanvas.tileSize;
- dynamicObject.height = gameCanvas.tileSize;
+ dynamicObject.x = column*gameCanvas.blockSize;
+ dynamicObject.y = row*gameCanvas.blockSize;
+ dynamicObject.width = gameCanvas.blockSize;
+ dynamicObject.height = gameCanvas.blockSize;
board[index(column,row)] = dynamicObject;
- }else{//isError or isLoading
+ }else{
print("error loading block component");
print(component.errorsString());
return false;
@@ -63,19 +60,19 @@ function createBlock(column,row){
return true;
}
-var fillFound;//Set after a floodFill call to the number of tiles found
+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
-//NOTE: Be careful with vars named x,y, as the calling object's x,y are still in scope
+
//![1]
-function handleClick(x,y)
+function handleClick(xPos,yPos)
{
- var column = Math.floor(x/gameCanvas.tileSize);
- var row = Math.floor(y/gameCanvas.tileSize);
+ 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)
return;
- //If it's a valid tile, remove it and all connected (does nothing if it's not connected)
+ //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)
return;
@@ -108,7 +105,7 @@ function floodFill(column,row,type)
floodFill(column,row+1,type);
floodFill(column,row-1,type);
if(first==true && fillFound == 0)
- return;//Can't remove single tiles
+ return;//Can't remove single blocks
board[index(column,row)].opacity = 0;
board[index(column,row)] = null;
fillFound += 1;
@@ -125,7 +122,7 @@ function shuffleDown()
}else{
if(fallDist > 0){
var obj = board[index(column,row)];
- obj.y += fallDist * gameCanvas.tileSize;
+ obj.y += fallDist * gameCanvas.blockSize;
board[index(column,row+fallDist)] = obj;
board[index(column,row)] = null;
}
@@ -143,7 +140,7 @@ function shuffleDown()
var obj = board[index(column,row)];
if(obj == null)
continue;
- obj.x -= fallDist * gameCanvas.tileSize;
+ obj.x -= fallDist * gameCanvas.blockSize;
board[index(column-fallDist,row)] = obj;
board[index(column,row)] = null;
}
@@ -155,20 +152,21 @@ function shuffleDown()
//![2]
function victoryCheck()
{
- //awards bonuses for no tiles left
+ //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)
gameCanvas.score += 500;
- //Checks for game over
+
+ //Check whether game has finished
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 tiles
+//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)
diff --git a/examples/declarative/tutorials/samegame/samegame3/samegame.qml b/examples/declarative/tutorials/samegame/samegame3/samegame.qml
index 9623932..cdf99d7 100644
--- a/examples/declarative/tutorials/samegame/samegame3/samegame.qml
+++ b/examples/declarative/tutorials/samegame/samegame3/samegame.qml
@@ -21,11 +21,11 @@ Rectangle {
Item {
id: gameCanvas
property int score: 0
- property int tileSize: 40
+ property int blockSize: 40
z: 20; anchors.centerIn: parent
- width: parent.width - (parent.width % tileSize);
- height: parent.height - (parent.height % tileSize);
+ width: parent.width - (parent.width % blockSize);
+ height: parent.height - (parent.height % blockSize);
MouseArea {
anchors.fill: parent; onClicked: SameGame.handleClick(mouse.x,mouse.y);
@@ -45,7 +45,7 @@ Rectangle {
anchors.bottom: screen.bottom
Button {
- text: "New Game"; onClicked: SameGame.initBoard();
+ text: "New Game"; onClicked: SameGame.startNewGame();
anchors.left: parent.left; anchors.leftMargin: 3
anchors.verticalCenter: parent.verticalCenter
}
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/Dialog.qml b/examples/declarative/tutorials/samegame/samegame4/content/Dialog.qml
index 0716bb3..15f5b19 100644
--- a/examples/declarative/tutorials/samegame/samegame4/content/Dialog.qml
+++ b/examples/declarative/tutorials/samegame/samegame4/content/Dialog.qml
@@ -11,7 +11,7 @@ Rectangle {
page.opacity = 1;
}
signal closed();
- color: "white"; border.width: 1; width: dialogText.width + 20; height: 60;
+ color: "white"; border.width: 1; width: dialogText.width + 20; height: dialogText.height + 20;
opacity: 0
Behavior on opacity {
NumberAnimation { duration: 1000 }
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
index a905f7d..0b1c6d6 100755
--- a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
@@ -1,38 +1,28 @@
/* This script file handles the game logic */
-//Note that X/Y referred to here are in game coordinates
-var maxColumn = 10;//Nums are for gameCanvas.tileSize 40
+var maxColumn = 10;
var maxRow = 15;
var maxIndex = maxColumn*maxRow;
var board = new Array(maxIndex);
-var tileSrc = "content/BoomBlock.qml";
-//var scoresURL = "http://qtfx-nokia.trolltech.com.au/samegame/scores.php";
+var component;
var scoresURL = "";
-var timer;
-var component = createComponent(tileSrc);
+var gameDuration;
//Index function used instead of a 2D array
function index(column,row) {
return column + (row * maxColumn);
}
-function timeStr(msecs) {
- var secs = Math.floor(msecs/1000);
- var m = Math.floor(secs/60);
- var ret = "" + m + "m " + (secs%60) + "s";
- return ret;
-}
-
-function initBoard()
+function startNewGame()
{
for(var i = 0; i<maxIndex; i++){
- //Delete old blocks
+ //Delete blocks from previous game
if(board[i] != null)
board[i].destroy();
}
//Calculate board size
- maxColumn = Math.floor(gameCanvas.width/gameCanvas.tileSize);
- maxRow = Math.floor(gameCanvas.height/gameCanvas.tileSize);
+ maxColumn = Math.floor(gameCanvas.width/gameCanvas.blockSize);
+ maxRow = Math.floor(gameCanvas.height/gameCanvas.blockSize);
maxIndex = maxRow*maxColumn;
//Close dialogs
@@ -49,21 +39,52 @@ function initBoard()
}
}
- timer = new Date();
+ gameDuration = new Date();
+}
+
+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){
+ var dynamicObject = component.createObject();
+ 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.width = gameCanvas.blockSize;
+ dynamicObject.height = gameCanvas.blockSize;
+ dynamicObject.spawned = true;
+ board[index(column,row)] = dynamicObject;
+ }else{
+ print("error loading block component");
+ print(component.errorsString());
+ return false;
+ }
+ return true;
}
-var fillFound;//Set after a floodFill call to the number of tiles found
+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
-//NOTE: Be careful with vars named x,y, as the calling object's x,y are still in scope
-function handleClick(x,y)
+
+function handleClick(xPos,yPos)
{
- var column = Math.floor(x/gameCanvas.tileSize);
- var row = Math.floor(y/gameCanvas.tileSize);
+ 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)
return;
- //If it's a valid tile, remove it and all connected (does nothing if it's not connected)
+ //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)
return;
@@ -95,7 +116,7 @@ function floodFill(column,row,type)
floodFill(column,row+1,type);
floodFill(column,row-1,type);
if(first==true && fillFound == 0)
- return;//Can't remove single tiles
+ return;//Can't remove single blocks
board[index(column,row)].dying = true;
board[index(column,row)] = null;
fillFound += 1;
@@ -112,7 +133,7 @@ function shuffleDown()
}else{
if(fallDist > 0){
var obj = board[index(column,row)];
- obj.targetY += fallDist * gameCanvas.tileSize;
+ obj.targetY += fallDist * gameCanvas.blockSize;
board[index(column,row+fallDist)] = obj;
board[index(column,row)] = null;
}
@@ -130,7 +151,7 @@ function shuffleDown()
obj = board[index(column,row)];
if(obj == null)
continue;
- obj.targetX -= fallDist * gameCanvas.tileSize;
+ obj.targetX -= fallDist * gameCanvas.blockSize;
board[index(column-fallDist,row)] = obj;
board[index(column,row)] = null;
}
@@ -141,21 +162,22 @@ function shuffleDown()
function victoryCheck()
{
- //awards bonuses for no tiles left
+ //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)
gameCanvas.score += 500;
- //Checks for game over
+
+ //Check whether game has finished
if(deservesBonus || !(floodMoveCheck(0,maxRow-1, -1))){
- timer = new Date() - timer;
+ 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 tiles
+//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)
@@ -169,35 +191,6 @@ function floodMoveCheck(column, row, type)
floodMoveCheck(column, row - 1, board[index(column,row)].type);
}
-function createBlock(column,row){
- // Note that we don't wait for the component to become ready. This will
- // only work if the block QML is a local file. Otherwise the component will
- // not be ready immediately. There is a statusChanged signal on the
- // component you could use if you want to wait to load remote files.
- if(component.isReady){
- var dynamicObject = component.createObject();
- 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.tileSize;
- dynamicObject.targetX = column*gameCanvas.tileSize;
- dynamicObject.targetY = row*gameCanvas.tileSize;
- dynamicObject.width = gameCanvas.tileSize;
- dynamicObject.height = gameCanvas.tileSize;
- dynamicObject.spawned = true;
- board[index(column,row)] = dynamicObject;
- }else{//isError or isLoading
- print("error loading block component");
- print(component.errorsString());
- return false;
- }
- return true;
-}
-
//![2]
function saveHighScore(name) {
if(scoresURL!="")
@@ -205,7 +198,7 @@ function saveHighScore(name) {
//OfflineStorage
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(timer/1000)];
+ 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)');
@@ -228,7 +221,7 @@ function saveHighScore(name) {
function sendHighScore(name) {
var postman = new XMLHttpRequest()
var postData = "name="+name+"&score="+gameCanvas.score
- +"&gridSize="+maxColumn+"x"+maxRow +"&time="+Math.floor(timer/1000);
+ +"&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() {
diff --git a/examples/declarative/tutorials/samegame/samegame4/samegame.qml b/examples/declarative/tutorials/samegame/samegame4/samegame.qml
index fe35e3b..5d5c81f 100644
--- a/examples/declarative/tutorials/samegame/samegame4/samegame.qml
+++ b/examples/declarative/tutorials/samegame/samegame4/samegame.qml
@@ -20,11 +20,11 @@ Rectangle {
Item {
id: gameCanvas
property int score: 0
- property int tileSize: 40
+ property int blockSize: 40
z: 20; anchors.centerIn: parent
- width: parent.width - (parent.width % tileSize);
- height: parent.height - (parent.height % tileSize);
+ width: parent.width - (parent.width % blockSize);
+ height: parent.height - (parent.height % blockSize);
MouseArea {
anchors.fill: parent; onClicked: SameGame.handleClick(mouse.x,mouse.y);
@@ -63,7 +63,7 @@ Rectangle {
anchors.bottom: screen.bottom
Button {
- text: "New Game"; onClicked: SameGame.initBoard();
+ text: "New Game"; onClicked: SameGame.startNewGame();
anchors.left: parent.left; anchors.leftMargin: 3
anchors.verticalCenter: parent.verticalCenter
}
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index af76a67..eab41e3 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -48,7 +48,6 @@ HEADERS += \
$$PWD/qdeclarativetext_p_p.h \
$$PWD/qdeclarativevisualitemmodel_p.h \
$$PWD/qdeclarativelistview_p.h \
- $$PWD/qdeclarativegraphicsobjectcontainer_p.h \
$$PWD/qdeclarativelayoutitem_p.h \
$$PWD/qdeclarativeitemchangelistener_p.h \
$$PWD/qdeclarativeeffects.cpp
@@ -82,5 +81,4 @@ SOURCES += \
$$PWD/qdeclarativetextedit.cpp \
$$PWD/qdeclarativevisualitemmodel.cpp \
$$PWD/qdeclarativelistview.cpp \
- $$PWD/qdeclarativegraphicsobjectcontainer.cpp \
$$PWD/qdeclarativelayoutitem.cpp
diff --git a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp
deleted file mode 100644
index f5beebd..0000000
--- a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qdeclarativegraphicsobjectcontainer_p.h"
-
-#include "private/qdeclarativeitem_p.h"
-
-#include <QGraphicsObject>
-#include <QGraphicsWidget>
-#include <QGraphicsSceneResizeEvent>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeGraphicsObjectContainerPrivate : public QDeclarativeItemPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeGraphicsObjectContainer)
-
-public:
- QDeclarativeGraphicsObjectContainerPrivate() : QDeclarativeItemPrivate(), graphicsObject(0), syncedResize(false)
- { }
-
- void _q_updateSize();
-
- void setFiltering(bool on)
- {
- Q_Q(QDeclarativeGraphicsObjectContainer);
- if (graphicsObject && graphicsObject->isWidget()) {
- if (!on) {
- graphicsObject->removeEventFilter(q);
- QObject::disconnect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize()));
- QObject::disconnect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize()));
- } else {
- graphicsObject->installEventFilter(q);
- QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize()));
- QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize()));
- }
- }
- }
-
-
- QGraphicsObject *graphicsObject;
- bool syncedResize;
-};
-
-
-/*!
- \qmlclass GraphicsObjectContainer QDeclarativeGraphicsObjectContainer
- \since 4.7
- \brief The GraphicsObjectContainer element allows you to add QGraphicsObjects into Fluid UI elements.
-
- While any QObject based class can be exposed to QML, QDeclarativeItem
- provides a lot of important functionality, including anchors and proper
- management of child items. GraphicsObjectContainer helps provide these
- functions to other QGraphicsObjects, so that they can be used unaltered in
- a QML scene. QGraphicsObjects, which are not QDeclarativeItems, and which are
- placed in a QML scene outside of a GraphicsObjectContainer, will not appear
- on screen at all.
-
- A GraphicsObjectContainer can have one element inside it, and it must be a
- QGraphicsObject or subclass which has been exposed to the QML engine.
- The graphics object inside the GraphicsObjectContainer can then be used
- like any other item in QML with the exception of not being reparentable
- and not having the standard properties of QML items (such as anchors).
-
- As the contained object is positioned relative to the container, anchors
- affecting the container item will affect the onscreen position of the
- contained item. If synchronizedResizing is set to true, then anchors
- affecting the container item's size will also affect the contained item's
- size.
-
- Example:
- \code
- import Qt 4.7
- import MyApp 2.1 as Widgets
- Rectangle{
- id: rect
- property alias widgetPropertyThree: widget.myThirdProperty;
- GraphicsObjectContainer{
- synchronizedResizing: true
- anchors.margins: 10
- anchors.fill: parent
- Widgets.MyWidget{
- myProperty: "A Value"
- myOtherProperty: rect.color
- }
- }
- }
- \endcode
-*/
-
-/*!
- \internal
- \class QDeclarativeGraphicsObjectContainer
- \brief The QDeclarativeGraphicsObjectContainer class allows you to add QGraphicsObjects into Fluid UI applications.
-*/
-
-QDeclarativeGraphicsObjectContainer::QDeclarativeGraphicsObjectContainer(QDeclarativeItem *parent)
-: QDeclarativeItem(*new QDeclarativeGraphicsObjectContainerPrivate, parent)
-{
-}
-
-QDeclarativeGraphicsObjectContainer::~QDeclarativeGraphicsObjectContainer()
-{
-}
-
-QGraphicsObject *QDeclarativeGraphicsObjectContainer::graphicsObject() const
-{
- Q_D(const QDeclarativeGraphicsObjectContainer);
- return d->graphicsObject;
-}
-
-/*!
- \qmlproperty QGraphicsObject GraphicsObjectContainer::graphicsObject
- The QGraphicsObject associated with this element.
-*/
-void QDeclarativeGraphicsObjectContainer::setGraphicsObject(QGraphicsObject *object)
-{
- Q_D(QDeclarativeGraphicsObjectContainer);
- if (object == d->graphicsObject)
- return;
-
- //### remove previously set item?
-
- d->setFiltering(false);
-
- d->graphicsObject = object;
-
- if (d->graphicsObject) {
- d->graphicsObject->setParentItem(this);
-
- if (d->syncedResize && d->graphicsObject->isWidget()) {
- QGraphicsWidget *gw = static_cast<QGraphicsWidget*>(d->graphicsObject);
- QSizeF gwSize = gw->size(); //### should we use sizeHint?
- QSizeF newSize = gwSize;
- if (heightValid())
- newSize.setHeight(height());
- if (widthValid())
- newSize.setWidth(width());
- if (gwSize != newSize)
- gw->resize(newSize);
-
- gwSize = gw->size();
- setImplicitWidth(gwSize.width());
- setImplicitHeight(gwSize.height());
-
- d->setFiltering(true);
- }
- }
-}
-
-QVariant QDeclarativeGraphicsObjectContainer::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- Q_D(QDeclarativeGraphicsObjectContainer);
- if (change == ItemSceneHasChanged) {
- QGraphicsObject *o = d->graphicsObject;
- d->graphicsObject = 0;
- setGraphicsObject(o);
- }
- return QDeclarativeItem::itemChange(change, value);
-}
-
-bool QDeclarativeGraphicsObjectContainer::eventFilter(QObject *watched, QEvent *e)
-{
- Q_D(QDeclarativeGraphicsObjectContainer);
- if (watched == d->graphicsObject && e->type() == QEvent::GraphicsSceneResize) {
- if (d->graphicsObject && d->graphicsObject->isWidget() && d->syncedResize) {
- QSizeF newSize = static_cast<QGraphicsWidget*>(d->graphicsObject)->size();
- setImplicitWidth(newSize.width());
- setImplicitHeight(newSize.height());
- }
- }
- return QDeclarativeItem::eventFilter(watched, e);
-}
-
-/*!
- \qmlproperty bool GraphicsObjectContainer::synchronizedResizing
-
- This property determines whether or not the container and graphics object will synchronize their
- sizes.
-
- \note This property only applies when wrapping a QGraphicsWidget.
-
- If synchronizedResizing is enabled, the container and widget will
- synchronize their sizes as follows.
- \list
- \o If a size has been set on the container, the widget will be resized to the container.
- Any changes in the container's size will be reflected in the widget.
-
- \o \e Otherwise, the container will initially be sized to the preferred size of the widget.
- Any changes to the container's size will be reflected in the widget, and any changes to the
- widget's size will be reflected in the container.
- \endlist
-*/
-bool QDeclarativeGraphicsObjectContainer::synchronizedResizing() const
-{
- Q_D(const QDeclarativeGraphicsObjectContainer);
- return d->syncedResize;
-}
-
-void QDeclarativeGraphicsObjectContainer::setSynchronizedResizing(bool on)
-{
- Q_D(QDeclarativeGraphicsObjectContainer);
- if (on == d->syncedResize)
- return;
-
- d->syncedResize = on;
- d->setFiltering(on);
-}
-
-void QDeclarativeGraphicsObjectContainerPrivate::_q_updateSize()
-{
- if (!graphicsObject || !graphicsObject->isWidget() || !syncedResize)
- return;
-
- QGraphicsWidget *gw = static_cast<QGraphicsWidget*>(graphicsObject);
- const QSizeF newSize(width(), height());
- gw->resize(newSize);
-
- //### will respecting the widgets min/max ever get us in trouble? (all other items always
- // size to exactly what you tell them)
- /*QSizeF constrainedSize = newSize.expandedTo(gw->minimumSize()).boundedTo(gw->maximumSize());
- gw->resize(constrainedSize);
- if (constrainedSize != newSize) {
- setImplicitWidth(constrainedSize.width());
- setImplicitHeight(constrainedSize.height());
- }*/
-}
-
-#include <moc_qdeclarativegraphicsobjectcontainer_p.cpp>
-
-QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer_p.h b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer_p.h
deleted file mode 100644
index 20c5bcf..0000000
--- a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer_p.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEGRAPHICSOBJECTCONTAINER_H
-#define QDECLARATIVEGRAPHICSOBJECTCONTAINER_H
-
-#include "qdeclarativeitem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QGraphicsObject;
-class QDeclarativeGraphicsObjectContainerPrivate;
-
-class Q_DECLARATIVE_EXPORT QDeclarativeGraphicsObjectContainer : public QDeclarativeItem
-{
- Q_OBJECT
-
- Q_CLASSINFO("DefaultProperty", "graphicsObject")
- Q_PROPERTY(QGraphicsObject *graphicsObject READ graphicsObject WRITE setGraphicsObject)
- Q_PROPERTY(bool synchronizedResizing READ synchronizedResizing WRITE setSynchronizedResizing)
-
-public:
- QDeclarativeGraphicsObjectContainer(QDeclarativeItem *parent = 0);
- ~QDeclarativeGraphicsObjectContainer();
-
- QGraphicsObject *graphicsObject() const;
- void setGraphicsObject(QGraphicsObject *);
-
- bool synchronizedResizing() const;
- void setSynchronizedResizing(bool on);
-
-protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant &value);
- bool eventFilter(QObject *watched, QEvent *e);
-
-private:
- Q_PRIVATE_SLOT(d_func(), void _q_updateSize())
- Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeGraphicsObjectContainer)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QDeclarativeGraphicsObjectContainer)
-
-QT_END_HEADER
-
-#endif // QDECLARATIVEGRAPHICSOBJECTCONTAINER_H
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 35a4d00..7664af1 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -57,7 +57,6 @@
#include "private/qdeclarativeflipable_p.h"
#include "private/qdeclarativefocuspanel_p.h"
#include "private/qdeclarativefocusscope_p.h"
-#include "private/qdeclarativegraphicsobjectcontainer_p.h"
#include "private/qdeclarativegridview_p.h"
#include "private/qdeclarativeimage_p.h"
#include "private/qdeclarativeitem_p.h"
@@ -96,7 +95,6 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterType<QDeclarativeFocusScope>("Qt",4,6,"FocusScope");
qmlRegisterType<QDeclarativeGradient>("Qt",4,6,"Gradient");
qmlRegisterType<QDeclarativeGradientStop>("Qt",4,6,"GradientStop");
- qmlRegisterType<QDeclarativeGraphicsObjectContainer>("Qt",4,6,"GraphicsObjectContainer");
qmlRegisterType<QDeclarativeGrid>("Qt",4,6,"Grid");
qmlRegisterType<QDeclarativeGridView>("Qt",4,6,"GridView");
qmlRegisterType<QDeclarativeImage>("Qt",4,6,"Image");
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 4b311af..1b8b84b 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -429,6 +429,29 @@ void QDeclarativeTextInput::setFocusOnPress(bool b)
}
/*!
+ \qmlproperty bool TextInput::autoScroll
+
+ Whether the TextInput should scroll when the text is longer than the width. By default this is
+ set to true.
+*/
+bool QDeclarativeTextInput::autoScroll() const
+{
+ Q_D(const QDeclarativeTextInput);
+ return d->autoScroll;
+}
+
+void QDeclarativeTextInput::setAutoScroll(bool b)
+{
+ Q_D(QDeclarativeTextInput);
+ if (d->autoScroll == b)
+ return;
+
+ d->autoScroll = b;
+
+ emit autoScrollChanged(d->autoScroll);
+}
+
+/*!
\qmlproperty Validator TextInput::validator
Allows you to set a validator on the TextInput. When a validator is set
@@ -645,6 +668,8 @@ void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus)
Q_Q(QDeclarativeTextInput);
focused = hasFocus;
q->setCursorVisible(hasFocus);
+ if (!hasFocus)
+ control->deselect();
QDeclarativeItemPrivate::focusChanged(hasFocus);
}
@@ -679,7 +704,15 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
setFocus(true);
}
- d->control->processEvent(event);
+ bool mark = event->modifiers() & Qt::ShiftModifier;
+ int cursor = d->xToPos(event->pos().x());
+ d->control->moveCursor(cursor, mark);
+}
+
+void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativeTextInput);
+ d->control->moveCursor(d->xToPos(event->pos().x()), true);
}
/*!
@@ -704,6 +737,7 @@ bool QDeclarativeTextInput::event(QEvent* ev)
case QEvent::KeyPress:
case QEvent::KeyRelease://###Should the control be doing anything with release?
case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMouseRelease:
break;
default:
@@ -733,28 +767,56 @@ void QDeclarativeTextInput::drawContents(QPainter *p, const QRect &r)
int flags = QLineControl::DrawText;
if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
flags |= QLineControl::DrawCursor;
- if (d->control->hasSelectedText()){
+ if (d->control->hasSelectedText())
flags |= QLineControl::DrawSelections;
- }
-
QPoint offset = QPoint(0,0);
- if(d->hAlign != AlignLeft){
- QFontMetrics fm = QFontMetrics(d->font);
- //###Is this using bearing appropriately?
- int minLB = qMax(0, -fm.minLeftBearing());
- int minRB = qMax(0, -fm.minRightBearing());
- int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
- int hOffset = 0;
+ QFontMetrics fm = QFontMetrics(d->font);
+ int cix = qRound(d->control->cursorToX());
+ QRect br(boundingRect().toRect());
+ //###Is this using bearing appropriately?
+ int minLB = qMax(0, -fm.minLeftBearing());
+ int minRB = qMax(0, -fm.minRightBearing());
+ int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
+ if (d->autoScroll) {
+ if ((minLB + widthUsed) <= br.width()) {
+ // text fits in br; use hscroll for alignment
+ switch (d->hAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
+ case Qt::AlignRight:
+ d->hscroll = widthUsed - br.width() + 1;
+ break;
+ case Qt::AlignHCenter:
+ d->hscroll = (widthUsed - br.width()) / 2;
+ break;
+ default:
+ // Left
+ d->hscroll = 0;
+ break;
+ }
+ d->hscroll -= minLB;
+ } else if (cix - d->hscroll >= br.width()) {
+ // text doesn't fit, cursor is to the right of br (scroll right)
+ d->hscroll = cix - br.width() + 1;
+ } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) {
+ // text doesn't fit, cursor is to the left of br (scroll left)
+ d->hscroll = cix;
+ } else if (widthUsed - d->hscroll < br.width()) {
+ // text doesn't fit, text document is to the left of br; align
+ // right
+ d->hscroll = widthUsed - br.width() + 1;
+ }
+ // the y offset is there to keep the baseline constant in case we have script changes in the text.
+ offset = br.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
+ } else {
if(d->hAlign == AlignRight){
- hOffset = width() - widthUsed;
+ d->hscroll = width() - widthUsed;
}else if(d->hAlign == AlignHCenter){
- hOffset = (width() - widthUsed) / 2;
+ d->hscroll = (width() - widthUsed) / 2;
}
- hOffset -= minLB;
- offset = QPoint(hOffset, 0);
+ d->hscroll -= minLB;
+ offset = QPoint(d->hscroll, 0);
}
- QRect clipRect = r;
- d->control->draw(p, offset, clipRect, flags);
+
+ d->control->draw(p, offset, r, flags);
p->restore();
}
@@ -892,10 +954,11 @@ void QDeclarativeTextInput::q_textChanged()
void QDeclarativeTextInput::updateRect(const QRect &r)
{
+ Q_D(QDeclarativeTextInput);
if(r == QRect())
clearCache();
else
- dirtyCache(r);
+ dirtyCache(QRect(r.x() - d->hscroll, r.y(), r.width(), r.height()));
update();
}
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index 64aff7d..6e61580 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -86,6 +86,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTextInput : public QDeclarativePaintedIte
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged)
Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged)
Q_PROPERTY(bool focusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY focusOnPressChanged)
+ Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
public:
QDeclarativeTextInput(QDeclarativeItem* parent=0);
@@ -163,6 +164,9 @@ public:
bool focusOnPress() const;
void setFocusOnPress(bool);
+ bool autoScroll() const;
+ void setAutoScroll(bool);
+
bool hasAcceptableInput() const;
void drawContents(QPainter *p,const QRect &r);
@@ -189,12 +193,14 @@ Q_SIGNALS:
void inputMaskChanged(const QString &inputMask);
void echoModeChanged(EchoMode echoMode);
void focusOnPressChanged(bool focusOnPress);
+ void autoScrollChanged(bool autoScroll);
protected:
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void keyPressEvent(QKeyEvent* ev);
bool event(QEvent *e);
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index 9e44b15..26cf78c 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -72,7 +72,7 @@ public:
color((QRgb)0), style(QDeclarativeText::Normal),
styleColor((QRgb)0), hAlign(QDeclarativeTextInput::AlignLeft),
hscroll(0), oldScroll(0), focused(false), focusOnPress(true),
- cursorVisible(false)
+ cursorVisible(false), autoScroll(true)
{
}
@@ -81,6 +81,14 @@ public:
delete control;
}
+ int xToPos(int x, QTextLine::CursorPosition betweenOrOn = QTextLine::CursorBetweenCharacters) const
+ {
+ Q_Q(const QDeclarativeTextInput);
+ QRect cr = q->boundingRect().toRect();
+ x-= cr.x() - hscroll;
+ return control->xToPos(x, betweenOrOn);
+ }
+
void init();
void startCreatingCursor();
void focusChanged(bool hasFocus);
@@ -107,6 +115,7 @@ public:
bool focused;
bool focusOnPress;
bool cursorVisible;
+ bool autoScroll;
};
QT_END_NAMESPACE
diff --git a/src/imports/widgets/graphicslayouts_p.h b/src/imports/widgets/graphicslayouts_p.h
index f9b9ae8..1c3dfe5 100644
--- a/src/imports/widgets/graphicslayouts_p.h
+++ b/src/imports/widgets/graphicslayouts_p.h
@@ -42,10 +42,9 @@
#ifndef GRAPHICSLAYOUTS_H
#define GRAPHICSLAYOUTS_H
-#include "graphicswidgets_p.h"
-
#include <QtGui/QGraphicsLinearLayout>
#include <QtGui/QGraphicsGridLayout>
+#include <qdeclarative.h>
QT_BEGIN_HEADER
diff --git a/src/imports/widgets/graphicswidgets.cpp b/src/imports/widgets/graphicswidgets.cpp
deleted file mode 100644
index 062e516..0000000
--- a/src/imports/widgets/graphicswidgets.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
diff --git a/src/imports/widgets/graphicswidgets_p.h b/src/imports/widgets/graphicswidgets_p.h
deleted file mode 100644
index 2c2b707..0000000
--- a/src/imports/widgets/graphicswidgets_p.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef GRAPHICSWIDGETS_H
-#define GRAPHICSWIDGETS_H
-
-#include <qdeclarative.h>
-
-#include <QtGui/QGraphicsScene>
-#include <QtGui/QGraphicsView>
-#include <QtGui/QGraphicsWidget>
-#include <QtGui/QGraphicsItem>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QGraphicsView)
-QML_DECLARE_TYPE_HASMETATYPE(QGraphicsScene)
-QML_DECLARE_TYPE(QGraphicsWidget)
-QML_DECLARE_TYPE(QGraphicsObject)
-QML_DECLARE_INTERFACE_HASMETATYPE(QGraphicsItem)
-
-QT_END_HEADER
-
-#endif // GRAPHICSWIDGETS_H
diff --git a/src/imports/widgets/widgets.cpp b/src/imports/widgets/widgets.cpp
index bc18e8a..f26969a 100644
--- a/src/imports/widgets/widgets.cpp
+++ b/src/imports/widgets/widgets.cpp
@@ -41,75 +41,12 @@
#include <QtDeclarative/qdeclarativeextensionplugin.h>
#include <QtDeclarative/qdeclarative.h>
+#include <QGraphicsWidget>
#include "graphicslayouts_p.h"
-#include "graphicswidgets_p.h"
QT_BEGIN_NAMESPACE
-class QGraphicsViewDeclarativeUI : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QGraphicsScene *scene READ scene WRITE setScene)
- Q_CLASSINFO("DefaultProperty", "scene")
-public:
- QGraphicsViewDeclarativeUI(QObject *other) : QObject(other) {}
-
- QGraphicsScene *scene() const { return static_cast<QGraphicsView *>(parent())->scene(); }
- void setScene(QGraphicsScene *scene)
- {
- static_cast<QGraphicsView *>(parent())->setScene(scene);
- }
-};
-
-class QGraphicsSceneDeclarativeUI : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QDeclarativeListProperty<QObject> children READ children)
- Q_CLASSINFO("DefaultProperty", "children")
-public:
- QGraphicsSceneDeclarativeUI(QObject *other) : QObject(other) {}
-
- QDeclarativeListProperty<QObject> children() { return QDeclarativeListProperty<QObject>(this->parent(), 0, children_append); }
-
-private:
- static void children_append(QDeclarativeListProperty<QObject> *prop, QObject *o) {
- if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(o))
- static_cast<QGraphicsScene *>(prop->object)->addItem(go);
- }
-};
-
-class QGraphicsWidgetDeclarativeUI : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QDeclarativeListProperty<QGraphicsItem> children READ children)
- Q_PROPERTY(QGraphicsLayout *layout READ layout WRITE setLayout)
- Q_CLASSINFO("DefaultProperty", "children")
-public:
- QGraphicsWidgetDeclarativeUI(QObject *other) : QObject(other) {}
-
- QDeclarativeListProperty<QGraphicsItem> children() { return QDeclarativeListProperty<QGraphicsItem>(this, 0, children_append); }
-
- QGraphicsLayout *layout() const { return static_cast<QGraphicsWidget *>(parent())->layout(); }
- void setLayout(QGraphicsLayout *lo)
- {
- static_cast<QGraphicsWidget *>(parent())->setLayout(lo);
- }
-
-private:
- void setItemParent(QGraphicsItem *wid)
- {
- wid->setParentItem(static_cast<QGraphicsWidget *>(parent()));
- }
-
- static void children_append(QDeclarativeListProperty<QGraphicsItem> *prop, QGraphicsItem *i) {
- static_cast<QGraphicsWidgetDeclarativeUI*>(prop->object)->setItemParent(i);
- }
-};
-
class QWidgetsQmlModule : public QDeclarativeExtensionPlugin
{
Q_OBJECT
@@ -123,10 +60,7 @@ public:
qmlRegisterType<QGraphicsLinearLayoutStretchItemObject>(uri,4,6,"QGraphicsLinearLayoutStretchItem");
qmlRegisterType<QGraphicsLinearLayoutObject>(uri,4,6,"QGraphicsLinearLayout");
qmlRegisterType<QGraphicsGridLayoutObject>(uri,4,6,"QGraphicsGridLayout");
- qmlRegisterExtendedType<QGraphicsView, QGraphicsViewDeclarativeUI>(uri,4,6,"QGraphicsView");
- qmlRegisterExtendedType<QGraphicsScene,QGraphicsSceneDeclarativeUI>(uri,4,6,"QGraphicsScene");
- qmlRegisterExtendedType<QGraphicsWidget,QGraphicsWidgetDeclarativeUI>(uri,4,6,"QGraphicsWidget");
- qmlRegisterInterface<QGraphicsItem>("QGraphicsItem");
+ qmlRegisterType<QGraphicsWidget>(uri,4,6,"QGraphicsWidget");
}
};
diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro
index 408f878..f26e4b9 100644
--- a/src/imports/widgets/widgets.pro
+++ b/src/imports/widgets/widgets.pro
@@ -9,7 +9,6 @@ SOURCES += \
widgets.cpp
HEADERS += \
- graphicswidgets_p.h \
graphicslayouts_p.h
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index 2b0b151..dd74c09 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -73,6 +73,7 @@ private slots:
void sendRequestSoftwareInputPanelEvent();
void setHAlignClearCache();
+ void focusOutClearSelection();
private:
void simulateKey(QDeclarativeView *, int key);
@@ -725,6 +726,29 @@ void tst_qdeclarativetextinput::setHAlignClearCache()
QCOMPARE(input.nbPaint, 2);
}
+void tst_qdeclarativetextinput::focusOutClearSelection()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QDeclarativeTextInput input;
+ QDeclarativeTextInput input2;
+ input.setText(QLatin1String("Hello world"));
+ input.setFocus(true);
+ scene.addItem(&input2);
+ scene.addItem(&input);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ input.setSelectionStart(2);
+ input.setSelectionEnd(5);
+ //The selection should work
+ QTRY_COMPARE(input.selectedText(), QLatin1String("llo"));
+ input2.setFocus(true);
+ QApplication::processEvents();
+ //The input lost the focus selection should be cleared
+ QTRY_COMPARE(input.selectedText(), QLatin1String(""));
+}
+
QTEST_MAIN(tst_qdeclarativetextinput)
#include "tst_qdeclarativetextinput.moc"