summaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
authorYann Bodson <yann.bodson@nokia.com>2010-03-12 05:26:37 (GMT)
committerYann Bodson <yann.bodson@nokia.com>2010-03-12 05:26:37 (GMT)
commitf42cbe210f00ab0f700c8b4ccba852b6c5a2fd26 (patch)
treedeb23ea7aae968d196fd0253cc9f32a557b29d4a /demos
parent45ef66f690966eb39b3b8ebef1708e1b87c55140 (diff)
downloadQt-f42cbe210f00ab0f700c8b4ccba852b6c5a2fd26.zip
Qt-f42cbe210f00ab0f700c8b4ccba852b6c5a2fd26.tar.gz
Qt-f42cbe210f00ab0f700c8b4ccba852b6c5a2fd26.tar.bz2
Add new declarative photoviewer demo
Diffstat (limited to 'demos')
-rw-r--r--demos/declarative/declarative.pro1
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml86
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml141
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml16
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml13
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/Tag.qml22
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/images/background.pngbin0 -> 2097 bytes
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.pngbin0 -> 588 bytes
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.pngbin0 -> 8844 bytes
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/qmldir5
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/script/script.js25
-rw-r--r--demos/declarative/photoviewer/photoviewer.qml45
12 files changed, 354 insertions, 0 deletions
diff --git a/demos/declarative/declarative.pro b/demos/declarative/declarative.pro
index 4d169e3..aa60db0 100644
--- a/demos/declarative/declarative.pro
+++ b/demos/declarative/declarative.pro
@@ -8,6 +8,7 @@ SUBDIRS = \
sources.files = \
calculator \
flickr \
+ photoviewer \
samegame \
snake \
twitter \
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml
new file mode 100644
index 0000000..0821cea
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml
@@ -0,0 +1,86 @@
+import Qt 4.6
+
+Component {
+ id: albumDelegate
+ Package {
+
+ Item {
+ Package.name: 'browser'
+ GridView {
+ id: photosGridView; model: visualModel.parts.grid; width: mainWindow.width; height: mainWindow.height - 21
+ x: 0; y: 21; cellWidth: 160; cellHeight: 153; interactive: false
+ onCurrentIndexChanged: photosListView.positionViewAtIndex(currentIndex, ListView.Contain)
+ }
+ }
+
+ Item {
+ Package.name: 'fullscreen'
+ ListView {
+ id: photosListView; model: visualModel.parts.list; orientation: Qt.Horizontal
+ width: mainWindow.width; height: mainWindow.height; interactive: false
+ onCurrentIndexChanged: photosGridView.positionViewAtIndex(currentIndex, GridView.Contain)
+ highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem
+ }
+ }
+
+ Item {
+ Package.name: 'album'
+ id: albumWrapper
+ width: 210; height: 220
+
+ VisualDataModel {
+ id: visualModel; delegate: PhotoDelegate { }
+ model: RssModel { tags: tag }
+ }
+
+ PathView {
+ id: photosPathView; model: visualModel.parts.stack
+ anchors.centerIn: parent; anchors.verticalCenterOffset: -20
+ pathItemCount: 5
+ path: Path {
+ PathAttribute { name: 'z'; value: 9999.0 }
+ PathLine { x: 1; y: 1 }
+ PathAttribute { name: 'z'; value: 0.0 }
+ }
+ }
+
+ Tag {
+ anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom
+ label: tag; rotation: Math.random() * (2 * 6 + 1) - 6
+ }
+
+ MouseArea { anchors.fill: parent; onClicked: albumWrapper.state = 'inGrid' }
+
+ states: [
+ State {
+ name: 'inGrid'
+ PropertyChanges { target: photosGridView; interactive: true }
+ PropertyChanges { target: albumsShade; opacity: 1 }
+ PropertyChanges{ target: backTag; onClicked: albumWrapper.state = ''; y: 6 }
+ },
+ State {
+ name: 'fullscreen'; extend: 'inGrid'
+ PropertyChanges { target: photosGridView; interactive: false }
+ PropertyChanges { target: photosListView; interactive: true }
+ PropertyChanges { target: photosShade; opacity: 1 }
+ PropertyChanges{ target: backTag; y: -backTag.height - 8 }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: '*'; to: 'inGrid'
+ SequentialAnimation {
+ NumberAnimation { properties: 'opacity'; duration: 250 }
+ PauseAnimation { duration: 350 }
+ NumberAnimation { target: backTag; properties: "y"; duration: 200; easing.type: "OutQuad" }
+ }
+ },
+ Transition {
+ from: 'inGrid'; to: '*'
+ NumberAnimation { properties: "y,opacity"; easing.type: "OutQuad"; duration: 300 }
+ }
+ ]
+ }
+ }
+}
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml
new file mode 100644
index 0000000..5a4e63e
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml
@@ -0,0 +1,141 @@
+import Qt 4.6
+
+Package {
+ Item { id: stackItem; Package.name: 'stack'; width: 160; height: 153; z: stackItem.PathView.z }
+ Item { id: listItem; Package.name: 'list'; width: mainWindow.width + 40; height: 153 }
+ Item { id: gridItem; Package.name: 'grid'; width: 160; height: 153 }
+
+ Item {
+ width: 160; height: 153
+
+ Item {
+ id: photoWrapper
+
+ property double randomAngle: Math.random() * (2 * 6 + 1) - 6
+ property double randomAngle2: Math.random() * (2 * 6 + 1) - 6
+
+ x: 0; y: 0; width: 140; height: 133
+ z: stackItem.PathView.z; rotation: photoWrapper.randomAngle
+
+ BorderImage {
+ anchors {
+ fill: border.visible ? border : placeHolder
+ leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8
+ }
+ source: 'images/box-shadow.png'; smooth: true
+ border.left: 10; border.top: 10; border.right: 10; border.bottom: 10
+ }
+ Rectangle {
+ id: placeHolder
+
+ property int w: getWidth(content)
+ property int h: getHeight(content)
+ property double s: calculateScale(w, h, photoWrapper.width)
+
+ color: '#898989'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3
+ width: w * s; height: h * s; visible: originalImage.status != Image.Ready
+ }
+ Rectangle {
+ id: border; color: 'white'; anchors.centerIn: parent; smooth: true
+ width: originalImage.paintedWidth + 6; height: originalImage.paintedHeight + 6
+ visible: !placeHolder.visible
+ }
+ Image {
+ id: originalImage; smooth: true; source: "http://" + getImagePath(content)
+ fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height
+ }
+ Image {
+ id: hqImage; smooth: true; source: ""; visible: false
+ fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height
+ }
+ Binding {
+ target: mainWindow; property: "downloadProgress"; value: hqImage.progress
+ when: listItem.ListView.isCurrentItem
+ }
+ Binding {
+ target: mainWindow; property: "imageLoading"
+ value: (hqImage.status == Image.Loading) ? 1 : 0; when: listItem.ListView.isCurrentItem
+ }
+ MouseArea {
+ width: originalImage.paintedWidth; height: originalImage.paintedHeight; anchors.centerIn: originalImage
+ onClicked: {
+ if (albumWrapper.state == 'inGrid') {
+ gridItem.GridView.view.currentIndex = index;
+ albumWrapper.state = 'fullscreen'
+ } else {
+ gridItem.GridView.view.currentIndex = index;
+ albumWrapper.state = 'inGrid'
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: 'stacked'; when: albumWrapper.state == ''
+ ParentChange { target: photoWrapper; parent: stackItem; x: 10; y: 10 }
+ PropertyChanges { target: photoWrapper; opacity: stackItem.PathView.onPath ? 1.0 : 0.0 }
+ },
+ State {
+ name: 'inGrid'; when: albumWrapper.state == 'inGrid'
+ ParentChange { target: photoWrapper; parent: gridItem; x: 10; y: 10; rotation: photoWrapper.randomAngle2 }
+ },
+ State {
+ name: 'fullscreen'; when: albumWrapper.state == 'fullscreen'
+ ParentChange {
+ target: photoWrapper; parent: listItem; x: 0; y: 0; rotation: 0
+ width: mainWindow.width; height: mainWindow.height
+ }
+ PropertyChanges { target: border; opacity: 0 }
+ PropertyChanges { target: hqImage; source: listItem.ListView.isCurrentItem ? hq : ""; visible: true }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: 'stacked'; to: 'inGrid'
+ SequentialAnimation {
+ PauseAnimation { duration: 10 * index }
+ ParentAnimation {
+ target: photoWrapper; via: foreground
+ NumberAnimation {
+ target: photoWrapper; properties: 'x,y,rotation,opacity'; duration: 600; easing.type: 'OutQuart'
+ }
+ }
+ }
+ },
+ Transition {
+ from: 'inGrid'; to: 'stacked'
+ ParentAnimation {
+ target: photoWrapper; via: foreground
+ NumberAnimation { properties: 'x,y,rotation,opacity'; duration: 600; easing.type: 'OutQuart' }
+ }
+ },
+ Transition {
+ from: 'inGrid'; to: 'fullscreen'
+ SequentialAnimation {
+ PauseAnimation { duration: gridItem.GridView.isCurrentItem ? 0 : 600 }
+ ParentAnimation {
+ target: photoWrapper; via: foreground
+ NumberAnimation {
+ targets: [ photoWrapper, border ]
+ properties: 'x,y,width,height,opacity,rotation'
+ duration: gridItem.GridView.isCurrentItem ? 600 : 1; easing.type: 'OutQuart'
+ }
+ }
+ }
+ },
+ Transition {
+ from: 'fullscreen'; to: 'inGrid'
+ ParentAnimation {
+ target: photoWrapper; via: foreground
+ NumberAnimation {
+ targets: [ photoWrapper, border ]
+ properties: 'x,y,width,height,rotation,opacity'
+ duration: gridItem.GridView.isCurrentItem ? 600 : 1; easing.type: 'OutQuart'
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml b/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml
new file mode 100644
index 0000000..bd6b30f
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/ProgressBar.qml
@@ -0,0 +1,16 @@
+import Qt 4.6
+
+Item {
+ id: container
+
+ property real progress: 0
+
+ Behavior on opacity { NumberAnimation { duration: 600 } }
+
+ Rectangle { anchors.fill: parent; color: "black"; opacity: 0.5 }
+
+ Rectangle {
+ id: fill; color: "white"; height: container.height
+ width: container.width * container.progress
+ }
+}
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml b/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml
new file mode 100644
index 0000000..ddbc02b
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/RssModel.qml
@@ -0,0 +1,13 @@
+import Qt 4.6
+
+XmlListModel {
+ property string tags : ""
+
+ source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")
+ query: "/feed/entry"
+ namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';"
+
+ XmlRole { name: "title"; query: "title/string()" }
+ XmlRole { name: "content"; query: "content/string()" }
+ XmlRole { name: "hq"; query: "link[@rel='enclosure']/@href/string()" }
+}
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml
new file mode 100644
index 0000000..ee11d05
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml
@@ -0,0 +1,22 @@
+import Qt 4.6
+
+Item {
+ id: container
+
+ property alias label: labelText.text
+ signal clicked
+
+ width: labelText.width + 70 ; height: labelText.height + 18
+
+ BorderImage {
+ anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 }
+ source: 'images/box-shadow.png'; smooth: true
+ border.left: 10; border.top: 10; border.right: 10; border.bottom: 10
+ }
+ Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true }
+ Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true }
+ MouseArea {
+ anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 }
+ onClicked: container.clicked()
+ }
+}
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/background.png b/demos/declarative/photoviewer/PhotoViewerCore/images/background.png
new file mode 100644
index 0000000..81d9a45
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/images/background.png
Binary files differ
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png b/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png
new file mode 100644
index 0000000..431af85
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/images/box-shadow.png
Binary files differ
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png b/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png
new file mode 100644
index 0000000..1847ab5
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/images/cardboard.png
Binary files differ
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir
new file mode 100644
index 0000000..1adce10
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir
@@ -0,0 +1,5 @@
+AlbumDelegate AlbumDelegate.qml
+PhotoDelegate PhotoDelegate.qml
+ProgressBar ProgressBar.qml
+RssModel RssModel.qml
+Tag Tag.qml
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js
new file mode 100644
index 0000000..ae24ea1
--- /dev/null
+++ b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js
@@ -0,0 +1,25 @@
+function getWidth(string) {
+ return (string.match(/width=\"([0-9]+)\"/))[1]
+}
+
+function getHeight(string) {
+ return (string.match(/height=\"([0-9]+)\"/))[1]
+}
+
+function getImagePath(string) {
+ var pattern = /src=\"http:\/\/(\S+)\"/
+ return (string.match(pattern))[1]
+}
+
+function calculateScale(width, height, cellSize) {
+ var widthScale = (cellSize * 1.0) / width
+ var heightScale = (cellSize * 1.0) / height
+ var scale = 0
+
+ if (widthScale <= heightScale) {
+ scale = widthScale;
+ } else if (heightScale < widthScale) {
+ scale = heightScale;
+ }
+ return scale;
+}
diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml
new file mode 100644
index 0000000..2b0b6a9
--- /dev/null
+++ b/demos/declarative/photoviewer/photoviewer.qml
@@ -0,0 +1,45 @@
+import Qt 4.6
+import PhotoViewerCore 1.0
+
+Image {
+ id: mainWindow
+
+ property real downloadProgress: 0
+ property bool imageLoading: false
+
+ width: 800; height: 480; source: "PhotoViewerCore/images/background.png"; fillMode: Image.Tile
+
+ Script { source: "PhotoViewerCore/script/script.js" }
+
+ ListModel {
+ id: photosModel
+ ListElement { tag: "Flowers" }
+ ListElement { tag: "Savanna" }
+ ListElement { tag: "Central Park" }
+ }
+
+ VisualDataModel {
+ id: albumVisualModel; delegate: AlbumDelegate { }
+ model: photosModel
+ }
+
+ GridView { width: parent.width; height: parent.height; cellWidth: 210; cellHeight: 220; model: albumVisualModel.parts.album }
+
+ Image {
+ id: albumsShade; source: "PhotoViewerCore/images/background.png"; fillMode: Image.Tile
+ width: parent.width; height: parent.height; opacity: 0
+ }
+
+ ListView { anchors.fill: parent; model: albumVisualModel.parts.browser; interactive: false }
+
+ Tag { id: backTag; label: "Back"; rotation: 3; x: parent.width - backTag.width - 6; y: -backTag.height - 8 }
+
+ Rectangle { id: photosShade; color: 'black'; width: parent.width; height: parent.height; opacity: 0 }
+ ListView { anchors.fill: parent; model: albumVisualModel.parts.fullscreen; interactive: false }
+ Item { id: foreground; anchors.fill: parent }
+
+ ProgressBar {
+ progress: mainWindow.downloadProgress; width: parent.width; height: 4
+ anchors.bottom: parent.bottom; opacity: mainWindow.imageLoading
+ }
+}