From e3af2d86b4b592e4b277c828c37ea845329feada Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 27 Oct 2009 19:06:03 +1000 Subject: Update dynamic example The start of a prettier version. Not yet complete, does not full resolve the task. Task-number: QT-2270 --- examples/declarative/dynamic/DynRect.qml | 9 -- examples/declarative/dynamic/Sun.qml | 22 +++ examples/declarative/dynamic/dynamic.js | 59 -------- examples/declarative/dynamic/dynamic.qml | 157 +++++++++++++-------- examples/declarative/dynamic/images/face-smile.png | Bin 0 -> 15408 bytes examples/declarative/dynamic/images/star.png | Bin 0 -> 349 bytes examples/declarative/dynamic/images/sun.png | Bin 0 -> 8153 bytes examples/declarative/dynamic/star.png | Bin 262 -> 0 bytes examples/declarative/dynamic/sunCreation.js | 69 +++++++++ 9 files changed, 188 insertions(+), 128 deletions(-) delete mode 100644 examples/declarative/dynamic/DynRect.qml create mode 100644 examples/declarative/dynamic/Sun.qml delete mode 100644 examples/declarative/dynamic/dynamic.js create mode 100644 examples/declarative/dynamic/images/face-smile.png create mode 100644 examples/declarative/dynamic/images/star.png create mode 100644 examples/declarative/dynamic/images/sun.png delete mode 100644 examples/declarative/dynamic/star.png create mode 100644 examples/declarative/dynamic/sunCreation.js diff --git a/examples/declarative/dynamic/DynRect.qml b/examples/declarative/dynamic/DynRect.qml deleted file mode 100644 index 06141ea..0000000 --- a/examples/declarative/dynamic/DynRect.qml +++ /dev/null @@ -1,9 +0,0 @@ -import Qt 4.6 - -Item { - states: State{ name: "dying"; PropertyChanges{ target: newRect; opacity: 0 } } - transitions: Transition{ - NumberAnimation{ properties: "opacity"; target: newRect; duration:500 } - } - Rectangle {color: "steelblue"; width: 100; height: 100; id: newRect } -} diff --git a/examples/declarative/dynamic/Sun.qml b/examples/declarative/dynamic/Sun.qml new file mode 100644 index 0000000..16d9907 --- /dev/null +++ b/examples/declarative/dynamic/Sun.qml @@ -0,0 +1,22 @@ +import Qt 4.6 + +Image { + id: sun + property bool created: false + onCreatedChanged: if(created){window.activeSuns++;}else{window.activeSuns--;} + + source: "images/sun.png"; + + //x and y get set when instantiated + //head offscreen + y: NumberAnimation { + to: parent.height; + duration: 10000; + running: created + } + + states: State { + name: "OffScreen"; when: created && y > window.height/2;//Below the ground + StateChangeScript { script: { sun.created = false; sun.destroy() } } + } +} diff --git a/examples/declarative/dynamic/dynamic.js b/examples/declarative/dynamic/dynamic.js deleted file mode 100644 index 8bfdba3..0000000 --- a/examples/declarative/dynamic/dynamic.js +++ /dev/null @@ -1,59 +0,0 @@ -var dynamicObject = null; -var fourthBox = null; -var component = null; -var started = false; - -function createQml(p) { - return createQmlObject('DynRect {}', p, 'DynPart.qml'); -} - -function destroyDynamicObject() { - if (!(dynamicObject == null)) { - dynamicObject.destroy(); - dynamicObject = null; - } -} - -function instantCreateWithComponent() {//Like create, but assumes instant readyness - if (dynamicObject != null)//Already made - return null; - component = createComponent("dynamic.qml"); - dynamicObject = component.createObject(); - - if (dynamicObject == null) { - print("error creating component"); - } else { - dynamicObject.parent = targetItem; - return dynamicObject; - } - return null; -} - -function finishCreation() { - if (component.isReady && dynamicObject == null) { - dynamicObject = component.createObject(); - dynamicObject.parent = targetItem; - } else if (component.isError) { - dynamicObject = null; - print("error creating component"); - print(component.errorsString()); - } -} - -function createWithComponent() { - if (component != null) { - return finishCreation(); - } - if (started != false) { - finishCreation();//Remakes if destroyed - return dynamicObject; - } - started = true; - component = createComponent("dynamic.qml"); - finishCreation(); - if (dynamicObject != null) { - return dynamicObject; - } - component.statusChanged.connect(finishCreation); - return null; -} diff --git a/examples/declarative/dynamic/dynamic.qml b/examples/declarative/dynamic/dynamic.qml index 2c6a8e0..aea9b0f 100644 --- a/examples/declarative/dynamic/dynamic.qml +++ b/examples/declarative/dynamic/dynamic.qml @@ -1,79 +1,116 @@ import Qt 4.6 -Rectangle { - id: page - width: 800 - height: 800 - color: "black" - Script { source: "dynamic.js" } +Item { + id: window + //This is a desktop example + width: 1024; height: 480 + property int activeSuns: 0 - property bool extendStars: false - property var fourthBox: undefined - - Item { id: targetItem; x: 100; y: 100; } - Item { id: targetItem2; x: 0; y: 300; } + // sky + Rectangle { id: sky + anchors { left: parent.left; top: parent.top; right: toolbox.right; bottom: parent.verticalCenter } + gradient: Gradient { + GradientStop { id: stopA; position: 0.0; color: "#0E1533" } + GradientStop { id: stopB; position: 1.0; color: "#437284" } + } + } - Rectangle { - id: rect - width: 100 - height: 100 - color: "green" + // stars (when there's no sun) + Particles { id: stars + x: 0; y: 0; width: parent.width; height: parent.height/2 + source: "images/star.png"; angleDeviation: 360; velocity: 0 + velocityDeviation: 0; count: parent.width / 10; fadeInDuration: 2800 + opacity: 1 + } - MouseRegion { - anchors.fill: parent - onClicked: { var a = createWithComponent(); } + // ground, which has a z such that the sun can set behind it + Rectangle { id: ground + z: 2 + anchors { left: parent.left; top: parent.verticalCenter; right: toolbox.right; bottom: parent.bottom } + gradient: Gradient { + GradientStop { position: 0.0; color: "ForestGreen" } + GradientStop { position: 1.0; color: "DarkGreen" } } } - Rectangle { - id: rect2 - width: 100 - height: 100 - y: 100 - color: "red" + states: State { name: "Day"; when: window.activeSuns > 0 + PropertyChanges { target: stopA; color: "DeepSkyBlue"} + PropertyChanges { target: stopB; color: "SkyBlue"} + PropertyChanges { target: stars; opacity: 0 } + } - MouseRegion { - anchors.fill:parent - onClicked: { destroyDynamicObject(); } - } + transitions: Transition { + PropertyAnimation { duration: 3000 } + ColorAnimation { duration: 3000 } } + //TODO: Below feature needs beautification to meet minimum standards + // toolbox Rectangle { - id: rect3 - width: 100 - height: 100 - y: 200 - color: "blue" + id: toolbox + z: 3 //Above ground + color: "white" + width: 480 + anchors { right: parent.right; top:parent.top; bottom: parent.bottom } + Column{ + id: toolboxPositioner + anchors.centerIn: parent + spacing: 1 + Sun { + id: sunButton + Script { source: "sunCreation.js" } + MouseRegion { + anchors.fill: parent; + onPressed: startDrag(mouse); + onPositionChanged: moveDrag(mouse); + onReleased: endDrag(mouse); + } + } + Text{ text: "Active Suns: " + activeSuns } + Rectangle { width: 440; height: 1; color: "black" } + Text{ text: "Arbitrary Javascript: " } + TextEdit { + id: jsText + width: 460 + height: 80 + readOnly: false + focusOnPress: true + + text: "window.activeSuns++;" + } + Rectangle { + width: 80 + height: 20 + color: "lightsteelblue" + Text{ anchors.centerIn: parent; text: "Execute" } + MouseRegion { + anchors.fill: parent; + onClicked: eval(jsText.text.toString()); + } + } - MouseRegion { - anchors.fill: parent - onClicked: { - if (fourthBox == null || fourthBox == undefined) { - var a = createQml(targetItem2); - if (a != null) { - a.parent = targetItem2;//BUG: this should happen automatically - fourthBox = a; - print(a.toStr()); - extendStars = true; - } - } else { - fourthBox.state = 'dying'; - fourthBox.destroy(500); - fourthBox = null; - extendStars = false; + Rectangle { width: 440; height: 1; color: "black" } + Text{ text: "Arbitrary QML: " } + TextEdit { + id: qmlText + width: 460 + height: 180 + readOnly: false + focusOnPress: true + + text: "import Qt 4.6\nImage { id: smile; x: 10; y: 10; \n source: 'images/face-smile.png';\n opacity: NumberAnimation{ \n running:true; to: 0; duration: 1500;\n }\n Component.onCompleted: smile.destroy(1500);\n}" + } + Rectangle { + width: 80 + height: 20 + color: "lightsteelblue" + Text{ anchors.centerIn: parent; text: "Create" } + MouseRegion { + anchors.fill: parent; + onClicked: {var obj=createQmlObject(qmlText.text, window, 'CustomObject'); obj.parent=window;} } } } } - Particles { - x: 0 - y: 0 - z: 10 - count: 20 - lifeSpan: 500 - width: 100 - height: if (extendStars) { 400; } else { 300; } - source: "star.png" - } } diff --git a/examples/declarative/dynamic/images/face-smile.png b/examples/declarative/dynamic/images/face-smile.png new file mode 100644 index 0000000..3d66d72 Binary files /dev/null and b/examples/declarative/dynamic/images/face-smile.png differ diff --git a/examples/declarative/dynamic/images/star.png b/examples/declarative/dynamic/images/star.png new file mode 100644 index 0000000..27ef924 Binary files /dev/null and b/examples/declarative/dynamic/images/star.png differ diff --git a/examples/declarative/dynamic/images/sun.png b/examples/declarative/dynamic/images/sun.png new file mode 100644 index 0000000..7713ca5 Binary files /dev/null and b/examples/declarative/dynamic/images/sun.png differ diff --git a/examples/declarative/dynamic/star.png b/examples/declarative/dynamic/star.png deleted file mode 100644 index defbde5..0000000 Binary files a/examples/declarative/dynamic/star.png and /dev/null differ diff --git a/examples/declarative/dynamic/sunCreation.js b/examples/declarative/dynamic/sunCreation.js new file mode 100644 index 0000000..d9e5dce --- /dev/null +++ b/examples/declarative/dynamic/sunCreation.js @@ -0,0 +1,69 @@ +var sunComponent = null; +var draggedItem = null; +var startingMouse; +//Until QT-2385 is resolved we need to convert to scene coordinates manually +var xOffset; +var yOffset; + +function startDrag(mouse) +{ + xOffset = toolbox.x + toolboxPositioner.x; + yOffset = toolbox.y + toolboxPositioner.y; + startingMouse = mouse; + loadComponent(); +} + +//Creation is split into two functions due to an asyncronous wait while +//possible external files are loaded. + +function loadComponent() { + if (sunComponent != null) //Already loaded the component + createSun(); + + sunComponent = createComponent("Sun.qml"); + if(sunComponent.isLoading){ + component.statusChanged.connect(finishCreation); + }else{//Depending on the content, it can be ready or error immediately + createSun(); + } +} + +function createSun() { + if (sunComponent.isReady && draggedItem == null) { + draggedItem = sunComponent.createObject(); + draggedItem.parent = window; + draggedItem.x = startingMouse.x + xOffset; + draggedItem.y = startingMouse.y + yOffset; + draggedItem.z = 4;//On top + } else if (sunComponent.isError) { + draggedItem = null; + print("error creating component"); + print(component.errorsString()); + } +} + +function moveDrag(mouse) +{ + if(draggedItem == null) + return; + + draggedItem.x = mouse.x + xOffset; + draggedItem.y = mouse.y + yOffset; +} + +function endDrag(mouse) +{ + if(draggedItem == null) + return; + + if(draggedItem.x + draggedItem.width > toolbox.x //Don't drop it in the toolbox + || draggedItem.y > ground.y){//Don't drop it on the ground + draggedItem.destroy(); + draggedItem = null; + }else{ + draggedItem.z = 1; + draggedItem.created = true; + draggedItem = null; + } +} + -- cgit v0.12 From e92c4b557b07e34a47615a1f7f9a5aff9e981aa6 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 27 Oct 2009 19:39:50 +1000 Subject: Support return values in synthesized methods --- src/declarative/qml/qmlcompiler.cpp | 1 + src/declarative/qml/qmlvmemetaobject.cpp | 6 ++++-- tests/auto/declarative/qmlecmascript/data/methods.3.qml | 7 +++++++ tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp | 7 +++++++ 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tests/auto/declarative/qmlecmascript/data/methods.3.qml diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 60282dc..ad74446 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -2234,6 +2234,7 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode) } sig.append(")"); QMetaMethodBuilder b = builder.addSlot(sig); + b.setReturnType("QVariant"); b.setParameterNames(s.parameterNames); ((QmlVMEMetaData *)dynamicData.data())->methodCount++; diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp index 3e1d931..83f904b 100644 --- a/src/declarative/qml/qmlvmemetaobject.cpp +++ b/src/declarative/qml/qmlvmemetaobject.cpp @@ -269,10 +269,11 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) QString code = QString::fromRawData(body, data->bodyLength); + QVariant rv; if (0 == (metaData->methodData() + id)->parameterCount) { QmlExpression expr(ctxt, code, object); expr.setTrackChange(false); - expr.value(); + rv = expr.value(); } else { QmlContext newCtxt(ctxt); QMetaMethod m = method(_id); @@ -281,8 +282,9 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) newCtxt.setContextProperty(QString::fromLatin1(names.at(ii)), *(QVariant *)a[ii + 1]); QmlExpression expr(&newCtxt, code, object); expr.setTrackChange(false); - expr.value(); + rv = expr.value(); } + if (a[0]) *reinterpret_cast(a[0]) = rv; } return -1; } diff --git a/tests/auto/declarative/qmlecmascript/data/methods.3.qml b/tests/auto/declarative/qmlecmascript/data/methods.3.qml new file mode 100644 index 0000000..2efcf6a --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/methods.3.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Object { + function testFunction() { return 19; } + + property int test: testFunction() +} diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index a0e65c5..67a98b1 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -152,6 +152,13 @@ void tst_qmlecmascript::methods() QCOMPARE(object->methodCalled(), false); QCOMPARE(object->methodIntCalled(), true); } + + { + QmlComponent component(&engine, TEST_FILE("methods.3.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("test").toInt(), 19); + } } void tst_qmlecmascript::bindingLoop() -- cgit v0.12 From 5f9091771eaa26db5ad35e4788c13ac011512b61 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 27 Oct 2009 20:03:35 +1000 Subject: Doc --- doc/src/declarative/pics/repeater-index.png | Bin 0 -> 3024 bytes doc/src/snippets/declarative/repeater-index.qml | 15 +++++++++++++++ src/declarative/fx/qfxrepeater.cpp | 12 ++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 doc/src/declarative/pics/repeater-index.png create mode 100644 doc/src/snippets/declarative/repeater-index.qml diff --git a/doc/src/declarative/pics/repeater-index.png b/doc/src/declarative/pics/repeater-index.png new file mode 100644 index 0000000..3dbe6d0 Binary files /dev/null and b/doc/src/declarative/pics/repeater-index.png differ diff --git a/doc/src/snippets/declarative/repeater-index.qml b/doc/src/snippets/declarative/repeater-index.qml new file mode 100644 index 0000000..9063967 --- /dev/null +++ b/doc/src/snippets/declarative/repeater-index.qml @@ -0,0 +1,15 @@ +import Qt 4.6 + +Rectangle { + width: 50; height: childrenRect.height; color: "white" + +//! [0] + Column { + Repeater { + model: 10 + Text { text: "I'm item " + index } + } + } +//! [0] +} + diff --git a/src/declarative/fx/qfxrepeater.cpp b/src/declarative/fx/qfxrepeater.cpp index 182dcc7..94954e7 100644 --- a/src/declarative/fx/qfxrepeater.cpp +++ b/src/declarative/fx/qfxrepeater.cpp @@ -72,10 +72,18 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Repeater,QFxRepeater) The model may be either an object list, a string list, a number or a Qt model. In each case, the data element and the index is exposed to each instantiated - component. The index is always exposed as an accessible \c index property. + component. + + The index is always exposed as an accessible \c index property. In the case of an object or string list, the data element (of type string or object) is available as the \c modelData property. In the case of a Qt model, - all roles are available as named properties just like in the view classes. + all roles are available as named properties just like in the view classes. The + following example shows how to use the index property inside the instantiated + items. + + \snippet doc/src/snippets/declarative/repeater-index.qml 0 + + \image repeater-index.png Items instantiated by the Repeater are inserted, in order, as children of the Repeater's parent. The insertion starts immediately after -- cgit v0.12 From c402509ea06a976a2a8ca671bec73f2fa3bd08f8 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 28 Oct 2009 11:58:38 +1000 Subject: Dynamic example now has more droppable Items The example is nearly done, just needs a little more aesthetic transfiguration. Also this commit introduces some generic components that could be easily used to make a game like ktuberling. --- examples/declarative/dynamic/GenericItem.qml | 13 ++++ examples/declarative/dynamic/PaletteItem.qml | 13 ++++ examples/declarative/dynamic/Sun.qml | 4 +- examples/declarative/dynamic/dynamic.qml | 69 +++++++++--------- examples/declarative/dynamic/images/NOTE | 1 + examples/declarative/dynamic/images/moon.png | Bin 0 -> 1757 bytes .../declarative/dynamic/images/rabbit_brown.png | Bin 0 -> 1245 bytes examples/declarative/dynamic/images/rabbit_bw.png | Bin 0 -> 1759 bytes examples/declarative/dynamic/images/tree_s.png | Bin 0 -> 3406 bytes examples/declarative/dynamic/itemCreation.js | 81 +++++++++++++++++++++ examples/declarative/dynamic/sunCreation.js | 69 ------------------ 11 files changed, 145 insertions(+), 105 deletions(-) create mode 100644 examples/declarative/dynamic/GenericItem.qml create mode 100644 examples/declarative/dynamic/PaletteItem.qml create mode 100644 examples/declarative/dynamic/images/NOTE create mode 100644 examples/declarative/dynamic/images/moon.png create mode 100644 examples/declarative/dynamic/images/rabbit_brown.png create mode 100644 examples/declarative/dynamic/images/rabbit_bw.png create mode 100644 examples/declarative/dynamic/images/tree_s.png create mode 100644 examples/declarative/dynamic/itemCreation.js delete mode 100644 examples/declarative/dynamic/sunCreation.js diff --git a/examples/declarative/dynamic/GenericItem.qml b/examples/declarative/dynamic/GenericItem.qml new file mode 100644 index 0000000..10e3dba --- /dev/null +++ b/examples/declarative/dynamic/GenericItem.qml @@ -0,0 +1,13 @@ +import Qt 4.6 + +Item{ + property bool created: false + property string image + width: imageItem.width + height: imageItem.height + z: 2 + Image{ + id: imageItem + source: image; + } +} diff --git a/examples/declarative/dynamic/PaletteItem.qml b/examples/declarative/dynamic/PaletteItem.qml new file mode 100644 index 0000000..bb6036d --- /dev/null +++ b/examples/declarative/dynamic/PaletteItem.qml @@ -0,0 +1,13 @@ +import Qt 4.6 + +GenericItem { + id: itemButton + property string file + Script { source: "itemCreation.js" } + MouseRegion { + anchors.fill: parent; + onPressed: startDrag(mouse); + onPositionChanged: moveDrag(mouse); + onReleased: endDrag(mouse); + } +} diff --git a/examples/declarative/dynamic/Sun.qml b/examples/declarative/dynamic/Sun.qml index 16d9907..a9f5d40 100644 --- a/examples/declarative/dynamic/Sun.qml +++ b/examples/declarative/dynamic/Sun.qml @@ -3,9 +3,11 @@ import Qt 4.6 Image { id: sun property bool created: false + property string image: "images/sun.png" onCreatedChanged: if(created){window.activeSuns++;}else{window.activeSuns--;} - source: "images/sun.png"; + source: image; + z: 1 //x and y get set when instantiated //head offscreen diff --git a/examples/declarative/dynamic/dynamic.qml b/examples/declarative/dynamic/dynamic.qml index aea9b0f..e6c3812 100644 --- a/examples/declarative/dynamic/dynamic.qml +++ b/examples/declarative/dynamic/dynamic.qml @@ -2,8 +2,8 @@ import Qt 4.6 Item { id: window - //This is a desktop example - width: 1024; height: 480 + //This is a desktop-sized example + width: 1024; height: 512 property int activeSuns: 0 // sky @@ -33,6 +33,7 @@ Item { } } + //Day state, for when you place a sun states: State { name: "Day"; when: window.activeSuns > 0 PropertyChanges { target: stopA; color: "DeepSkyBlue"} PropertyChanges { target: stopB; color: "SkyBlue"} @@ -55,50 +56,48 @@ Item { Column{ id: toolboxPositioner anchors.centerIn: parent - spacing: 1 - Sun { - id: sunButton - Script { source: "sunCreation.js" } - MouseRegion { - anchors.fill: parent; - onPressed: startDrag(mouse); - onPositionChanged: moveDrag(mouse); - onReleased: endDrag(mouse); + spacing: 4 + Text{ text: "Drag an item into the scene." } + Row{ spacing: 4; + height: childrenRect.height//TODO: Put bug in JIRA when it comes back up + PaletteItem{ + anchors.verticalCenter: parent.verticalCenter + file: "Sun.qml"; + image: "images/sun.png" } - } - Text{ text: "Active Suns: " + activeSuns } - Rectangle { width: 440; height: 1; color: "black" } - Text{ text: "Arbitrary Javascript: " } - TextEdit { - id: jsText - width: 460 - height: 80 - readOnly: false - focusOnPress: true - - text: "window.activeSuns++;" - } - Rectangle { - width: 80 - height: 20 - color: "lightsteelblue" - Text{ anchors.centerIn: parent; text: "Execute" } - MouseRegion { - anchors.fill: parent; - onClicked: eval(jsText.text.toString()); + PaletteItem{ + anchors.verticalCenter: parent.verticalCenter + file: "GenericItem.qml" + image: "images/moon.png" + } + PaletteItem{ + anchors.verticalCenter: parent.verticalCenter + file: "GenericItem.qml" + image: "images/tree_s.png" + } + PaletteItem{ + anchors.verticalCenter: parent.verticalCenter + file: "GenericItem.qml" + image: "images/rabbit_brown.png" + } + PaletteItem{ + anchors.verticalCenter: parent.verticalCenter + file: "GenericItem.qml" + image: "images/rabbit_bw.png" } } - + Text{ text: "Active Suns: " + activeSuns } Rectangle { width: 440; height: 1; color: "black" } Text{ text: "Arbitrary QML: " } TextEdit { id: qmlText width: 460 - height: 180 + height: 220 readOnly: false focusOnPress: true + font.pixelSize: 16 - text: "import Qt 4.6\nImage { id: smile; x: 10; y: 10; \n source: 'images/face-smile.png';\n opacity: NumberAnimation{ \n running:true; to: 0; duration: 1500;\n }\n Component.onCompleted: smile.destroy(1500);\n}" + text: "import Qt 4.6\nImage { id: smile;\n x: 500*Math.random();\n y: 250*Math.random(); \n source: 'images/face-smile.png';\n opacity: NumberAnimation{ \n running:true; to: 0; duration: 1500;\n }\n Component.onCompleted: smile.destroy(1500);\n}" } Rectangle { width: 80 diff --git a/examples/declarative/dynamic/images/NOTE b/examples/declarative/dynamic/images/NOTE new file mode 100644 index 0000000..fcd87f9 --- /dev/null +++ b/examples/declarative/dynamic/images/NOTE @@ -0,0 +1 @@ +Images (except star.png) are from the KDE project. diff --git a/examples/declarative/dynamic/images/moon.png b/examples/declarative/dynamic/images/moon.png new file mode 100644 index 0000000..1c0d606 Binary files /dev/null and b/examples/declarative/dynamic/images/moon.png differ diff --git a/examples/declarative/dynamic/images/rabbit_brown.png b/examples/declarative/dynamic/images/rabbit_brown.png new file mode 100644 index 0000000..ebfdeed Binary files /dev/null and b/examples/declarative/dynamic/images/rabbit_brown.png differ diff --git a/examples/declarative/dynamic/images/rabbit_bw.png b/examples/declarative/dynamic/images/rabbit_bw.png new file mode 100644 index 0000000..7bff9b9 Binary files /dev/null and b/examples/declarative/dynamic/images/rabbit_bw.png differ diff --git a/examples/declarative/dynamic/images/tree_s.png b/examples/declarative/dynamic/images/tree_s.png new file mode 100644 index 0000000..6eac35a Binary files /dev/null and b/examples/declarative/dynamic/images/tree_s.png differ diff --git a/examples/declarative/dynamic/itemCreation.js b/examples/declarative/dynamic/itemCreation.js new file mode 100644 index 0000000..3c3123b --- /dev/null +++ b/examples/declarative/dynamic/itemCreation.js @@ -0,0 +1,81 @@ +var itemComponent = null; +var draggedItem = null; +var startingMouse; +var startingZ; +//Until QT-2385 is resolved we need to convert to scene coordinates manually +var xOffset; +var yOffset; +function setSceneOffset() +{ + xOffset = 0; + yOffset = 0; + var p = itemButton; + while(p != window){ + xOffset += p.x; + yOffset += p.y; + p = p.parent; + } +} + +function startDrag(mouse) +{ + setSceneOffset(); + startingMouse = mouse; + loadComponent(); +} + +//Creation is split into two functions due to an asyncronous wait while +//possible external files are loaded. + +function loadComponent() { + if (itemComponent != null) //Already loaded the component + createItem(); + + itemComponent = createComponent(itemButton.file); + if(itemComponent.isLoading){ + component.statusChanged.connect(finishCreation); + }else{//Depending on the content, it can be ready or error immediately + createItem(); + } +} + +function createItem() { + if (itemComponent.isReady && draggedItem == null) { + draggedItem = itemComponent.createObject(); + draggedItem.parent = window; + draggedItem.image = itemButton.image; + draggedItem.x = startingMouse.x + xOffset; + draggedItem.y = startingMouse.y + yOffset; + startingZ = draggedItem.z; + draggedItem.z = 4;//On top + } else if (itemComponent.isError) { + draggedItem = null; + print("error creating component"); + print(component.errorsString()); + } +} + +function moveDrag(mouse) +{ + if(draggedItem == null) + return; + + draggedItem.x = mouse.x + xOffset; + draggedItem.y = mouse.y + yOffset; +} + +function endDrag(mouse) +{ + if(draggedItem == null) + return; + + if(draggedItem.x + draggedItem.width > toolbox.x){ //Don't drop it in the toolbox + draggedItem.destroy(); + draggedItem = null; + }else{ + draggedItem.z = startingZ; + draggedItem.created = true; + draggedItem = null; + } +} + diff --git a/examples/declarative/dynamic/sunCreation.js b/examples/declarative/dynamic/sunCreation.js deleted file mode 100644 index d9e5dce..0000000 --- a/examples/declarative/dynamic/sunCreation.js +++ /dev/null @@ -1,69 +0,0 @@ -var sunComponent = null; -var draggedItem = null; -var startingMouse; -//Until QT-2385 is resolved we need to convert to scene coordinates manually -var xOffset; -var yOffset; - -function startDrag(mouse) -{ - xOffset = toolbox.x + toolboxPositioner.x; - yOffset = toolbox.y + toolboxPositioner.y; - startingMouse = mouse; - loadComponent(); -} - -//Creation is split into two functions due to an asyncronous wait while -//possible external files are loaded. - -function loadComponent() { - if (sunComponent != null) //Already loaded the component - createSun(); - - sunComponent = createComponent("Sun.qml"); - if(sunComponent.isLoading){ - component.statusChanged.connect(finishCreation); - }else{//Depending on the content, it can be ready or error immediately - createSun(); - } -} - -function createSun() { - if (sunComponent.isReady && draggedItem == null) { - draggedItem = sunComponent.createObject(); - draggedItem.parent = window; - draggedItem.x = startingMouse.x + xOffset; - draggedItem.y = startingMouse.y + yOffset; - draggedItem.z = 4;//On top - } else if (sunComponent.isError) { - draggedItem = null; - print("error creating component"); - print(component.errorsString()); - } -} - -function moveDrag(mouse) -{ - if(draggedItem == null) - return; - - draggedItem.x = mouse.x + xOffset; - draggedItem.y = mouse.y + yOffset; -} - -function endDrag(mouse) -{ - if(draggedItem == null) - return; - - if(draggedItem.x + draggedItem.width > toolbox.x //Don't drop it in the toolbox - || draggedItem.y > ground.y){//Don't drop it on the ground - draggedItem.destroy(); - draggedItem = null; - }else{ - draggedItem.z = 1; - draggedItem.created = true; - draggedItem = null; - } -} - -- cgit v0.12 From c3663202dade896078d3466fccdcbac11909f2ba Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 28 Oct 2009 12:04:53 +1000 Subject: Better dragging of items for dynamic example The mouse is no longer at 0,0 of dragged item, but rather at the same point as the original click. --- examples/declarative/dynamic/itemCreation.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/declarative/dynamic/itemCreation.js b/examples/declarative/dynamic/itemCreation.js index 3c3123b..06e67c5 100644 --- a/examples/declarative/dynamic/itemCreation.js +++ b/examples/declarative/dynamic/itemCreation.js @@ -20,7 +20,7 @@ function setSceneOffset() function startDrag(mouse) { setSceneOffset(); - startingMouse = mouse; + startingMouse = { x: mouse.x, y: mouse.y } loadComponent(); } @@ -44,8 +44,8 @@ function createItem() { draggedItem = itemComponent.createObject(); draggedItem.parent = window; draggedItem.image = itemButton.image; - draggedItem.x = startingMouse.x + xOffset; - draggedItem.y = startingMouse.y + yOffset; + draggedItem.x = xOffset; + draggedItem.y = yOffset; startingZ = draggedItem.z; draggedItem.z = 4;//On top } else if (itemComponent.isError) { @@ -60,8 +60,8 @@ function moveDrag(mouse) if(draggedItem == null) return; - draggedItem.x = mouse.x + xOffset; - draggedItem.y = mouse.y + yOffset; + draggedItem.x = mouse.x + xOffset - startingMouse.x; + draggedItem.y = mouse.y + yOffset - startingMouse.y; } function endDrag(mouse) -- cgit v0.12 From 6b089607ab4ad3b2f3f0b0b95166458f59d504f8 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 28 Oct 2009 13:15:34 +1000 Subject: dynamic example now meets minimum aesthetic requirements Task-number: QT-2270 Reviewed-by: Yann Bodson --- examples/declarative/dynamic/Button.qml | 24 ++++++++++++++++++++++++ examples/declarative/dynamic/dynamic.qml | 31 +++++++++++++++++-------------- 2 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 examples/declarative/dynamic/Button.qml diff --git a/examples/declarative/dynamic/Button.qml b/examples/declarative/dynamic/Button.qml new file mode 100644 index 0000000..0b8b6db --- /dev/null +++ b/examples/declarative/dynamic/Button.qml @@ -0,0 +1,24 @@ +import Qt 4.6 + +Rectangle { + id: container + + property var text + signal clicked + + SystemPalette { id: activePalette; colorGroup: Qt.Active } + height: text.height + 10 + width: text.width + 20 + border.width: 1 + radius: 4 + gradient: Gradient { + GradientStop { position: 0.0; + color: if(!mr.pressed){activePalette.light;}else{activePalette.button;} + } + GradientStop { position: 1.0; + color: if(!mr.pressed){activePalette.button;}else{activePalette.dark;} + } + } + MouseRegion { id:mr; anchors.fill: parent; onClicked: container.clicked() } + Text { id: text; anchors.centerIn:parent; font.pointSize: 10; text: parent.text; color: activePalette.buttonText } +} diff --git a/examples/declarative/dynamic/dynamic.qml b/examples/declarative/dynamic/dynamic.qml index e6c3812..e083a5b 100644 --- a/examples/declarative/dynamic/dynamic.qml +++ b/examples/declarative/dynamic/dynamic.qml @@ -45,20 +45,29 @@ Item { ColorAnimation { duration: 3000 } } - //TODO: Below feature needs beautification to meet minimum standards + SystemPalette { id: activePalette; colorGroup: Qt.Active } + // toolbox Rectangle { id: toolbox z: 3 //Above ground - color: "white" + color: activePalette.window; width: 480 anchors { right: parent.right; top:parent.top; bottom: parent.bottom } + Rectangle { //Not a child of any positioner + color: "white"; border.color: "black"; + width: toolRow.width + 4 + height: toolRow.height + 4 + x: toolboxPositioner.x + toolRow.x - 2 + y: toolboxPositioner.y + toolRow.y - 2 + } Column{ id: toolboxPositioner anchors.centerIn: parent - spacing: 4 + spacing: 8 Text{ text: "Drag an item into the scene." } - Row{ spacing: 4; + Row{ id: toolRow + spacing: 8; height: childrenRect.height//TODO: Put bug in JIRA when it comes back up PaletteItem{ anchors.verticalCenter: parent.verticalCenter @@ -97,17 +106,11 @@ Item { focusOnPress: true font.pixelSize: 16 - text: "import Qt 4.6\nImage { id: smile;\n x: 500*Math.random();\n y: 250*Math.random(); \n source: 'images/face-smile.png';\n opacity: NumberAnimation{ \n running:true; to: 0; duration: 1500;\n }\n Component.onCompleted: smile.destroy(1500);\n}" + text: "import Qt 4.6\nImage { id: smile;\n x: 500*Math.random();\n y: 200*Math.random(); \n source: 'images/face-smile.png';\n opacity: NumberAnimation{ \n running:true; to: 0; duration: 1500;\n }\n Component.onCompleted: smile.destroy(1500);\n}" } - Rectangle { - width: 80 - height: 20 - color: "lightsteelblue" - Text{ anchors.centerIn: parent; text: "Create" } - MouseRegion { - anchors.fill: parent; - onClicked: {var obj=createQmlObject(qmlText.text, window, 'CustomObject'); obj.parent=window;} - } + Button { + text: "Create" + onClicked: {var obj=createQmlObject(qmlText.text, window, 'CustomObject'); obj.parent=window;} } } } -- cgit v0.12 From fc733f4573f1fe43e0cfe43734623d77f61a4614 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 28 Oct 2009 13:20:15 +1000 Subject: Ensure that the Follows handle the target value changing unexpectedly. If the target's property was changed elsewhere while the Follow wasn't running, it would fail to start when a source identical to its current source valule was set. --- src/declarative/util/qmleasefollow.cpp | 3 +-- src/declarative/util/qmlspringfollow.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/declarative/util/qmleasefollow.cpp b/src/declarative/util/qmleasefollow.cpp index 99720f8..9d17d25 100644 --- a/src/declarative/util/qmleasefollow.cpp +++ b/src/declarative/util/qmleasefollow.cpp @@ -210,7 +210,6 @@ void QmlEaseFollowPrivate::tick(int t) qreal value = 0.5 * a * time_seconds * time_seconds + vi * time_seconds; value = (invert?-1.0:1.0) * value; target.write(initialValue + value); - out = initialValue + value; } else if (time_seconds < td) { @@ -397,7 +396,7 @@ void QmlEaseFollow::setSourceValue(qreal s) { Q_D(QmlEaseFollow); - if (d->source == s) + if (d->clock.state() == QAbstractAnimation::Running && d->source == s) return; d->source = s; diff --git a/src/declarative/util/qmlspringfollow.cpp b/src/declarative/util/qmlspringfollow.cpp index 34ec976..569cc48 100644 --- a/src/declarative/util/qmlspringfollow.cpp +++ b/src/declarative/util/qmlspringfollow.cpp @@ -272,10 +272,11 @@ qreal QmlSpringFollow::sourceValue() const void QmlSpringFollow::setSourceValue(qreal value) { Q_D(QmlSpringFollow); - if (d->sourceValue != value) { - d->sourceValue = value; - d->start(); - } + if (d->clock.state() == QAbstractAnimation::Running && d->sourceValue == value) + return; + + d->sourceValue = value; + d->start(); } /*! -- cgit v0.12 From 486eb1ccb91e239bf4440ec62c221e8af1ffddcc Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 28 Oct 2009 13:23:00 +1000 Subject: Mode improvement to strictly enforced highlight range movement. --- examples/declarative/listview/listview.qml | 1 + examples/declarative/parallax/ParallaxView.qml | 3 +- src/declarative/fx/qfxflickable.cpp | 26 ++++++--- src/declarative/fx/qfxlistview.cpp | 80 ++++++++++++++++++++++---- 4 files changed, 92 insertions(+), 18 deletions(-) diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview.qml index b614904..92acce1 100644 --- a/examples/declarative/listview/listview.qml +++ b/examples/declarative/listview/listview.qml @@ -72,5 +72,6 @@ Rectangle { preferredHighlightBegin: 125 preferredHighlightEnd: 125 highlightRangeMode: "StrictlyEnforceRange" + flickDeceleration: 1000 } } diff --git a/examples/declarative/parallax/ParallaxView.qml b/examples/declarative/parallax/ParallaxView.qml index bad9b85..50ab72c 100644 --- a/examples/declarative/parallax/ParallaxView.qml +++ b/examples/declarative/parallax/ParallaxView.qml @@ -25,7 +25,8 @@ Item { anchors.fill: parent model: VisualItemModel { id: visualModel } - highlight: Item { height: 1; width: 1} + highlight: Rectangle { height: 1; width: 1 } + highlightMoveSpeed: 2000 preferredHighlightBegin: 0 preferredHighlightEnd: 0 highlightRangeMode: "StrictlyEnforceRange" diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 92e79dd..659193d 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE static const int DragThreshold = 8; static const int FlickThreshold = 20; +// Really slow flicks can be annoying. +static const int minimumFlickVelocity = 200; class QFxFlickableVisibleArea : public QObject { @@ -183,6 +185,8 @@ void QFxFlickablePrivate::flickX(qreal velocity) { Q_Q(QFxFlickable); qreal maxDistance = -1; + if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. + velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; // -ve velocity means list is moving up if (velocity > 0) { if (_moveX.value() < q->minXExtent()) @@ -686,8 +690,8 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (rejectX) velocityX = 0; if (moved) { - q->viewportMoved(); q->movementStarting(); + q->viewportMoved(); } lastPos = event->pos(); @@ -707,15 +711,23 @@ void QFxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *even } vTime = timeline.time(); - if (qAbs(velocityY) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) - flickY(velocityY); - else + if (qAbs(velocityY) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) { + qreal velocity = velocityY; + if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. + velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; + flickY(velocity); + } else { fixupY(); + } - if (qAbs(velocityX) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) - flickX(velocityX); - else + if (qAbs(velocityX) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) { + qreal velocity = velocityX; + if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. + velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; + flickX(velocity); + } else { fixupX(); + } stealMouse = false; lastPosTime = QTime(); diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index fbb91b1..e970ddd 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -691,8 +691,7 @@ void QFxListViewPrivate::updateHighlight() { if ((!currentItem && highlight) || (currentItem && !highlight)) createHighlight(); - updateTrackedItem(); - if (currentItem && autoHighlight && highlight && !pressed && moveReason != QFxListViewPrivate::Mouse) { + if (currentItem && autoHighlight && highlight && !moving) { // auto-update highlight highlightPosAnimator->setSourceValue(currentItem->position()); highlightSizeAnimator->setSourceValue(currentItem->size()); @@ -704,6 +703,7 @@ void QFxListViewPrivate::updateHighlight() highlight->item->setHeight(currentItem->item->height()); } } + updateTrackedItem(); } void QFxListViewPrivate::updateSections() @@ -832,8 +832,10 @@ void QFxListViewPrivate::flickX(qreal velocity) { Q_Q(QFxListView); - if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange) + if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange) { QFxFlickablePrivate::flickX(velocity); + return; + } qreal maxDistance = -1; // -ve velocity means list is moving up @@ -855,19 +857,20 @@ void QFxListViewPrivate::flickX(qreal velocity) v = maxVelocity; } qreal accel = deceleration; - qreal maxAccel = (v * v) / (2.0f * maxDistance); + qreal v2 = v * v; + qreal maxAccel = v2 / (2.0f * maxDistance); if (maxAccel < accel) { // If we are not flicking to the end then attempt to stop exactly on an item boundary - qreal dist = (v * v) / accel / 2.0; + qreal dist = v2 / accel / 2.0; if (v > 0) dist = -dist; - dist = -_moveX.value() - snapPosAt(-_moveX.value() + dist + highlightRangeStart); + dist = -_moveX.value() - snapPosAt(-(_moveX.value() - highlightRangeStart) + dist) + highlightRangeStart; if (v < 0 && dist >= 0 || v > 0 && dist <= 0) { timeline.reset(_moveX); fixupX(); return; } - accel = (v * v) / (2.0f * qAbs(dist)); + accel = v2 / (2.0f * qAbs(dist)); } timeline.reset(_moveX); timeline.accel(_moveX, v, accel, maxDistance); @@ -885,7 +888,60 @@ void QFxListViewPrivate::flickX(qreal velocity) void QFxListViewPrivate::flickY(qreal velocity) { - QFxFlickablePrivate::flickY(velocity); + Q_Q(QFxListView); + + if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange) { + QFxFlickablePrivate::flickY(velocity); + return; + } + + qreal maxDistance = -1; + // -ve velocity means list is moving up + if (velocity > 0) { + if (_moveY.value() < q->minYExtent()) + maxDistance = qAbs(q->minYExtent() -_moveY.value() + (overShoot?30:0)); + flickTargetY = q->minYExtent(); + } else { + if (_moveY.value() > q->maxYExtent()) + maxDistance = qAbs(q->maxYExtent() - _moveY.value()) + (overShoot?30:0); + flickTargetY = q->maxYExtent(); + } + if (maxDistance > 0) { + qreal v = velocity; + if (maxVelocity != -1 && maxVelocity < qAbs(v)) { + if (v < 0) + v = -maxVelocity; + else + v = maxVelocity; + } + qreal accel = deceleration; + qreal v2 = v * v; + qreal maxAccel = v2 / (2.0f * maxDistance); + if (maxAccel < accel) { + // If we are not flicking to the end then attempt to stop exactly on an item boundary + qreal dist = v2 / accel / 2.0; + if (v > 0) + dist = -dist; + dist = -_moveY.value() - snapPosAt(-(_moveY.value() - highlightRangeStart) + dist) + highlightRangeStart; + if (v < 0 && dist >= 0 || v > 0 && dist <= 0) { + timeline.reset(_moveY); + fixupY(); + return; + } + accel = v2 / (2.0f * qAbs(dist)); + } + timeline.reset(_moveY); + timeline.accel(_moveY, v, accel, maxDistance); + timeline.execute(fixupYEvent); + if (!flicked) { + flicked = true; + emit q->flickingChanged(); + emit q->flickStarted(); + } + } else { + timeline.reset(_moveY); + fixupY(); + } } //---------------------------------------------------------------------------- @@ -1185,6 +1241,10 @@ void QFxListView::setHighlight(QmlComponent *highlight) \snippet doc/src/snippets/declarative/listview/highlight.qml 1 + Note that the highlight animation also affects the way that the view + is scrolled. This is because the view moves to maintain the + highlight within the preferred highlight range (or visible viewport). + \sa highlight */ bool QFxListView::highlightFollowsCurrentItem() const @@ -1445,7 +1505,7 @@ void QFxListView::viewportMoved() Q_D(QFxListView); QFxFlickable::viewportMoved(); refill(); - if (isFlicking() || d->pressed) + if (isFlicking() || d->moving) d->moveReason = QFxListViewPrivate::Mouse; if (d->moveReason == QFxListViewPrivate::Mouse) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { @@ -1606,7 +1666,7 @@ void QFxListView::trackedPositionChanged() Q_D(QFxListView); if (!d->trackedItem) return; - if (!isFlicking() && !d->pressed && d->moveReason != QFxListViewPrivate::Mouse) { + if (!isFlicking() && !d->moving && d->moveReason != QFxListViewPrivate::Mouse) { const qreal trackedPos = d->trackedItem->position(); if (d->haveHighlightRange) { if (d->highlightRange == StrictlyEnforceRange) { -- cgit v0.12 From 84bc6c6f25c88a84455dfb74e23a8a7e5b9493a5 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 28 Oct 2009 13:30:10 +1000 Subject: QT-2382 --- examples/declarative/listview/itemlist.qml | 2 +- src/declarative/fx/qfxlistview.cpp | 72 +++++++++++++++--------------- src/declarative/fx/qfxlistview.h | 8 ++-- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/examples/declarative/listview/itemlist.qml b/examples/declarative/listview/itemlist.qml index 77f5c2d..6ce4287 100644 --- a/examples/declarative/listview/itemlist.qml +++ b/examples/declarative/listview/itemlist.qml @@ -32,7 +32,7 @@ Rectangle { preferredHighlightBegin: 0 preferredHighlightEnd: 0 highlightRangeMode: "StrictlyEnforceRange" - orientation: "Horizontal" + orientation: ListView.Horizontal } Rectangle { diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index fbb91b1..18aa5d2 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -141,15 +141,15 @@ public: } ~FxListItem() {} - qreal position() const { return (view->orientation() == Qt::Vertical ? item->y() : item->x()); } - int size() const { return (view->orientation() == Qt::Vertical ? item->height() : item->width()); } + qreal position() const { return (view->orientation() == QFxListView::Vertical ? item->y() : item->x()); } + int size() const { return (view->orientation() == QFxListView::Vertical ? item->height() : item->width()); } qreal endPosition() const { - return (view->orientation() == Qt::Vertical + return (view->orientation() == QFxListView::Vertical ? item->y() + (item->height() > 0 ? item->height() : 1) : item->x() + (item->width() > 0 ? item->width() : 1)) - 1; } void setPosition(qreal pos) { - if (view->orientation() == Qt::Vertical) { + if (view->orientation() == QFxListView::Vertical) { item->setY(pos); } else { item->setX(pos); @@ -170,7 +170,7 @@ class QFxListViewPrivate : public QFxFlickablePrivate public: QFxListViewPrivate() - : model(0), currentItem(0), orient(Qt::Vertical) + : model(0), currentItem(0), orient(QFxListView::Vertical) , visiblePos(0), visibleIndex(0) , averageSize(100.0), currentIndex(-1), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0) @@ -199,18 +199,18 @@ public: qreal position() const { Q_Q(const QFxListView); - return orient == Qt::Vertical ? q->viewportY() : q->viewportX(); + return orient == QFxListView::Vertical ? q->viewportY() : q->viewportX(); } void setPosition(qreal pos) { Q_Q(QFxListView); - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) q->setViewportY(pos); else q->setViewportX(pos); } qreal size() const { Q_Q(const QFxListView); - return orient == Qt::Vertical ? q->height() : q->width(); + return orient == QFxListView::Vertical ? q->height() : q->width(); } qreal startPosition() const { @@ -378,7 +378,7 @@ public: QList visibleItems; QHash unrequestedItems; FxListItem *currentItem; - Qt::Orientation orient; + QFxListView::Orientation orient; int visiblePos; int visibleIndex; qreal averageSize; @@ -454,7 +454,7 @@ FxListItem *QFxListViewPrivate::createItem(int modelIndex) model->completeItem(); listItem->item->setZValue(1); listItem->item->setParent(q->viewport()); - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) QObject::connect(listItem->item, SIGNAL(heightChanged()), q, SLOT(itemResized())); else QObject::connect(listItem->item, SIGNAL(widthChanged()), q, SLOT(itemResized())); @@ -470,8 +470,8 @@ void QFxListViewPrivate::releaseItem(FxListItem *item) if (!item) return; if (trackedItem == item) { - const char *notifier1 = orient == Qt::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); - const char *notifier2 = orient == Qt::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); + const char *notifier1 = orient == QFxListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); + const char *notifier2 = orient == QFxListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged())); QObject::disconnect(trackedItem->item, notifier2, q, SLOT(trackedPositionChanged())); trackedItem = 0; @@ -479,7 +479,7 @@ void QFxListViewPrivate::releaseItem(FxListItem *item) if (model->release(item->item) == 0) { // item was not destroyed, and we no longer reference it. unrequestedItems.insert(item->item, model->indexOf(item->item, q)); - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) QObject::disconnect(item->item, SIGNAL(heightChanged()), q, SLOT(itemResized())); else QObject::disconnect(item->item, SIGNAL(widthChanged()), q, SLOT(itemResized())); @@ -553,7 +553,7 @@ void QFxListViewPrivate::refill(qreal from, qreal to) updateAverage(); if (!sectionExpression.isEmpty()) updateCurrentSection(); - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) q->setViewportHeight(endPosition() - startPosition()); else q->setViewportWidth(endPosition() - startPosition()); @@ -597,7 +597,7 @@ void QFxListViewPrivate::updateUnrequestedPositions() for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) { if (visibleItem(*it)) continue; - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) it.key()->setY(positionAt(*it)); else it.key()->setX(positionAt(*it)); @@ -613,8 +613,8 @@ void QFxListViewPrivate::updateTrackedItem() FxListItem *oldTracked = trackedItem; - const char *notifier1 = orient == Qt::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); - const char *notifier2 = orient == Qt::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); + const char *notifier1 = orient == QFxListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); + const char *notifier2 = orient == QFxListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged()); if (trackedItem && item != trackedItem) { QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged())); @@ -669,16 +669,16 @@ void QFxListViewPrivate::createHighlight() if (item) { item->setZValue(0); highlight = new FxListItem(item, q); - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) highlight->item->setHeight(currentItem->item->height()); else highlight->item->setWidth(currentItem->item->width()); - const QLatin1String posProp(orient == Qt::Vertical ? "y" : "x"); + const QLatin1String posProp(orient == QFxListView::Vertical ? "y" : "x"); highlightPosAnimator = new QmlEaseFollow(q); highlightPosAnimator->setTarget(QmlMetaProperty(highlight->item, posProp)); highlightPosAnimator->setVelocity(highlightMoveSpeed); highlightPosAnimator->setEnabled(autoHighlight); - const QLatin1String sizeProp(orient == Qt::Vertical ? "height" : "width"); + const QLatin1String sizeProp(orient == QFxListView::Vertical ? "height" : "width"); highlightSizeAnimator = new QmlEaseFollow(q); highlightSizeAnimator->setVelocity(highlightResizeSpeed); highlightSizeAnimator->setTarget(QmlMetaProperty(highlight->item, sizeProp)); @@ -696,7 +696,7 @@ void QFxListViewPrivate::updateHighlight() // auto-update highlight highlightPosAnimator->setSourceValue(currentItem->position()); highlightSizeAnimator->setSourceValue(currentItem->size()); - if (orient == Qt::Vertical) { + if (orient == QFxListView::Vertical) { if (highlight->item->width() == 0) highlight->item->setWidth(currentItem->item->width()); } else { @@ -792,7 +792,7 @@ void QFxListViewPrivate::updateAverage() void QFxListViewPrivate::fixupPosition() { - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) fixupY(); else fixupX(); @@ -801,7 +801,7 @@ void QFxListViewPrivate::fixupPosition() void QFxListViewPrivate::fixupY() { QFxFlickablePrivate::fixupY(); - if (orient == Qt::Horizontal) + if (orient == QFxListView::Horizontal) return; if (haveHighlightRange && highlightRange == QFxListView::StrictlyEnforceRange) { @@ -816,7 +816,7 @@ void QFxListViewPrivate::fixupY() void QFxListViewPrivate::fixupX() { QFxFlickablePrivate::fixupX(); - if (orient == Qt::Vertical) + if (orient == QFxListView::Vertical) return; if (haveHighlightRange && highlightRange == QFxListView::StrictlyEnforceRange) { @@ -1298,18 +1298,18 @@ void QFxListView::setSpacing(qreal spacing) Horizontal Example: \image ListViewHorizontal.png */ -Qt::Orientation QFxListView::orientation() const +QFxListView::Orientation QFxListView::orientation() const { Q_D(const QFxListView); return d->orient; } -void QFxListView::setOrientation(Qt::Orientation orientation) +void QFxListView::setOrientation(QFxListView::Orientation orientation) { Q_D(QFxListView); if (d->orient != orientation) { d->orient = orientation; - if (d->orient == Qt::Vertical) + if (d->orient == QFxListView::Vertical) setViewportWidth(-1); else setViewportHeight(-1); @@ -1466,7 +1466,7 @@ void QFxListView::viewportMoved() qreal QFxListView::minYExtent() const { Q_D(const QFxListView); - if (d->orient == Qt::Horizontal) + if (d->orient == QFxListView::Horizontal) return QFxFlickable::minYExtent(); qreal extent = -d->startPosition(); if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) @@ -1478,7 +1478,7 @@ qreal QFxListView::minYExtent() const qreal QFxListView::maxYExtent() const { Q_D(const QFxListView); - if (d->orient == Qt::Horizontal) + if (d->orient == QFxListView::Horizontal) return QFxFlickable::maxYExtent(); qreal extent; if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) @@ -1494,7 +1494,7 @@ qreal QFxListView::maxYExtent() const qreal QFxListView::minXExtent() const { Q_D(const QFxListView); - if (d->orient == Qt::Vertical) + if (d->orient == QFxListView::Vertical) return QFxFlickable::minXExtent(); qreal extent = -d->startPosition(); if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) @@ -1506,7 +1506,7 @@ qreal QFxListView::minXExtent() const qreal QFxListView::maxXExtent() const { Q_D(const QFxListView); - if (d->orient == Qt::Vertical) + if (d->orient == QFxListView::Vertical) return QFxFlickable::maxXExtent(); qreal extent; if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) @@ -1527,8 +1527,8 @@ void QFxListView::keyPressEvent(QKeyEvent *event) return; if (d->model && d->model->count() && d->interactive) { - if ((d->orient == Qt::Horizontal && event->key() == Qt::Key_Left) - || (d->orient == Qt::Vertical && event->key() == Qt::Key_Up)) { + if ((d->orient == QFxListView::Horizontal && event->key() == Qt::Key_Left) + || (d->orient == QFxListView::Vertical && event->key() == Qt::Key_Up)) { if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) { d->moveReason = QFxListViewPrivate::Key; decrementCurrentIndex(); @@ -1538,8 +1538,8 @@ void QFxListView::keyPressEvent(QKeyEvent *event) event->accept(); return; } - } else if ((d->orient == Qt::Horizontal && event->key() == Qt::Key_Right) - || (d->orient == Qt::Vertical && event->key() == Qt::Key_Down)) { + } else if ((d->orient == QFxListView::Horizontal && event->key() == Qt::Key_Right) + || (d->orient == QFxListView::Vertical && event->key() == Qt::Key_Down)) { if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) { d->moveReason = QFxListViewPrivate::Key; incrementCurrentIndex(); @@ -1930,7 +1930,7 @@ void QFxListView::createdItem(int index, QFxItem *item) if (d->requestedIndex != index) { item->setParentItem(viewport()); d->unrequestedItems.insert(item, index); - if (d->orient == Qt::Vertical) + if (d->orient == QFxListView::Vertical) item->setY(d->positionAt(index)); else item->setX(d->positionAt(index)); diff --git a/src/declarative/fx/qfxlistview.h b/src/declarative/fx/qfxlistview.h index 0fa0fa0..b31b951 100644 --- a/src/declarative/fx/qfxlistview.h +++ b/src/declarative/fx/qfxlistview.h @@ -72,7 +72,7 @@ class Q_DECLARATIVE_EXPORT QFxListView : public QFxFlickable Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode) Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) - Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged) + Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged) Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled) Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer) Q_PROPERTY(QString sectionExpression READ sectionExpression WRITE setSectionExpression NOTIFY sectionExpressionChanged) @@ -81,6 +81,7 @@ class Q_DECLARATIVE_EXPORT QFxListView : public QFxFlickable Q_PROPERTY(qreal highlightMoveSpeed READ highlightMoveSpeed WRITE setHighlightMoveSpeed NOTIFY highlightMoveSpeedChanged) Q_PROPERTY(qreal highlightResizeSpeed READ highlightResizeSpeed WRITE setHighlightResizeSpeed NOTIFY highlightResizeSpeedChanged) Q_ENUMS(HighlightRangeMode) + Q_ENUMS(Orientation) Q_CLASSINFO("DefaultProperty", "data") public: @@ -118,8 +119,9 @@ public: qreal spacing() const; void setSpacing(qreal spacing); - Qt::Orientation orientation() const; - void setOrientation(Qt::Orientation); + enum Orientation { Horizontal = Qt::Horizontal, Vertical = Qt::Vertical }; + Orientation orientation() const; + void setOrientation(Orientation); bool isWrapEnabled() const; void setWrapEnabled(bool); -- cgit v0.12 From eaab2a271f0d73d5a413902169efe32741208c42 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 13:59:33 +1000 Subject: Add a QmlExpression::error() method QmlExpression should not print errors itself. This is the responsibility of the caller. --- src/declarative/qml/qmlbinding.cpp | 8 +++-- src/declarative/qml/qmlboundsignal.cpp | 5 +++- src/declarative/qml/qmlcontext.cpp | 7 +++-- src/declarative/qml/qmlerror.cpp | 42 +++++++++++++++++++------- src/declarative/qml/qmlerror.h | 2 ++ src/declarative/qml/qmlexpression.cpp | 55 +++++++++++++++++++++++++++++++--- src/declarative/qml/qmlexpression.h | 5 ++++ src/declarative/qml/qmlexpression_p.h | 4 ++- 8 files changed, 107 insertions(+), 21 deletions(-) diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index 65ff789..ab4343c 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -128,10 +128,12 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) idx, a); } else { - bool undefined = false; - QVariant value = this->value(&undefined); + bool isUndefined = false; + QVariant value = this->value(&isUndefined); - if (!undefined && data->property.object() && !data->property.write(value, flags)) { + if (this->hasError()) { + qWarning().nospace() << qPrintable(this->error().toString()); + } else if (!isUndefined && data->property.object() && !data->property.write(value, flags)) { QString fileName = data->fileName; int line = data->line; if (fileName.isEmpty()) fileName = QLatin1String(""); diff --git a/src/declarative/qml/qmlboundsignal.cpp b/src/declarative/qml/qmlboundsignal.cpp index ce591e8..d715309 100644 --- a/src/declarative/qml/qmlboundsignal.cpp +++ b/src/declarative/qml/qmlboundsignal.cpp @@ -175,8 +175,11 @@ int QmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a) { if (c == QMetaObject::InvokeMetaMethod && id == evaluateIdx) { if (m_params) m_params->setValues(a); - if (m_expression) + if (m_expression) { QmlExpressionPrivate::get(m_expression)->value(m_params); + if (m_expression->hasError()) + qWarning().nospace() << qPrintable(m_expression->error().toString()); + } if (m_params) m_params->clearValues(); return -1; } else { diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 2ebdf10..5032ff4 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -77,8 +77,11 @@ void QmlContextPrivate::addScript(const QString &script, QObject *scopeObject, QScriptValue val = scriptEngine->evaluate(script, fileName, lineNumber); - if (scriptEngine->hasUncaughtException()) - QmlExpressionPrivate::printException(scriptEngine); + if (scriptEngine->hasUncaughtException()) { + QmlError error; + QmlExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } scriptEngine->popContext(); diff --git a/src/declarative/qml/qmlerror.cpp b/src/declarative/qml/qmlerror.cpp index 514fe44..f4c9580 100644 --- a/src/declarative/qml/qmlerror.cpp +++ b/src/declarative/qml/qmlerror.cpp @@ -70,7 +70,7 @@ QmlErrorPrivate::QmlErrorPrivate() Create an empty error object. */ QmlError::QmlError() -: d(new QmlErrorPrivate) +: d(0) { } @@ -78,7 +78,7 @@ QmlError::QmlError() Create a copy of \a other. */ QmlError::QmlError(const QmlError &other) -: d(new QmlErrorPrivate) +: d(0) { *this = other; } @@ -88,10 +88,16 @@ QmlError::QmlError(const QmlError &other) */ QmlError &QmlError::operator=(const QmlError &other) { - d->url = other.d->url; - d->description = other.d->description; - d->line = other.d->line; - d->column = other.d->column; + if (!other.d) { + delete d; + d = 0; + } else { + if (!d) d = new QmlErrorPrivate; + d->url = other.d->url; + d->description = other.d->description; + d->line = other.d->line; + d->column = other.d->column; + } return *this; } @@ -104,11 +110,20 @@ QmlError::~QmlError() } /*! + Return true if this error is valid, otherwise false. +*/ +bool QmlError::isValid() const +{ + return d != 0; +} + +/*! Return the url for the file that caused this error. */ QUrl QmlError::url() const { - return d->url; + if (d) return d->url; + else return QUrl(); } /*! @@ -116,6 +131,7 @@ QUrl QmlError::url() const */ void QmlError::setUrl(const QUrl &url) { + if (!d) d = new QmlErrorPrivate; d->url = url; } @@ -124,7 +140,8 @@ void QmlError::setUrl(const QUrl &url) */ QString QmlError::description() const { - return d->description; + if (d) return d->description; + else return QString(); } /*! @@ -132,6 +149,7 @@ QString QmlError::description() const */ void QmlError::setDescription(const QString &description) { + if (!d) d = new QmlErrorPrivate; d->description = description; } @@ -140,7 +158,8 @@ void QmlError::setDescription(const QString &description) */ int QmlError::line() const { - return d->line; + if (d) return d->line; + else return -1; } /*! @@ -148,6 +167,7 @@ int QmlError::line() const */ void QmlError::setLine(int line) { + if (!d) d = new QmlErrorPrivate; d->line = line; } @@ -156,7 +176,8 @@ void QmlError::setLine(int line) */ int QmlError::column() const { - return d->column; + if (d) return d->column; + else return -1; } /*! @@ -164,6 +185,7 @@ int QmlError::column() const */ void QmlError::setColumn(int column) { + if (!d) d = new QmlErrorPrivate; d->column = column; } diff --git a/src/declarative/qml/qmlerror.h b/src/declarative/qml/qmlerror.h index c1a8720..ee3d7b4 100644 --- a/src/declarative/qml/qmlerror.h +++ b/src/declarative/qml/qmlerror.h @@ -61,6 +61,8 @@ public: QmlError &operator=(const QmlError &); ~QmlError(); + bool isValid() const; + QUrl url() const; void setUrl(const QUrl &); QString description() const; diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index c62756b..8231bf8 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -260,7 +260,8 @@ QVariant QmlExpressionPrivate::evalSSE() return rv; } -void QmlExpressionPrivate::printException(QScriptEngine *scriptEngine) +void QmlExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine, + QmlError &error) { if (scriptEngine->hasUncaughtException() && scriptEngine->uncaughtException().isError()) { @@ -277,8 +278,12 @@ void QmlExpressionPrivate::printException(QScriptEngine *scriptEngine) fileName = QLatin1String(""); } - qWarning().nospace() << qPrintable(fileName) << ":" << lineNumber << ": " - << qPrintable(exception.toString()); + error.setUrl(QUrl(fileName)); + error.setLine(lineNumber); + error.setColumn(-1); + error.setDescription(exception.toString()); + } else { + error = QmlError(); } } @@ -321,10 +326,13 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd if (isUndefined) *isUndefined = svalue.isUndefined() || scriptEngine->hasUncaughtException(); + // Handle exception if (scriptEngine->hasUncaughtException()) { - printException(scriptEngine); + exceptionToError(scriptEngine, data->error); scriptEngine->clearExceptions(); return QVariant(); + } else { + data->error = QmlError(); } if (secondaryScope) { @@ -418,6 +426,8 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) \a isUndefined is set to true if the expression resulted in an undefined value. + + \sa hasError(), error() */ QVariant QmlExpression::value(bool *isUndefined) { @@ -509,6 +519,43 @@ QObject *QmlExpression::scopeObject() const return d->data->me; } +/*! + Returns true if the last call to value() resulted in an error, + otherwise false. + + \sa error(), clearError() +*/ +bool QmlExpression::hasError() const +{ + Q_D(const QmlExpression); + return d->data->error.isValid(); +} + +/*! + Clear any expression errors. Calls to hasError() following this will + return false. + + \sa hasError(), error() +*/ +void QmlExpression::clearError() +{ + Q_D(QmlExpression); + d->data->error = QmlError(); +} + +/*! + Return any error from the last call to value(). If there was no error, + this returns an invalid QmlError instance. + + \sa hasError(), clearError() +*/ + +QmlError QmlExpression::error() const +{ + Q_D(const QmlExpression); + return d->data->error; +} + /*! \internal */ void QmlExpression::__q_notify() { diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 96694d6..127d3f3 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_HEADER @@ -82,6 +83,10 @@ public: QObject *scopeObject() const; + bool hasError() const; + void clearError(); + QmlError error() const; + public Q_SLOTS: QVariant value(bool *isUndefined = 0); diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h index 3ec8d1c..b453a96 100644 --- a/src/declarative/qml/qmlexpression_p.h +++ b/src/declarative/qml/qmlexpression_p.h @@ -92,6 +92,8 @@ public: bool expressionRewritten:1; QScriptValue expressionFunction; + QmlError error; + QmlBasicScript sse; QObject *me; bool trackChange; @@ -151,7 +153,7 @@ public: return static_cast(QObjectPrivate::get(expr)); } - static void printException(QScriptEngine *); + static void exceptionToError(QScriptEngine *, QmlError &); }; QT_END_NAMESPACE -- cgit v0.12 From 6be1b102d27610e7d4417222eb4b4dd80d453295 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 28 Oct 2009 14:21:53 +1000 Subject: Fix bug where repeater would add spacing for 0 sized children --- src/declarative/fx/qfxpositioners.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/declarative/fx/qfxpositioners.cpp b/src/declarative/fx/qfxpositioners.cpp index f8e7213..cc385e0 100644 --- a/src/declarative/fx/qfxpositioners.cpp +++ b/src/declarative/fx/qfxpositioners.cpp @@ -659,8 +659,10 @@ void QFxRow::doPositioning() child->setX(hoffset); setMovingItem(0); } - hoffset += child->width(); - hoffset += spacing(); + if(!child->width() || !child->height()){//don't advance for invisible children + hoffset += child->width(); + hoffset += spacing(); + } } } -- cgit v0.12 From 97fe32132f1e55fddca464404f06ab70d81c56d8 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 28 Oct 2009 14:24:19 +1000 Subject: Doc --- doc/src/declarative/globalobject.qdoc | 26 ++++++++++++++++++++++++++ src/declarative/fx/qfxitem.cpp | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index 2328c8a..afbe3db 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -56,6 +56,32 @@ Contains all the properties of the ECMAScript global object, plus: \section1 Qt Object +The Qt object contains functions for + +creating types: +\list +\o hsla +\o rgba +\o rect +\o point +\o size +\o vector3d +\endlist + +manipulating color: +\list +\o lighter +\o darker +\o tint +\endlist + +and playing sound: +\list +\o playSound +\endlist + +It also contains enum values used by some items. + \section1 Asynchronous JavaScript and XML \section1 Offline Storage API diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index e714494..7d60336 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -1199,7 +1199,7 @@ QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj) /*! \class QFxItem - \brief QFxItem is the most basic of all visual items in QML. + \brief The QFxItem class provides the most basic of all visual items in QML. All visual items in Qt Declarative inherit from QFxItem. Although QFxItem has no visual appearance, it defines all the properties that are -- cgit v0.12 From f6b063eeef71b4cb7c1cff090166201f794c9679 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 28 Oct 2009 14:52:48 +1000 Subject: make TextElideMode an enum of QFxText. --- src/declarative/fx/qfxtext.cpp | 22 +++++++++++----------- src/declarative/fx/qfxtext.h | 15 ++++++++++----- src/declarative/fx/qfxtext_p.h | 4 ++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/declarative/fx/qfxtext.cpp b/src/declarative/fx/qfxtext.cpp index 4d02f0d..763256b 100644 --- a/src/declarative/fx/qfxtext.cpp +++ b/src/declarative/fx/qfxtext.cpp @@ -420,28 +420,28 @@ void QFxText::setTextFormat(TextFormat format) } /*! - \qmlproperty Qt::TextElideMode Text::elide + \qmlproperty enumeration Text::elide Set this property to elide parts of the text fit to the Text item's width. The text will only elide if an explicit width has been set. This property cannot be used with wrap enabled or with rich text. - Eliding can be ElideNone (the default), ElideLeft, ElideMiddle, or ElideRight. + Eliding can be \c ElideNone (the default), \c ElideLeft, \c ElideMiddle, or \c ElideRight. - If the text is a multi-length string, and the mode is not ElideNone, + If the text is a multi-length string, and the mode is not \c ElideNone, the first string that fits will be used, otherwise the last will be elided. Multi-length strings are ordered from longest to shortest, separated by the - Unicode "String Terminator" character U009C (write this in QML with "\\x9C"). + Unicode "String Terminator" character \c U009C (write this in QML with \c{"\\x9C"}). */ -Qt::TextElideMode QFxText::elideMode() const +QFxText::TextElideMode QFxText::elideMode() const { Q_D(const QFxText); return d->elideMode; } -void QFxText::setElideMode(Qt::TextElideMode mode) +void QFxText::setElideMode(QFxText::TextElideMode mode) { Q_D(QFxText); if (mode == d->elideMode) @@ -458,7 +458,7 @@ void QFxText::geometryChanged(const QRectF &newGeometry, { Q_D(QFxText); if (newGeometry.width() != oldGeometry.width()) { - if (d->wrap || d->elideMode != Qt::ElideNone) { + if (d->wrap || d->elideMode != QFxText::ElideNone) { d->imgDirty = true; d->updateSize(); } @@ -486,8 +486,8 @@ void QFxTextPrivate::updateSize() tmp = text; tmp.replace(QLatin1Char('\n'), QChar::LineSeparator); singleline = !tmp.contains(QChar::LineSeparator); - if (singleline && elideMode != Qt::ElideNone && q->widthValid()) - tmp = fm.elidedText(tmp,elideMode,q->width()); // XXX still worth layout...? + if (singleline && elideMode != QFxText::ElideNone && q->widthValid()) + tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width()); // XXX still worth layout...? layout.clearLayout(); layout.setFont(font); layout.setText(tmp); @@ -586,7 +586,7 @@ QSize QFxTextPrivate::setupTextLayout(QTextLayout *layout) qreal lineWidth = 0; //set manual width - if ((wrap || elideMode != Qt::ElideNone) && q->widthValid()) + if ((wrap || elideMode != QFxText::ElideNone) && q->widthValid()) lineWidth = q->width(); layout->beginLayout(); @@ -596,7 +596,7 @@ QSize QFxTextPrivate::setupTextLayout(QTextLayout *layout) if (!line.isValid()) break; - if ((wrap || elideMode != Qt::ElideNone) && q->widthValid()) + if ((wrap || elideMode != QFxText::ElideNone) && q->widthValid()) line.setLineWidth(lineWidth); } layout->endLayout(); diff --git a/src/declarative/fx/qfxtext.h b/src/declarative/fx/qfxtext.h index 763e2aa..cdb8025 100644 --- a/src/declarative/fx/qfxtext.h +++ b/src/declarative/fx/qfxtext.h @@ -57,6 +57,7 @@ class Q_DECLARATIVE_EXPORT QFxText : public QFxItem Q_ENUMS(VAlignment) Q_ENUMS(TextStyle) Q_ENUMS(TextFormat) + Q_ENUMS(TextElideMode) Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QFont font READ font WRITE setFont) @@ -67,7 +68,7 @@ class Q_DECLARATIVE_EXPORT QFxText : public QFxItem Q_PROPERTY(VAlignment verticalAlignment READ vAlign WRITE setVAlign) Q_PROPERTY(bool wrap READ wrap WRITE setWrap) //### there are several wrap modes in Qt Q_PROPERTY(TextFormat textFormat READ textFormat WRITE setTextFormat) - Q_PROPERTY(Qt::TextElideMode elide READ elideMode WRITE setElideMode) //### elideMode? + Q_PROPERTY(TextElideMode elide READ elideMode WRITE setElideMode) //### elideMode? public: QFxText(QFxItem *parent=0); @@ -84,8 +85,12 @@ public: Raised, Sunken }; enum TextFormat { PlainText = Qt::PlainText, - RichText = Qt::RichText, - AutoText = Qt::AutoText }; + RichText = Qt::RichText, + AutoText = Qt::AutoText }; + enum TextElideMode { ElideLeft = Qt::ElideLeft, + ElideRight = Qt::ElideRight, + ElideMiddle = Qt::ElideMiddle, + ElideNone = Qt::ElideNone }; QString text() const; void setText(const QString &); @@ -114,8 +119,8 @@ public: TextFormat textFormat() const; void setTextFormat(TextFormat format); - Qt::TextElideMode elideMode() const; - void setElideMode(Qt::TextElideMode); + TextElideMode elideMode() const; + void setElideMode(TextElideMode); void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); diff --git a/src/declarative/fx/qfxtext_p.h b/src/declarative/fx/qfxtext_p.h index 8b24c66..a10cdfa 100644 --- a/src/declarative/fx/qfxtext_p.h +++ b/src/declarative/fx/qfxtext_p.h @@ -70,7 +70,7 @@ class QFxTextPrivate : public QFxItemPrivate public: QFxTextPrivate() : color((QRgb)0), style(QFxText::Normal), imgDirty(true), - hAlign(QFxText::AlignLeft), vAlign(QFxText::AlignTop), elideMode(Qt::ElideNone), + hAlign(QFxText::AlignLeft), vAlign(QFxText::AlignTop), elideMode(QFxText::ElideNone), dirty(true), wrap(false), richText(false), singleline(false), control(0), doc(0), format(QFxText::AutoText) { @@ -97,7 +97,7 @@ public: QPixmap imgStyleCache; QFxText::HAlignment hAlign; QFxText::VAlignment vAlign; - Qt::TextElideMode elideMode; + QFxText::TextElideMode elideMode; bool dirty; bool wrap; bool richText; -- cgit v0.12 From d42846123ec17641d1e8a8082fab0d04ce93e8a1 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 14:57:16 +1000 Subject: Do not display transient binding errors During QML startup, it is common to have "errors" in bindings as the apps state stabilizes. These are not real errors, but just a consequence of implementing a declarative UI in an imperative world. Now during startup, the display of errors is delayed until the startup completes, and then only bindings that are still in an error state are displayed. QT-2373 --- src/declarative/qml/qmlbinding.cpp | 62 +++++++++++++++++++++++++++++++---- src/declarative/qml/qmlbinding_p.h | 6 ++++ src/declarative/qml/qmlcomponent.cpp | 17 ++++++++++ src/declarative/qml/qmlengine.cpp | 5 +-- src/declarative/qml/qmlengine_p.h | 5 +++ src/declarative/qml/qmlexpression.cpp | 1 + src/declarative/qml/qmlexpression_p.h | 2 +- 7 files changed, 88 insertions(+), 10 deletions(-) diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index ab4343c..317a4b3 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -58,10 +58,46 @@ QT_BEGIN_NAMESPACE QML_DEFINE_NOCREATE_TYPE(QmlBinding); QmlBindingData::QmlBindingData() -: updating(false), enabled(false) +: updating(false), enabled(false), nextError(0), prevError(0) { } +QmlBindingData::~QmlBindingData() +{ + removeError(); +} + +void QmlBindingData::removeError() +{ + if (!prevError) return; + + if (nextError) nextError->prevError = prevError; + *prevError = nextError; + nextError = 0; + prevError = 0; +} + +bool QmlBindingData::addError() +{ + if (prevError) return false; + + QmlContext *c = context(); + if (!c) return false; + QmlEngine *e = c->engine(); + if (!e) return false; + + QmlEnginePrivate *p = QmlEnginePrivate::get(e); + + if (p->inProgressCreations == 0) return false; // Not in construction + + prevError = &p->erroredBindings; + nextError = p->erroredBindings; + p->erroredBindings = this; + if (nextError) nextError->prevError = &nextError; + + return true; +} + QmlBindingPrivate::QmlBindingPrivate() : QmlExpressionPrivate(new QmlBindingData) { @@ -131,9 +167,9 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) bool isUndefined = false; QVariant value = this->value(&isUndefined); - if (this->hasError()) { - qWarning().nospace() << qPrintable(this->error().toString()); - } else if (!isUndefined && data->property.object() && !data->property.write(value, flags)) { + if (!isUndefined && data->property.object() && + !data->property.write(value, flags)) { + QString fileName = data->fileName; int line = data->line; if (fileName.isEmpty()) fileName = QLatin1String(""); @@ -141,9 +177,21 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) const char *valueType = 0; if (value.userType() == QVariant::Invalid) valueType = "null"; else valueType = QMetaType::typeName(value.userType()); - qWarning().nospace() << qPrintable(fileName) << ":" << line - << " Unable to assign " << valueType << " to " - << QMetaType::typeName(data->property.propertyType()); + + data->error.setUrl(fileName); + data->error.setLine(line); + data->error.setColumn(-1); + data->error.setDescription(QLatin1String("Unable to assign ") + + QLatin1String(valueType) + + QLatin1String(" to ") + + QLatin1String(QMetaType::typeName(data->property.propertyType()))); + } + + if (data->error.isValid()) { + if (!data->addError()) + qWarning().nospace() << qPrintable(this->error().toString()); + } else { + data->removeError(); } } diff --git a/src/declarative/qml/qmlbinding_p.h b/src/declarative/qml/qmlbinding_p.h index 2c0c6b9..c9378cb 100644 --- a/src/declarative/qml/qmlbinding_p.h +++ b/src/declarative/qml/qmlbinding_p.h @@ -63,11 +63,17 @@ class QmlBindingData : public QmlExpressionData { public: QmlBindingData(); + virtual ~QmlBindingData(); bool updating:1; bool enabled:1; QmlMetaProperty property; + + void removeError(); + bool addError(); + QmlBindingData *nextError; + QmlBindingData **prevError; }; class QmlBindingPrivate : public QmlExpressionPrivate diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 0894758..3767695 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -55,6 +55,7 @@ #include "qmlbinding.h" #include #include +#include #include "qmlscriptparser_p.h" @@ -197,6 +198,12 @@ QmlComponent::QmlComponent(QObject *parent) QmlComponent::~QmlComponent() { Q_D(QmlComponent); + + if (d->completePending) { + qWarning("QmlComponent: Component destroyed while completion pending"); + d->completeCreate(); + } + if (d->typeData) { d->typeData->remWaiter(d); d->typeData->release(); @@ -574,8 +581,10 @@ QmlComponentPrivate::beginCreate(QmlContext *context, const QBitField &bindings) ep->bindValues.clear(); ep->parserStatus.clear(); completePending = true; + QmlEnginePrivate::get(engine)->inProgressCreations++; } + if (rv) { QFx_setParent_noEvent(ctxt, rv); } else { @@ -643,6 +652,14 @@ void QmlComponentPrivate::completeCreate() bindValues.clear(); parserStatus.clear(); completePending = false; + QmlEnginePrivate *p = QmlEnginePrivate::get(engine); + p->inProgressCreations--; + if (0 == p->inProgressCreations) { + while (p->erroredBindings) { + qWarning().nospace() << qPrintable(p->erroredBindings->error.toString()); + p->erroredBindings->removeError(); + } + } } } diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 0e239ce..3da8aa9 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -126,8 +126,9 @@ static QString userLocalDataPath(const QString& app) QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) : rootContext(0), currentExpression(0), isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0), globalClass(0), - nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), cleanup(0), scriptEngine(this), - componentAttacheds(0), rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) + nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), cleanup(0), erroredBindings(0), + inProgressCreations(0), scriptEngine(this), componentAttacheds(0), rootComponent(0), + networkAccessManager(0), typeManager(e), uniqueId(1) { QScriptValue qtObject = scriptEngine.newQMetaObject(StaticQtMetaObject::get()); diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 69b121e..efd26bf 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -98,6 +98,7 @@ class QmlTypeNameCache; class QmlComponentAttached; class QmlListScriptClass; class QmlCleanup; +class QmlBindingData; class QmlEnginePrivate : public QObjectPrivate { @@ -143,6 +144,10 @@ public: // Registered cleanup handlers QmlCleanup *cleanup; + // Bindings that have had errors during startup + QmlBindingData *erroredBindings; + int inProgressCreations; + struct QmlScriptEngine : public QScriptEngine { QmlScriptEngine(QmlEnginePrivate *priv) diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 8231bf8..e5e5cf9 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -293,6 +293,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd QFxPerfTimer perfqt; #endif + QmlExpressionData *data = this->data; QmlContextPrivate *ctxtPriv = data->context()->d_func(); QmlEngine *engine = data->context()->engine(); QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h index b453a96..4e13de3 100644 --- a/src/declarative/qml/qmlexpression_p.h +++ b/src/declarative/qml/qmlexpression_p.h @@ -83,7 +83,7 @@ class QmlExpressionData : public QmlAbstractExpression, public QmlRefCount { public: QmlExpressionData(); - ~QmlExpressionData(); + virtual ~QmlExpressionData(); QmlExpressionPrivate *q; -- cgit v0.12 From 1e7318348848ff7f51446ae90021051a494e3cb8 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 28 Oct 2009 15:19:34 +1000 Subject: cleanup --- examples/declarative/fillmode/fillmode.qml | 14 ++-- examples/declarative/velocity/Day.qml | 108 ++++++++++------------------- examples/declarative/velocity/velocity.qml | 77 ++++++++++---------- 3 files changed, 79 insertions(+), 120 deletions(-) diff --git a/examples/declarative/fillmode/fillmode.qml b/examples/declarative/fillmode/fillmode.qml index 0fdacbf..d3a28e2 100644 --- a/examples/declarative/fillmode/fillmode.qml +++ b/examples/declarative/fillmode/fillmode.qml @@ -7,22 +7,22 @@ Image { fillMode: SequentialAnimation { running: true repeat: true - PropertyAction { value: "Stretch" } + PropertyAction { value: Image.Stretch } PropertyAction { target: label; property: "text"; value: "Stretch" } PauseAnimation { duration: 1000 } - PropertyAction { value: "PreserveAspectFit" } + PropertyAction { value: Image.PreserveAspectFit } PropertyAction { target: label; property: "text"; value: "PreserveAspectFit" } PauseAnimation { duration: 1000 } - PropertyAction { value: "PreserveAspectCrop" } + PropertyAction { value: Image.PreserveAspectCrop } PropertyAction { target: label; property: "text"; value: "PreserveAspectCrop" } PauseAnimation { duration: 1000 } - PropertyAction { value: "Tile" } + PropertyAction { value: Image.Tile } PropertyAction { target: label; property: "text"; value: "Tile" } PauseAnimation { duration: 1000 } - PropertyAction { value: "TileHorizontally" } + PropertyAction { value: Image.TileHorizontally } PropertyAction { target: label; property: "text"; value: "TileHorizontally" } PauseAnimation { duration: 1000 } - PropertyAction { value: "TileVertically" } + PropertyAction { value: Image.TileVertically } PropertyAction { target: label; property: "text"; value: "TileVertically" } PauseAnimation { duration: 1000 } } @@ -30,7 +30,7 @@ Image { id: label font.pointSize: 24 color: "blue" - style: "Outline" + style: Text.Outline styleColor: "white" anchors { centerIn: parent } } diff --git a/examples/declarative/velocity/Day.qml b/examples/declarative/velocity/Day.qml index b0d4dd9..030fa13 100644 --- a/examples/declarative/velocity/Day.qml +++ b/examples/declarative/velocity/Day.qml @@ -1,65 +1,48 @@ import Qt 4.6 Rectangle { - property string day + property alias day: dayText.text property var stickies - width: 400 - height: 500 - radius: 7 - border.color: "black" id: page - Image { - x: 10 - y: 10 - source: "cork.jpg" - } + width: 400; height: 500; radius: 7 + border.color: "black" + + Image { x: 10; y: 10; source: "cork.jpg" } + Text { - x: 20 - y: 20 - height: 40 - font.pointSize: 14 - font.bold: true - width: 370 - text: day - style: "Outline" - styleColor: "#dedede" + id: dayText; x: 20; y: 20 + height: 40; width: 370 + font.pointSize: 14; font.bold: true + style: Text.Outline; styleColor: "#dedede" } + Repeater { model: page.stickies + Item { + id: stickyPage x: Math.random() * 200 + 100 y: Math.random() * 300 + 50 - id: stickyPage rotation: SpringFollow { source: -flickable.horizontalVelocity / 100 - spring: 2.0 - damping: 0.1 + spring: 2.0; damping: 0.1 } + Item { id: sticky scale: 0.5 Image { - id: stickyImage - source: "sticky.png" - smooth: true - y: -20 - x: 8 + -width * 0.6 / 2 - scale: 0.6 + id: stickyImage; source: "sticky.png" + smooth: true; y: -20; x: 8 + -width * 0.6 / 2; scale: 0.6 } + TextEdit { - id: myText - smooth: true - font.pointSize: 28 - readOnly: false - x: -104 - y: 36 - wrap: true - rotation: -8 - text: noteText - width: 195 - height: 172 + id: myText; smooth: true; font.pointSize: 28 + readOnly: false; x: -104; y: 36; wrap: true + rotation: -8; text: noteText; width: 195; height: 172 } + Item { y: -20 x: stickyImage.x @@ -69,44 +52,27 @@ Rectangle { id: mouse onClicked: { myText.focus = true } anchors.fill: parent - drag.target: stickyPage - drag.axis: "XandYAxis" - drag.minimumY: 0 - drag.maximumY: 500 - drag.minimumX: 0 - drag.maximumX: 400 + drag.target: stickyPage; drag.axis: "XandYAxis"; drag.minimumY: 0; drag.maximumY: 500 + drag.minimumX: 0; drag.maximumX: 400 } } } + Image { source: "tack.png" - x: -width / 2 - y: -height * 0.7 / 2 - scale: 0.7 + x: -width / 2; y: -height * 0.7 / 2; scale: 0.7 + } + + states: State { + name: "pressed" + when: mouse.pressed + PropertyChanges { target: sticky; rotation: 8; scale: 1 } + PropertyChanges { target: page; z: 8 } + } + + transitions: Transition { + NumberAnimation { properties: "rotation,scale"; duration: 200 } } - states: [ - State { - name: "pressed" - when: mouse.pressed - PropertyChanges { - target: sticky - rotation: 8 - scale: 1 - } - PropertyChanges { - target: page - z: 8 - } - } - ] - transitions: [ - Transition { - NumberAnimation { - properties: "rotation,scale" - duration: 200 - } - } - ] } } } diff --git a/examples/declarative/velocity/velocity.qml b/examples/declarative/velocity/velocity.qml index b132965..50d69d8 100644 --- a/examples/declarative/velocity/velocity.qml +++ b/examples/declarative/velocity/velocity.qml @@ -2,8 +2,8 @@ import Qt 4.6 Rectangle { color: "lightSteelBlue" - width: 800 - height: 600 + width: 800; height: 600 + ListModel { id: list ListElement { @@ -12,10 +12,10 @@ Rectangle { notes: [ ListElement { noteText: "Lunch" - }, - ListElement { - noteText: "Party" - } + }, + ListElement { + noteText: "Party" + } ] } ListElement { @@ -24,13 +24,13 @@ Rectangle { notes: [ ListElement { noteText: "Pickup kids" - }, - ListElement { - noteText: "Checkout kinetic" - }, - ListElement { - noteText: "Read email" - } + }, + ListElement { + noteText: "Checkout kinetic" + }, + ListElement { + noteText: "Read email" + } ] } ListElement { @@ -39,10 +39,10 @@ Rectangle { notes: [ ListElement { noteText: "Walk dog" - }, - ListElement { - noteText: "Buy newspaper" - } + }, + ListElement { + noteText: "Buy newspaper" + } ] } ListElement { @@ -51,10 +51,10 @@ Rectangle { notes: [ ListElement { noteText: "Cook dinner" - }, - ListElement { - noteText: "Eat dinner" - } + }, + ListElement { + noteText: "Eat dinner" + } ] } ListElement { @@ -63,10 +63,10 @@ Rectangle { notes: [ ListElement { noteText: "5:30pm Meeting" - }, - ListElement { - noteText: "Weed garden" - } + }, + ListElement { + noteText: "Weed garden" + } ] } ListElement { @@ -75,10 +75,10 @@ Rectangle { notes: [ ListElement { noteText: "Still work" - }, - ListElement { - noteText: "Drink" - } + }, + ListElement { + noteText: "Drink" + } ] } ListElement { @@ -87,28 +87,21 @@ Rectangle { notes: [ ListElement { noteText: "Drink" - }, - ListElement { - noteText: "Drink" - } + }, + ListElement { + noteText: "Drink" + } ] } } Flickable { id: flickable - anchors.fill: parent - viewportWidth: lay.width + anchors.fill: parent; viewportWidth: lay.width Row { id: lay Repeater { model: list - Component { - Day { - day: name - color: dayColor - stickies: notes - } - } + Component { Day { day: name; color: dayColor; stickies: notes } } } } } -- cgit v0.12 From 57d2291b2e0533d23bd52e9814faf6a5727a4e96 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 15:21:36 +1000 Subject: Test for QT-2373 Ensure that transient binding errors are not displayed. --- .../data/NestedTypeTransientErrors.qml | 11 +++++++++++ .../qmlecmascript/data/transientErrors.qml | 10 ++++++++++ .../qmlecmascript/tst_qmlecmascript.cpp | 23 ++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 tests/auto/declarative/qmlecmascript/data/NestedTypeTransientErrors.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/transientErrors.qml diff --git a/tests/auto/declarative/qmlecmascript/data/NestedTypeTransientErrors.qml b/tests/auto/declarative/qmlecmascript/data/NestedTypeTransientErrors.qml new file mode 100644 index 0000000..e19bf24 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/NestedTypeTransientErrors.qml @@ -0,0 +1,11 @@ +import Qt 4.6 + +Object { + property int b: obj.prop.a + + property var prop; + prop: Object { + property int a: 10 + } +} + diff --git a/tests/auto/declarative/qmlecmascript/data/transientErrors.qml b/tests/auto/declarative/qmlecmascript/data/transientErrors.qml new file mode 100644 index 0000000..4e123c6 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/transientErrors.qml @@ -0,0 +1,10 @@ +import Qt 4.6 + +Object { + property var obj: nested + + property var obj2 + obj2: NestedTypeTransientErrors { + id: nested + } +} diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index 67a98b1..48c2249 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -66,6 +66,7 @@ private slots: void signalTriggeredBindings(); void listProperties(); void exceptionClearsOnReeval(); + void transientErrors(); private: QmlEngine engine; @@ -847,6 +848,28 @@ void tst_qmlecmascript::exceptionClearsOnReeval() QCOMPARE(object->property("test").toBool(), true); } +static int transientErrorsMsgCount = 0; +static void transientErrorsMsgHandler(QtMsgType, const char *) +{ + ++transientErrorsMsgCount; +} + +// Check that transient binding errors are not displayed +void tst_qmlecmascript::transientErrors() +{ + QmlComponent component(&engine, TEST_FILE("transientErrors.qml")); + + transientErrorsMsgCount = 0; + QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); + + QObject *object = component.create(); + QVERIFY(object != 0); + + qInstallMsgHandler(old); + + QCOMPARE(transientErrorsMsgCount, 0); +} + QTEST_MAIN(tst_qmlecmascript) #include "tst_qmlecmascript.moc" -- cgit v0.12 From a8f312c84d2c21f8f1c21a99f3dd3428fd16b2fa Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 28 Oct 2009 15:27:42 +1000 Subject: cleanup --- examples/declarative/aspectratio/scale_and_crop_simple.qml | 2 +- examples/declarative/aspectratio/scale_to_fit_simple.qml | 2 +- examples/declarative/fonts/fonts.qml | 10 +++++----- examples/declarative/loader/Browser.qml | 4 ++-- examples/declarative/snow/ImageBatch.qml | 2 +- examples/declarative/tutorials/samegame/samegame1/samegame.qml | 2 +- examples/declarative/tutorials/samegame/samegame2/samegame.qml | 2 +- examples/declarative/tutorials/samegame/samegame3/samegame.qml | 2 +- examples/declarative/tutorials/samegame/samegame4/samegame.qml | 2 +- examples/declarative/webview/content/FieldText.qml | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/declarative/aspectratio/scale_and_crop_simple.qml b/examples/declarative/aspectratio/scale_and_crop_simple.qml index 9cc9c19..434e98e 100644 --- a/examples/declarative/aspectratio/scale_and_crop_simple.qml +++ b/examples/declarative/aspectratio/scale_and_crop_simple.qml @@ -13,7 +13,7 @@ Rectangle { Image { id: face source: "pics/face.png" - fillMode: "PreserveAspectCrop" + fillMode: Image.PreserveAspectCrop anchors.fill: parent } } diff --git a/examples/declarative/aspectratio/scale_to_fit_simple.qml b/examples/declarative/aspectratio/scale_to_fit_simple.qml index f7fcd8b..83909ef 100644 --- a/examples/declarative/aspectratio/scale_to_fit_simple.qml +++ b/examples/declarative/aspectratio/scale_to_fit_simple.qml @@ -13,7 +13,7 @@ Rectangle { Image { id: face source: "pics/face.png" - fillMode: "PreserveAspectFit" + fillMode: Image.PreserveAspectFit anchors.fill: parent } } diff --git a/examples/declarative/fonts/fonts.qml b/examples/declarative/fonts/fonts.qml index 4029f8b..e68bdb6 100644 --- a/examples/declarative/fonts/fonts.qml +++ b/examples/declarative/fonts/fonts.qml @@ -22,21 +22,21 @@ Rectangle { Text { text: myText color: palette.windowText - width: parent.width; elide: "ElideRight" + width: parent.width; elide: Text.ElideRight font.family: "Times" font.pointSize: 32 } Text { text: myText color: palette.windowText - width: parent.width; elide: "ElideRight" + width: parent.width; elide: Text.ElideRight font.family: fixedFont.name font.pointSize: 32 } Text { text: myText color: palette.windowText - width: parent.width; elide: "ElideRight" + width: parent.width; elide: Text.ElideRight font.family: localFont.name font.pointSize: 32 } @@ -47,7 +47,7 @@ Rectangle { else if (webFont.status == 3) "Error loading font" } color: palette.windowText - width: parent.width; elide: "ElideRight" + width: parent.width; elide: Text.ElideRight font.family: webFont.name font.pointSize: 32 } @@ -58,7 +58,7 @@ Rectangle { else if (webFont2.status == 3) "Error loading font" } color: palette.windowText - width: parent.width; elide: "ElideRight" + width: parent.width; elide: Text.ElideRight font.family: webFont2.name font.pointSize: 32 } diff --git a/examples/declarative/loader/Browser.qml b/examples/declarative/loader/Browser.qml index 9e54758..f2cbd3d 100644 --- a/examples/declarative/loader/Browser.qml +++ b/examples/declarative/loader/Browser.qml @@ -81,7 +81,7 @@ Rectangle { } Text { id: nameText - anchors.fill: parent; verticalAlignment: "AlignVCenter" + anchors.fill: parent; verticalAlignment: Text.AlignVCenter text: fileName; anchors.leftMargin: 48 font.pixelSize: 32 color: wrapper.isCurrentItem ? palette.highlightedText : palette.text @@ -225,7 +225,7 @@ Rectangle { anchors.left: upButton.right; anchors.right: parent.right; height: parent.height anchors.leftMargin: 4; anchors.rightMargin: 4 text: folders.folder; color: "white" - elide: "ElideLeft"; horizontalAlignment: "AlignRight"; verticalAlignment: "AlignVCenter" + elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter font.pixelSize: 32 } } diff --git a/examples/declarative/snow/ImageBatch.qml b/examples/declarative/snow/ImageBatch.qml index dfe2a46..95b9b97 100644 --- a/examples/declarative/snow/ImageBatch.qml +++ b/examples/declarative/snow/ImageBatch.qml @@ -41,7 +41,7 @@ GridView { transformOrigin: Item.Center width: grid.imageWidth; height: grid.imageHeight; - Image { id: flickrImage; source: url; fillMode: "PreserveAspectFit"; smooth: true; anchors.fill: parent; + Image { id: flickrImage; source: url; fillMode: Image.PreserveAspectFit; smooth: true; anchors.fill: parent; opacity: (status == Image.Ready)?1:0; opacity: Behavior { NumberAnimation { properties: "opacity" } } } Loading { anchors.centerIn: parent; visible: flickrImage.status!=1 } diff --git a/examples/declarative/tutorials/samegame/samegame1/samegame.qml b/examples/declarative/tutorials/samegame/samegame1/samegame.qml index 8b32cae..b5546d0 100644 --- a/examples/declarative/tutorials/samegame/samegame1/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame1/samegame.qml @@ -13,7 +13,7 @@ Rectangle { Image { id: background anchors.fill: parent; source: "pics/background.png" - fillMode: "PreserveAspectCrop" + fillMode: Image.PreserveAspectCrop } } diff --git a/examples/declarative/tutorials/samegame/samegame2/samegame.qml b/examples/declarative/tutorials/samegame/samegame2/samegame.qml index 63431b1..257e0de 100644 --- a/examples/declarative/tutorials/samegame/samegame2/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame2/samegame.qml @@ -15,7 +15,7 @@ Rectangle { Image { id: background anchors.fill: parent; source: "pics/background.png" - fillMode: "PreserveAspectCrop" + fillMode: Image.PreserveAspectCrop } } diff --git a/examples/declarative/tutorials/samegame/samegame3/samegame.qml b/examples/declarative/tutorials/samegame/samegame3/samegame.qml index 5b98f48..0a7ec0f 100644 --- a/examples/declarative/tutorials/samegame/samegame3/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame3/samegame.qml @@ -14,7 +14,7 @@ Rectangle { Image { id: background anchors.fill: parent; source: "pics/background.png" - fillMode: "PreserveAspectCrop" + fillMode: Image.PreserveAspectCrop } //![1] diff --git a/examples/declarative/tutorials/samegame/samegame4/samegame.qml b/examples/declarative/tutorials/samegame/samegame4/samegame.qml index ede4362..e519912 100644 --- a/examples/declarative/tutorials/samegame/samegame4/samegame.qml +++ b/examples/declarative/tutorials/samegame/samegame4/samegame.qml @@ -15,7 +15,7 @@ Rectangle { Image { id: background anchors.fill: parent; source: "content/pics/background.png" - fillMode: "PreserveAspectCrop" + fillMode: Image.PreserveAspectCrop } Item { diff --git a/examples/declarative/webview/content/FieldText.qml b/examples/declarative/webview/content/FieldText.qml index 2adfbbf..b1c1938 100644 --- a/examples/declarative/webview/content/FieldText.qml +++ b/examples/declarative/webview/content/FieldText.qml @@ -79,7 +79,7 @@ Item { x: 5 width: parent.width-10 anchors.verticalCenter: parent.verticalCenter - horizontalAlignment: "AlignHCenter" + horizontalAlignment: Text.AlignHCenter color: fieldText.state == "editing" ? "#505050" : "#AAAAAA" font.italic: true font.bold: true -- cgit v0.12 From e7dbe2d99da7ed29246ac27e11db92980b5aa986 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 15:30:47 +1000 Subject: "Compile" --- demos/declarative/minehunt/minehunt.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/declarative/minehunt/minehunt.qml b/demos/declarative/minehunt/minehunt.qml index 72431af..67d2813 100644 --- a/demos/declarative/minehunt/minehunt.qml +++ b/demos/declarative/minehunt/minehunt.qml @@ -96,7 +96,7 @@ Item { properties: "angle" } ScriptAction{ - script: "if(modelData.hasMine && modelData.flipped){expl.explode = true;}" + script: if(modelData.hasMine && modelData.flipped){expl.explode = true;} } } } -- cgit v0.12 From f79e9b1f959d44f7efd0186d7f99612480d1bec9 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 15:36:56 +1000 Subject: Use a nicer face image --- examples/declarative/aspectratio/face_fit.qml | 1 + .../declarative/aspectratio/face_fit_animated.qml | 1 + examples/declarative/aspectratio/pics/face.png | Bin 905 -> 15408 bytes examples/declarative/aspectratio/scale_and_crop.qml | 1 + .../declarative/aspectratio/scale_and_crop_simple.qml | 1 + .../declarative/aspectratio/scale_and_sidecrop.qml | 1 + examples/declarative/aspectratio/scale_to_fit.qml | 1 + .../declarative/aspectratio/scale_to_fit_simple.qml | 1 + 8 files changed, 7 insertions(+) diff --git a/examples/declarative/aspectratio/face_fit.qml b/examples/declarative/aspectratio/face_fit.qml index 3d1451c..482d1b7 100644 --- a/examples/declarative/aspectratio/face_fit.qml +++ b/examples/declarative/aspectratio/face_fit.qml @@ -15,6 +15,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" x: (parent.width-width*scale)/2 y: (parent.height-height*scale)/2 diff --git a/examples/declarative/aspectratio/face_fit_animated.qml b/examples/declarative/aspectratio/face_fit_animated.qml index f004a6c..80a762b 100644 --- a/examples/declarative/aspectratio/face_fit_animated.qml +++ b/examples/declarative/aspectratio/face_fit_animated.qml @@ -13,6 +13,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" x: (parent.width-width*scale)/2 y: (parent.height-height*scale)/2 diff --git a/examples/declarative/aspectratio/pics/face.png b/examples/declarative/aspectratio/pics/face.png index 9623b1a..3d66d72 100644 Binary files a/examples/declarative/aspectratio/pics/face.png and b/examples/declarative/aspectratio/pics/face.png differ diff --git a/examples/declarative/aspectratio/scale_and_crop.qml b/examples/declarative/aspectratio/scale_and_crop.qml index 2c9477e..283e24b 100644 --- a/examples/declarative/aspectratio/scale_and_crop.qml +++ b/examples/declarative/aspectratio/scale_and_crop.qml @@ -11,6 +11,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" x: (parent.width-width*scale)/2 y: (parent.height-height*scale)/2 diff --git a/examples/declarative/aspectratio/scale_and_crop_simple.qml b/examples/declarative/aspectratio/scale_and_crop_simple.qml index 434e98e..e720ce7 100644 --- a/examples/declarative/aspectratio/scale_and_crop_simple.qml +++ b/examples/declarative/aspectratio/scale_and_crop_simple.qml @@ -12,6 +12,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" fillMode: Image.PreserveAspectCrop anchors.fill: parent diff --git a/examples/declarative/aspectratio/scale_and_sidecrop.qml b/examples/declarative/aspectratio/scale_and_sidecrop.qml index 67c7e29..c3ef859 100644 --- a/examples/declarative/aspectratio/scale_and_sidecrop.qml +++ b/examples/declarative/aspectratio/scale_and_sidecrop.qml @@ -12,6 +12,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" x: (parent.width-width*scale)/2 y: (parent.height-height*scale)/2 diff --git a/examples/declarative/aspectratio/scale_to_fit.qml b/examples/declarative/aspectratio/scale_to_fit.qml index c4efc29..961ac04 100644 --- a/examples/declarative/aspectratio/scale_to_fit.qml +++ b/examples/declarative/aspectratio/scale_to_fit.qml @@ -12,6 +12,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" x: (parent.width-width*scale)/2 y: (parent.height-height*scale)/2 diff --git a/examples/declarative/aspectratio/scale_to_fit_simple.qml b/examples/declarative/aspectratio/scale_to_fit_simple.qml index 83909ef..7389581 100644 --- a/examples/declarative/aspectratio/scale_to_fit_simple.qml +++ b/examples/declarative/aspectratio/scale_to_fit_simple.qml @@ -12,6 +12,7 @@ Rectangle { Image { id: face + smooth: true source: "pics/face.png" fillMode: Image.PreserveAspectFit anchors.fill: parent -- cgit v0.12 From 3e6732dd364b139485888df053a23f40a4bdee79 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 15:42:38 +1000 Subject: Ensure all tests appear in pro file --- tests/auto/declarative/declarative.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index b51e285..5d355f6 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -1,7 +1,10 @@ TEMPLATE = subdirs SUBDIRS += anchors \ + animatedimage \ animations \ + behaviors \ datetimeformatter \ + examples \ layouts \ listview \ numberformatter \ -- cgit v0.12 From e78a0d8f7449b81c971284310e6fb255d4a9d4eb Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 28 Oct 2009 15:43:48 +1000 Subject: Whoops --- tests/auto/declarative/declarative.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 5d355f6..8b1c9cd 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -9,7 +9,6 @@ SUBDIRS += anchors \ listview \ numberformatter \ pathview \ - qbindablemap \ qfxloader \ qfxpixmapcache \ qfxtext \ -- cgit v0.12 From dbba440da0677b8174d087d498d3d0dbd465548a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 28 Oct 2009 15:44:26 +1000 Subject: Fix dynamic example Includes adding a comment to the positioners to alert others that you shouldn't use anchors as well. --- examples/declarative/dynamic/dynamic.qml | 2 -- src/declarative/fx/qfxpositioners.cpp | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/examples/declarative/dynamic/dynamic.qml b/examples/declarative/dynamic/dynamic.qml index e083a5b..885e037 100644 --- a/examples/declarative/dynamic/dynamic.qml +++ b/examples/declarative/dynamic/dynamic.qml @@ -68,14 +68,12 @@ Item { Text{ text: "Drag an item into the scene." } Row{ id: toolRow spacing: 8; - height: childrenRect.height//TODO: Put bug in JIRA when it comes back up PaletteItem{ anchors.verticalCenter: parent.verticalCenter file: "Sun.qml"; image: "images/sun.png" } PaletteItem{ - anchors.verticalCenter: parent.verticalCenter file: "GenericItem.qml" image: "images/moon.png" } diff --git a/src/declarative/fx/qfxpositioners.cpp b/src/declarative/fx/qfxpositioners.cpp index cc385e0..86a069d 100644 --- a/src/declarative/fx/qfxpositioners.cpp +++ b/src/declarative/fx/qfxpositioners.cpp @@ -375,6 +375,10 @@ Column { \endqml \endtable + Note that the positioner assumes that the x and y positions of its children + will not change. If you manually change the x or y properties in script, bind + the x or y properties, or use anchors on a child of a positioner, then the + positioner may exhibit strange behaviour. */ /*! @@ -539,6 +543,11 @@ Row { \endqml \image horizontalpositioner_example.png + Note that the positioner assumes that the x and y positions of its children + will not change. If you manually change the x or y properties in script, bind + the x or y properties, or use anchors on a child of a positioner, then the + positioner may exhibit strange behaviour. + */ /*! \qmlproperty Transition Row::remove @@ -659,7 +668,7 @@ void QFxRow::doPositioning() child->setX(hoffset); setMovingItem(0); } - if(!child->width() || !child->height()){//don't advance for invisible children + if(child->width() && child->height()){//don't advance for invisible children hoffset += child->width(); hoffset += spacing(); } @@ -707,6 +716,11 @@ Grid { } \endqml \endtable + + Note that the positioner assumes that the x and y positions of its children + will not change. If you manually change the x or y properties in script, bind + the x or y properties, or use anchors on a child of a positioner, then the + positioner may exhibit strange behaviour. */ /*! \qmlproperty Transition Grid::remove -- cgit v0.12