Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / examples / declarative / flickr / content / ImageDetails.qml
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 import QtQuick 2.0
43 import QtQuick.Particles 2.0
44
45 Flipable {
46     id: container
47
48     property alias frontContainer: containerFront
49     property string photoTitle: ""
50     property string photoTags: ""
51     property int photoWidth
52     property int photoHeight
53     property string photoType
54     property string photoAuthor
55     property string photoDate
56     property string photoUrl
57     property int rating: 2
58     property variant prevScale: 1.0
59
60     property int flipDuration: 1600
61
62     signal closed
63
64     transform: Rotation {
65         id: itemRotation
66         origin.x: container.width / 2;
67         axis.y: 1; axis.z: 0
68     }
69
70     front: Item {
71         id: containerFront; anchors.fill: container
72
73         Rectangle {
74             anchors.fill: parent
75             color: "black"; opacity: 0.4
76         }
77
78         Column {
79             spacing: 10
80             anchors {
81                 left: parent.left; leftMargin: 10
82                 right: parent.right; rightMargin: 10
83                 top: parent.top; topMargin: 120
84             }
85             Text { font.bold: true; color: "white"; elide: Text.ElideRight; text: container.photoTitle; width: parent.width }
86             Text { color: "white"; elide: Text.ElideRight; text: "Size: " + container.photoWidth + 'x' + container.photoHeight; width: parent.width }
87             Text { color: "white"; elide: Text.ElideRight; text: "Type: " + container.photoType; width: parent.width }
88             Text { color: "white"; elide: Text.ElideRight; text: "Author: " + container.photoAuthor; width: parent.width }
89             Text { color: "white"; elide: Text.ElideRight; text: "Published: " + container.photoDate; width: parent.width }
90             Text { color: "white"; elide: Text.ElideRight; text: container.photoTags == "" ? "" : "Tags: "; width: parent.width }
91             Text { color: "white"; elide: Text.ElideRight; text: container.photoTags; width: parent.width }
92         }
93     }
94
95     back: Item {
96         anchors.fill: container
97
98         Rectangle { anchors.fill: parent; color: "black"; opacity: 0.4 }
99
100         Progress {
101             anchors.centerIn: parent; width: 200; height: 22
102             progress: bigImage.progress; visible: bigImage.status != Image.Ready
103         }
104
105         Flickable {
106             id: flickable; anchors.fill: parent; clip: true
107             contentWidth: imageContainer.width; contentHeight: imageContainer.height
108
109             function updateMinimumScale() {
110                 if (bigImage.status == Image.Ready && bigImage.width != 0) {
111                     slider.minimum = Math.min(flickable.width / bigImage.width, flickable.height / bigImage.height);
112                     if (bigImage.width * slider.value > flickable.width) {
113                         var xoff = (flickable.width/2 + flickable.contentX) * slider.value / prevScale;
114                         flickable.contentX = xoff - flickable.width/2;
115                     }
116                     if (bigImage.height * slider.value > flickable.height) {
117                         var yoff = (flickable.height/2 + flickable.contentY) * slider.value / prevScale;
118                         flickable.contentY = yoff - flickable.height/2;
119                     }
120                     prevScale = slider.value;
121                 }
122             }
123
124             onWidthChanged: updateMinimumScale()
125             onHeightChanged: updateMinimumScale()
126
127             Item {
128                 id: imageContainer
129                 width: Math.max(bigImage.width * bigImage.scale, flickable.width);
130                 height: Math.max(bigImage.height * bigImage.scale, flickable.height);
131                 Image {
132                     id: bigImage; source: container.photoUrl; scale: slider.value
133                     anchors.centerIn: parent; smooth: !flickable.movingVertically
134                     onStatusChanged : {
135                         // Default scale shows the entire image.
136                         if (bigImage.status == Image.Ready && bigImage.width != 0) {
137                             slider.minimum = Math.min(flickable.width / bigImage.width, flickable.height / bigImage.height);
138                             prevScale = Math.min(slider.minimum, 1);
139                             slider.value = prevScale;
140                         }
141                         if (inBackState && bigImage.status == Image.Ready)
142                             effectBox.imageInAnim();
143                     }
144                     property bool inBackState: false
145                     onInBackStateChanged:{
146                         if(inBackState && bigImage.status == Image.Ready)
147                             effectBox.imageInAnim();
148                         else if (!inBackState && bigImage.status == Image.Ready)
149                             effectBox.imageOutAnim();
150                     }
151                 }
152                 ShaderEffectSource{
153                     id: pictureSource
154                     sourceItem: bigImage 
155                     smooth: true
156                     //Workaround: Doesn't work below lines
157                     width: bigImage.width
158                     height: bigImage.width
159                     visible: false
160                 }
161                 Turbulence{//only fill visible rect
162                     id: turbulence
163                     system: imageSystem
164                     anchors.fill: parent 
165                     strength: 240
166                     enabled: false
167                 }
168
169                 Item{
170                     id: effectBox
171                     width: bigImage.width * bigImage.scale
172                     height: bigImage.height * bigImage.scale
173                     anchors.centerIn: parent
174                     function imageInAnim(){
175                         bigImage.visible = false;
176                         noiseIn.visible = true;
177                         endEffectTimer.start();
178                     }
179                     function imageOutAnim(){
180                         bigImage.visible = false;
181                         noiseIn.visible = false;
182                         turbulence.enabled = true;
183                         endEffectTimer.start();
184                         pixelEmitter.burst(2048);
185                     }
186                     Timer{
187                         id: endEffectTimer
188                         interval: flipDuration
189                         repeat: false
190                         running: false
191                         onTriggered:{
192                             turbulence.enabled = false;
193                             noiseIn.visible = false;
194                             bigImage.visible = true;
195                         }
196                     }
197                     ShaderEffect{
198                         id: noiseIn
199                         anchors.fill: parent
200                         property real t: 0
201                         visible: false
202                         onVisibleChanged: tAnim.start()
203                         NumberAnimation{
204                             id: tAnim
205                             target: noiseIn
206                             property: "t"
207                             from: 0.0 
208                             to: 1.0
209                             duration: flipDuration
210                         }
211                         property variant source: pictureSource
212                         property variant noise: ShaderEffectSource{
213                             sourceItem:Image{
214                                 source: "images/noise.png"
215                             }
216                             hideSource: true
217                             smooth: false
218                         }
219                         fragmentShader:"
220                             uniform sampler2D noise;
221                             uniform sampler2D source;
222                             uniform highp float t;
223                             uniform lowp float qt_Opacity;
224                             varying highp vec2 qt_TexCoord0;
225                             void main(){
226                                 //Want to use noise2, but it always returns (0,0)?
227                                 if(texture2D(noise, qt_TexCoord0).w <= t)
228                                     gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
229                                 else
230                                     gl_FragColor = vec4(0.,0.,0.,0.);
231                             }
232                         "
233                     }
234                     ParticleSystem{
235                         id: imageSystem
236                     }
237                     Emitter{
238                         id: pixelEmitter
239                         system: imageSystem
240                         //anchors.fill: parent
241                         width: Math.min(bigImage.width * bigImage.scale, flickable.width);
242                         height: Math.min(bigImage.height * bigImage.scale, flickable.height);
243                         anchors.centerIn: parent
244                         size: 4
245                         lifeSpan: flipDuration
246                         emitRate: 2048
247                         enabled: false
248                     }
249                     CustomParticle{
250                         id: blowOut
251                         system: imageSystem
252                         property real maxWidth: effectBox.width
253                         property real maxHeight: effectBox.height
254                         vertexShader:"
255                             uniform highp float maxWidth;
256                             uniform highp float maxHeight;
257
258                             varying highp vec2 fTex2;
259
260                             void main() {
261                                 defaultMain();
262                                 fTex2 = vec2(qt_ParticlePos.x / maxWidth, qt_ParticlePos.y / maxHeight);
263                             }
264                         "
265                         property variant pictureTexture: pictureSource
266                         fragmentShader: "
267                             uniform lowp float qt_Opacity;
268                             uniform sampler2D pictureTexture;
269                             varying highp vec2 fTex2;
270                             void main() {
271                                 gl_FragColor = texture2D(pictureTexture, fTex2) * qt_Opacity;
272                         }"
273                     }
274
275
276
277                 }
278             }
279         }
280
281         Text {
282             text: "Image Unavailable"
283             visible: bigImage.status == Image.Error
284             anchors.centerIn: parent; color: "white"; font.bold: true
285         }
286
287         Slider {
288             id: slider; visible: { bigImage.status == Image.Ready && maximum > minimum }
289             anchors {
290                 bottom: parent.bottom; bottomMargin: 65
291                 left: parent.left; leftMargin: 25
292                 right: parent.right; rightMargin: 25
293             }
294             onValueChanged: {
295                 if (bigImage.width * value > flickable.width) {
296                     var xoff = (flickable.width/2 + flickable.contentX) * value / prevScale;
297                     flickable.contentX = xoff - flickable.width/2;
298                 }
299                 if (bigImage.height * value > flickable.height) {
300                     var yoff = (flickable.height/2 + flickable.contentY) * value / prevScale;
301                     flickable.contentY = yoff - flickable.height/2;
302                 }
303                 prevScale = value;
304             }
305         }
306     }
307
308     states: State {
309         name: "Back"
310         PropertyChanges { target: itemRotation; angle: 180 }
311         PropertyChanges { target: toolBar; button2Visible: false }
312         PropertyChanges { target: toolBar; button1Label: "Back" }
313         PropertyChanges { target: bigImage; inBackState: true }
314     }
315
316     transitions: Transition {
317         SequentialAnimation {
318             PropertyAction { target: bigImage; property: "smooth"; value: false }
319             NumberAnimation { easing.type: Easing.InOutQuad; properties: "angle"; duration: flipDuration }
320             PropertyAction { target: bigImage; property: "smooth"; value: !flickable.movingVertically }
321         }
322     }
323 }