diff options
author | Kimmo Ollila <kimmo.ollila@digia.com> | 2013-03-28 11:13:29 +0200 |
---|---|---|
committer | Sami Makkonen <sami.makkonen@digia.com> | 2013-03-28 12:40:58 +0200 |
commit | ef80e146bd5f4a52763fb1123b388f561286c448 (patch) | |
tree | 7b71990aaa1117567e5f2acaa5522d15a5474015 | |
parent | e02b925f0e7628e805f6f8c0889d96f1eb17c930 (diff) |
Initial commit: basic navigation functionality
Change-Id: I2420fe4012584f7f6dd037707685e17c092618d1
Reviewed-by: Sami Makkonen <sami.makkonen@digia.com>
-rw-r--r-- | QtDemo/QtDemo.pro | 19 | ||||
-rw-r--r-- | QtDemo/QtDemo64.png | bin | 0 -> 3400 bytes | |||
-rw-r--r-- | QtDemo/QtDemo80.png | bin | 0 -> 4945 bytes | |||
-rw-r--r-- | QtDemo/main.cpp | 13 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/Button.qml | 32 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/NavigationPanel.qml | 35 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/Slide.qml | 20 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/engine.js | 47 | ||||
-rw-r--r-- | QtDemo/qml/QtDemo/main.qml | 166 |
9 files changed, 332 insertions, 0 deletions
diff --git a/QtDemo/QtDemo.pro b/QtDemo/QtDemo.pro new file mode 100644 index 0000000..edda2e4 --- /dev/null +++ b/QtDemo/QtDemo.pro @@ -0,0 +1,19 @@ +# Add more folders to ship with the application, here +folder_01.source = qml/QtDemo +folder_01.target = qml +DEPLOYMENTFOLDERS = folder_01 + +# Additional import path used to resolve QML modules in Creator's code model +QML_IMPORT_PATH = + +# If your application uses the Qt Mobility libraries, uncomment the following +# lines and add the respective components to the MOBILITY variable. +# CONFIG += mobility +# MOBILITY += + +# The .cpp file which was generated for your project. Feel free to hack it. +SOURCES += main.cpp + +# Please do not modify the following two lines. Required for deployment. +include(qtquick2applicationviewer/qtquick2applicationviewer.pri) +qtcAddDeployment() diff --git a/QtDemo/QtDemo64.png b/QtDemo/QtDemo64.png Binary files differnew file mode 100644 index 0000000..707d5c4 --- /dev/null +++ b/QtDemo/QtDemo64.png diff --git a/QtDemo/QtDemo80.png b/QtDemo/QtDemo80.png Binary files differnew file mode 100644 index 0000000..6ad8096 --- /dev/null +++ b/QtDemo/QtDemo80.png diff --git a/QtDemo/main.cpp b/QtDemo/main.cpp new file mode 100644 index 0000000..3dcc086 --- /dev/null +++ b/QtDemo/main.cpp @@ -0,0 +1,13 @@ +#include <QtGui/QGuiApplication> +#include "qtquick2applicationviewer.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QtQuick2ApplicationViewer viewer; + viewer.setMainQmlFile(QStringLiteral("qml/QtDemo/main.qml")); + viewer.showExpanded(); + + return app.exec(); +} diff --git a/QtDemo/qml/QtDemo/Button.qml b/QtDemo/qml/QtDemo/Button.qml new file mode 100644 index 0000000..57eb58e --- /dev/null +++ b/QtDemo/qml/QtDemo/Button.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 40 + height: 40 + border {color: "#333333"; width: 1} + radius: 20 + smooth: true + gradient: Gradient{ + GradientStop {position: .0; color: buttonMouseArea.pressed ? "#dddddd" : "#aaaaaa"} + GradientStop {position: 1.0; color: "#666666"} + } + + property string label: "" + signal clicked() + + Text{ + text: root.label + anchors.centerIn: root + color: "white" + font { pixelSize: 26; weight: Font.Bold } + } + + MouseArea { + id: buttonMouseArea + anchors.fill: root + onClicked: { + root.clicked() + } + } +} diff --git a/QtDemo/qml/QtDemo/NavigationPanel.qml b/QtDemo/qml/QtDemo/NavigationPanel.qml new file mode 100644 index 0000000..62a845b --- /dev/null +++ b/QtDemo/qml/QtDemo/NavigationPanel.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 + +Column{ + Button { + label: "<" + color: "#aaaaaa" + onClicked: { + canvas.angle+=10 + } + } + + Button { + label: ">" + color: "#aaaaaa" + onClicked: { + canvas.angle-=10 + } + } + + Button { + label: "+" + color: "#aaaaaa" + onClicked: { + canvas.scalingFactor+=.1 + } + } + + Button { + label: "-" + color: "#aaaaaa" + onClicked: { + if (canvas.scalingFactor > .1) canvas.scalingFactor-=.1 + } + } +} diff --git a/QtDemo/qml/QtDemo/Slide.qml b/QtDemo/qml/QtDemo/Slide.qml new file mode 100644 index 0000000..9a3e565 --- /dev/null +++ b/QtDemo/qml/QtDemo/Slide.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Rectangle { + id: slide + objectName: "slide" + width: 640 + height: 480 + color: "grey" + border {color: "#333333"; width:3} + + property int uid: 0 + + Text{ + anchors.centerIn: parent + text: "^This side up^" + font.pixelSize: 60 + color: "white" + } + Component.onCompleted: print ("new slide created!") +} diff --git a/QtDemo/qml/QtDemo/engine.js b/QtDemo/qml/QtDemo/engine.js new file mode 100644 index 0000000..573dec3 --- /dev/null +++ b/QtDemo/qml/QtDemo/engine.js @@ -0,0 +1,47 @@ +var positions = [{x:1300, y:-500, angle:-45, color: "blue", scale: .8}, + {x:-200, y:200, angle:0, color: "grey", scale: 1.2}, + {x:-1500, y:-1000, angle:170, color: "green", scale: .4}, + {x:-1000, y:1000, angle:289, color: "red", scale: .3}, + {x: 1700, y: 100, angle:257, color: "lime", scale: 1}, + {x:50, y:-1500, angle:-45, color: "black", scale: .5} + ] + +var objects = [] + +function initSlides(){ + positions.forEach(function(pos){ + createNew(pos.x,pos.y,pos.angle, pos.color, pos.scale) + }) +} + +function createNew(x,y,angle,color,scale){ + var component = Qt.createComponent("Slide.qml") + if (component.status === Component.Ready) + var object=component.createObject(canvas) + object.x = x-object.width/2 + object.y = y-object.height/2 + object.rotation = angle + object.color = color + object.scale = scale + object.uid = objects.length+1 //TODO make unique + //in future objects will also + //get destroyed and re-created + objects.push(object) +} + +function selectTarget(uid){ + + var idx; + + if (uid){ + for (idx=0; idx < objects.length; idx++){ + if (objects[idx].uid === uid){ + return {"x": positions[idx].x, "y": positions[idx].y, "angle": positions[idx].angle, "scale": positions[idx].scale} + } + } + } + + //randomly select new target for now + idx = Math.floor(Math.random()*positions.length) + return {"x": positions[idx].x, "y": positions[idx].y, "angle": positions[idx].angle, "scale": positions[idx].scale} +} diff --git a/QtDemo/qml/QtDemo/main.qml b/QtDemo/qml/QtDemo/main.qml new file mode 100644 index 0000000..abc5d53 --- /dev/null +++ b/QtDemo/qml/QtDemo/main.qml @@ -0,0 +1,166 @@ +import QtQuick 2.0 +import "engine.js" as Engine + +Item{ + id: app + width: 640 + height: 480 + clip: true + Rectangle{ + anchors.centerIn: parent + width:1000 + height:1 + color: "black" + } + + Rectangle{ + anchors.centerIn: parent + width: 1 + height:1000 + color: "black" + } + + Item{ + id:canvas + width:1 + height:1 + + x: app.width/2+xOffset + y: app.height/2+yOffset + + property real xOffset: 0 + property real yOffset: 0 + property real angle: 0 + property real scalingFactor: .1 + + property real zoomInTarget: 1 + property real zoomOutTarget: .4 + + property real rotationOriginX + property real rotationOriginY + + Behavior on angle {NumberAnimation{duration: 1000}} + + Behavior on xOffset { + id: xOffsetBehaviour + enabled: !worldMouseArea.panning + NumberAnimation{duration: 1000} + } + + Behavior on yOffset { + id: yOffsetBehaviour + enabled: !worldMouseArea.panning + NumberAnimation{duration: 1000} + } + + Behavior on rotationOriginX {NumberAnimation{duration: 1000}} + Behavior on rotationOriginY {NumberAnimation{duration: 1000}} + + Rectangle{ + anchors.centerIn: parent + width:4000 + height:4000 + color:"transparent" + radius:2000 + border{color:"red"; width:100} + } + + transform: [ + + Scale{ + id: canvasScale + origin.x: canvas.rotationOriginX + origin.y: canvas.rotationOriginY + xScale: canvas.scalingFactor + yScale :canvas.scalingFactor + + }, + Rotation{ + id: canvasRotation + origin.x: canvas.rotationOriginX + origin.y: canvas.rotationOriginY + angle: canvas.angle + } + ] + } + + SequentialAnimation{ + id: zoomFlyByAnimation + alwaysRunToEnd: true + NumberAnimation { target: canvas; property: "scalingFactor"; duration: 500; to:canvas.zoomOutTarget; easing.type: Easing.OutCubic } + NumberAnimation { target: canvas; property: "scalingFactor"; duration: 500; to:canvas.zoomInTarget; easing.type: Easing.InCubic } + } + + MouseArea{ + id: worldMouseArea + + property int startX: 0 + property int startY: 0 + + property int oldX: 0 + property int oldY: 0 + + property bool panning: false + + anchors.fill: parent + + onClicked: { + if (panning) { + panning = false + return + } + var object = mapToItem(canvas, mouse.x, mouse.y) + var item = canvas.childAt(object.x,object.y) + + var target = null + + if (item && item.objectName === 'slide') { + target = Engine.selectTarget(item.uid) + } else { + //select random target for now... + target = Engine.selectTarget(null) + } + + canvas.xOffset = -target.x + canvas.yOffset = -target.y + canvas.rotationOriginX = target.x + canvas.rotationOriginY = target.y + canvas.angle = -target.angle + canvas.zoomOutTarget = .4 + canvas.zoomInTarget = 1.0/target.scale + + zoomFlyByAnimation.restart() + } + + onPressed: { + startX = mouse.x + startY = mouse.y + oldX = mouse.x + oldY = mouse.y + } + + onPositionChanged: { + panning= true + + canvas.xOffset+=(mouse.x - oldX) + canvas.yOffset+=(mouse.y - oldY) + + oldX = mouse.x + oldY = mouse.y + } + + onReleased: { + //TODO: make it so that movement slows down and stops + //rather that just stopping the movement + } + + // drag.target: canvas + // drag.axis: Drag.XAndYAxis + } + + NavigationPanel{ + anchors{top:parent.top; right:parent.right} + } + + Component.onCompleted: Engine.initSlides() +} |