aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2014-12-04 15:35:40 +0100
committerShawn Rutledge <shawn.rutledge@digia.com>2015-02-12 06:34:17 +0000
commit1574ba82e6a3dae03fc129973da1da9b0f6a5543 (patch)
tree7bfe4c26927d3cd76bec097e72518952d7644107 /examples
parentb8a3b410cf518dfce9e552d153849aeb142f89ff (diff)
Photosurface example: flickable surface
The Flickable provides a way of testing interaction with 2-finger trackpad gestures: if the cursor is over the background, you can flick the surface via wheel events (which come from native flick gestures if you are using a trackpad on OS X); inside the bounds of a photo, the same 2-finger gesture is for zooming and rotating. Also, random position and rotation are applied more correctly, and only at startup. Position and rotation changes are animated. Change-Id: Iab49b7f2e99a9686424368fd94f0b7f89807da22 Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/quick/demos/photosurface/photosurface.qml168
1 files changed, 107 insertions, 61 deletions
diff --git a/examples/quick/demos/photosurface/photosurface.qml b/examples/quick/demos/photosurface/photosurface.qml
index 6c85bef77f..96478ebf65 100644
--- a/examples/quick/demos/photosurface/photosurface.qml
+++ b/examples/quick/demos/photosurface/photosurface.qml
@@ -37,7 +37,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.4
import QtQuick.Dialogs 1.0
import QtQuick.Window 2.1
import Qt.labs.folderlistmodel 1.0
@@ -50,6 +50,7 @@ Window {
property int highestZ: 0
property real defaultSize: 200
property var currentFrame: undefined
+ property real surfaceViewportRatio: 1.5
FileDialog {
id: fileDialog
@@ -58,76 +59,121 @@ Window {
onAccepted: folderModel.folder = fileUrl + "/"
}
- Repeater {
- model: FolderListModel {
- id: folderModel
- objectName: "folderModel"
- showDirs: false
- nameFilters: ["*.png", "*.jpg", "*.gif"]
- }
- Rectangle {
- id: photoFrame
- width: image.width * (1 + 0.10 * image.height / image.width)
- height: image.height * 1.10
- scale: defaultSize / Math.max(image.sourceSize.width, image.sourceSize.height)
- border.color: "black"
- border.width: 2
- smooth: true
- antialiasing: true
- Component.onCompleted: {
- x = Math.random() * root.width - defaultSize
- y = Math.random() * root.height - defaultSize
- rotation = Math.random() * 13 - 6
+ Flickable {
+ id: flick
+ anchors.fill: parent
+ contentWidth: width * surfaceViewportRatio
+ contentHeight: height * surfaceViewportRatio
+ Repeater {
+ model: FolderListModel {
+ id: folderModel
+ objectName: "folderModel"
+ showDirs: false
+ nameFilters: ["*.png", "*.jpg", "*.gif"]
}
- Image {
- id: image
- anchors.centerIn: parent
- fillMode: Image.PreserveAspectFit
- source: folderModel.folder + fileName
+ Rectangle {
+ id: photoFrame
+ width: image.width * (1 + 0.10 * image.height / image.width)
+ height: image.height * 1.10
+ scale: defaultSize / Math.max(image.sourceSize.width, image.sourceSize.height)
+ Behavior on scale { NumberAnimation { duration: 200 } }
+ Behavior on x { NumberAnimation { duration: 200 } }
+ Behavior on y { NumberAnimation { duration: 200 } }
+ border.color: "black"
+ border.width: 2
+ smooth: true
antialiasing: true
- }
- PinchArea {
- anchors.fill: parent
- pinch.target: photoFrame
- pinch.minimumRotation: -360
- pinch.maximumRotation: 360
- pinch.minimumScale: 0.1
- pinch.maximumScale: 10
- onPinchStarted: setFrameColor();
- MouseArea {
- id: dragArea
- hoverEnabled: true
+ Component.onCompleted: {
+ x = Math.random() * root.width - width / 2
+ y = Math.random() * root.height - height / 2
+ rotation = Math.random() * 13 - 6
+ }
+ Image {
+ id: image
+ anchors.centerIn: parent
+ fillMode: Image.PreserveAspectFit
+ source: folderModel.folder + fileName
+ antialiasing: true
+ }
+ PinchArea {
anchors.fill: parent
- drag.target: photoFrame
- onPressed: {
- photoFrame.z = ++root.highestZ;
- parent.setFrameColor();
- }
- onEntered: parent.setFrameColor();
- onWheel: {
- if (wheel.modifiers & Qt.ControlModifier) {
- photoFrame.rotation += wheel.angleDelta.y / 120 * 5;
- if (Math.abs(photoFrame.rotation) < 4)
- photoFrame.rotation = 0;
- } else {
- photoFrame.rotation += wheel.angleDelta.x / 120;
- if (Math.abs(photoFrame.rotation) < 0.6)
- photoFrame.rotation = 0;
- var scaleBefore = photoFrame.scale;
- photoFrame.scale += photoFrame.scale * wheel.angleDelta.y / 120 / 10;
+ pinch.target: photoFrame
+ pinch.minimumRotation: -360
+ pinch.maximumRotation: 360
+ pinch.minimumScale: 0.1
+ pinch.maximumScale: 10
+ pinch.dragAxis: Pinch.XAndYAxis
+ onPinchStarted: setFrameColor();
+ MouseArea {
+ id: dragArea
+ hoverEnabled: true
+ anchors.fill: parent
+ drag.target: photoFrame
+ scrollGestureEnabled: false // 2-finger-flick gesture should pass through to the Flickable
+ onPressed: {
+ photoFrame.z = ++root.highestZ;
+ parent.setFrameColor();
+ }
+ onEntered: parent.setFrameColor();
+ onWheel: {
+ if (wheel.modifiers & Qt.ControlModifier) {
+ photoFrame.rotation += wheel.angleDelta.y / 120 * 5;
+ if (Math.abs(photoFrame.rotation) < 4)
+ photoFrame.rotation = 0;
+ } else {
+ photoFrame.rotation += wheel.angleDelta.x / 120;
+ if (Math.abs(photoFrame.rotation) < 0.6)
+ photoFrame.rotation = 0;
+ var scaleBefore = photoFrame.scale;
+ photoFrame.scale += photoFrame.scale * wheel.angleDelta.y / 120 / 10;
+ }
}
}
- }
- function setFrameColor() {
- if (currentFrame)
- currentFrame.border.color = "black";
- currentFrame = photoFrame;
- currentFrame.border.color = "red";
+ function setFrameColor() {
+ if (currentFrame)
+ currentFrame.border.color = "black";
+ currentFrame = photoFrame;
+ currentFrame.border.color = "red";
+ }
}
}
}
}
+ Rectangle {
+ id: verticalScrollDecorator
+ anchors.right: parent.right
+ anchors.margins: 2
+ color: "cyan"
+ border.color: "black"
+ border.width: 1
+ width: 5
+ radius: 2
+ antialiasing: true
+ height: flick.height * (flick.height / flick.contentHeight) - (width - anchors.margins) * 2
+ y: flick.contentY * (flick.height / flick.contentHeight)
+ NumberAnimation on opacity { id: vfade; to: 0; duration: 500 }
+ onYChanged: { opacity = 1.0; fadeTimer.restart() }
+ }
+
+ Rectangle {
+ id: horizontalScrollDecorator
+ anchors.bottom: parent.bottom
+ anchors.margins: 2
+ color: "cyan"
+ border.color: "black"
+ border.width: 1
+ height: 5
+ radius: 2
+ antialiasing: true
+ width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2
+ x: flick.contentX * (flick.width / flick.contentWidth)
+ NumberAnimation on opacity { id: hfade; to: 0; duration: 500 }
+ onXChanged: { opacity = 1.0; fadeTimer.restart() }
+ }
+
+ Timer { id: fadeTimer; interval: 1000; onTriggered: { hfade.start(); vfade.start() } }
+
Image {
anchors.top: parent.top
anchors.left: parent.left