1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 import QtQuick.Particles 2.0
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
60 property int flipDuration: 1600
66 origin.x: container.width / 2;
71 id: containerFront; anchors.fill: container
75 color: "black"; opacity: 0.4
81 left: parent.left; leftMargin: 10
82 right: parent.right; rightMargin: 10
83 top: parent.top; topMargin: 120
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 }
96 anchors.fill: container
98 Rectangle { anchors.fill: parent; color: "black"; opacity: 0.4 }
101 anchors.centerIn: parent; width: 200; height: 22
102 progress: bigImage.progress; visible: bigImage.status != Image.Ready
106 id: flickable; anchors.fill: parent; clip: true
107 contentWidth: imageContainer.width; contentHeight: imageContainer.height
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;
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;
120 prevScale = slider.value;
124 onWidthChanged: updateMinimumScale()
125 onHeightChanged: updateMinimumScale()
129 width: Math.max(bigImage.width * bigImage.scale, flickable.width);
130 height: Math.max(bigImage.height * bigImage.scale, flickable.height);
132 id: bigImage; source: container.photoUrl; scale: slider.value
133 anchors.centerIn: parent; smooth: !flickable.movingVertically
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;
141 if (inBackState && bigImage.status == Image.Ready)
142 effectBox.imageInAnim();
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();
156 //Workaround: Doesn't work below lines
157 width: bigImage.width
158 height: bigImage.width
161 Turbulence{//only fill visible rect
172 width: bigImage.width * bigImage.scale
173 height: bigImage.height * bigImage.scale
174 anchors.centerIn: parent
175 function imageInAnim(){
176 bigImage.visible = false;
177 noiseIn.visible = true;
178 endEffectTimer.start();
180 function imageOutAnim(){
181 bigImage.visible = false;
182 noiseIn.visible = false;
183 turbulence.active = true;
184 endEffectTimer.start();
185 pixelEmitter.burst(2048);
189 interval: flipDuration
193 turbulence.active = false;
194 noiseIn.visible = false;
195 bigImage.visible = true;
203 onVisibleChanged: tAnim.start()
210 duration: flipDuration
212 property variant source: pictureSource
213 property variant noise: ShaderEffectSource{
215 source: "images/noise.png"
221 uniform sampler2D noise;
222 uniform sampler2D source;
223 uniform highp float t;
224 uniform lowp float qt_Opacity;
225 varying highp vec2 qt_TexCoord0;
227 //Want to use noise2, but it always returns (0,0)?
228 if(texture2D(noise, qt_TexCoord0).w <= t)
229 gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
231 gl_FragColor = vec4(0.,0.,0.,0.);
241 //anchors.fill: parent
242 width: Math.min(bigImage.width * bigImage.scale, flickable.width);
243 height: Math.min(bigImage.height * bigImage.scale, flickable.height);
244 anchors.centerIn: parent
246 lifeSpan: flipDuration
253 property real maxWidth: effectBox.width
254 property real maxHeight: effectBox.height
256 attribute highp vec2 vPos;
257 attribute highp vec2 vTex;
258 attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
259 attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
260 attribute highp float r;
262 uniform highp float maxWidth;
263 uniform highp float maxHeight;
265 uniform highp mat4 qt_ModelViewProjectionMatrix;
266 uniform highp float timestamp;
267 uniform lowp float qt_Opacity;
269 varying highp vec2 fTex2;
270 varying lowp float fFade;
273 fTex2 = vec2(vPos.x / maxWidth, vPos.y / maxHeight);
274 highp float size = vData.z;
275 highp float endSize = vData.w;
277 highp float t = (timestamp - vData.x) / vData.y;
279 highp float currentSize = mix(size, endSize, t * t);
281 if (t < 0. || t > 1.)
284 highp vec2 pos = vPos
285 - currentSize / 2. + currentSize * vTex // adjust size
286 + vVec.xy * t * vData.y // apply speed vector..
287 + 0.5 * vVec.zw * pow(t * vData.y, 2.);
289 gl_Position = qt_ModelViewProjectionMatrix * vec4(pos.x, pos.y, 0, 1);
291 highp float fadeIn = min(t * 10., 1.);
292 highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
294 fFade = 1.0;//fadeIn * fadeOut * qt_Opacity;
297 property variant pictureTexture: pictureSource
299 uniform sampler2D pictureTexture;
300 varying highp vec2 fTex2;
301 varying highp float fFade;
303 gl_FragColor = texture2D(pictureTexture, fTex2) * fFade;
314 text: "Image Unavailable"
315 visible: bigImage.status == Image.Error
316 anchors.centerIn: parent; color: "white"; font.bold: true
320 id: slider; visible: { bigImage.status == Image.Ready && maximum > minimum }
322 bottom: parent.bottom; bottomMargin: 65
323 left: parent.left; leftMargin: 25
324 right: parent.right; rightMargin: 25
327 if (bigImage.width * value > flickable.width) {
328 var xoff = (flickable.width/2 + flickable.contentX) * value / prevScale;
329 flickable.contentX = xoff - flickable.width/2;
331 if (bigImage.height * value > flickable.height) {
332 var yoff = (flickable.height/2 + flickable.contentY) * value / prevScale;
333 flickable.contentY = yoff - flickable.height/2;
342 PropertyChanges { target: itemRotation; angle: 180 }
343 PropertyChanges { target: toolBar; button2Visible: false }
344 PropertyChanges { target: toolBar; button1Label: "Back" }
345 PropertyChanges { target: bigImage; inBackState: true }
348 transitions: Transition {
349 SequentialAnimation {
350 PropertyAction { target: bigImage; property: "smooth"; value: false }
351 NumberAnimation { easing.type: Easing.InOutQuad; properties: "angle"; duration: flipDuration }
352 PropertyAction { target: bigImage; property: "smooth"; value: !flickable.movingVertically }