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 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