Commit 108f7cec authored by Alan Alpert's avatar Alan Alpert

Upgrade Flickr demo to QtQuick 2.

And throw in particle effects.

Includes a variety of fixes to modelparticle and picture affector which
were arrived at during this demo.
parent f7d3d68c
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
id: container
......
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
id: wrapper; width: GridView.view.cellWidth; height: GridView.view.cellHeight
......
......@@ -39,8 +39,8 @@
**
****************************************************************************/
import QtQuick 1.0
import "../common" as Common
import QtQuick 2.0
import Qt.labs.particles 2.0
Flipable {
id: container
......@@ -95,7 +95,7 @@ Flipable {
Rectangle { anchors.fill: parent; color: "black"; opacity: 0.4 }
Common.Progress {
Progress {
anchors.centerIn: parent; width: 200; height: 22
progress: bigImage.progress; visible: bigImage.status != Image.Ready
}
......@@ -126,7 +126,6 @@ Flipable {
id: imageContainer
width: Math.max(bigImage.width * bigImage.scale, flickable.width);
height: Math.max(bigImage.height * bigImage.scale, flickable.height);
Image {
id: bigImage; source: container.photoUrl; scale: slider.value
anchors.centerIn: parent; smooth: !flickable.movingVertically
......@@ -137,7 +136,96 @@ Flipable {
prevScale = Math.min(slider.minimum, 1);
slider.value = prevScale;
}
if (inBackState && bigImage.status == Image.Ready)
particleBox.imageInAnim();
}
property bool inBackState: false
onInBackStateChanged:{
if(inBackState && bigImage.status == Image.Ready)
particleBox.imageInAnim();
else if (!inBackState && bigImage.status == Image.Ready)
particleBox.imageOutAnim();
}
}
Item{
id: particleBox
width: bigImage.width * bigImage.scale
height: bigImage.height * bigImage.scale
anchors.centerIn: parent
function imageInAnim(){
cp.visible = true;
pixAffect.onceOff = false;
bigImage.visible = false;
endEffectTimer.start();
pixelEmitter.pulse(1);
}
function imageOutAnim(){
cp.visible = true;
pixAffect.onceOff = true;
bigImage.visible = false;
turbulence.active = true;
endEffectTimer.start();
pixelEmitter.burst(2048);
}
Timer{
id: endEffectTimer
interval: 1000
repeat: false
running: false
onTriggered:{
bigImage.visible = true;
turbulence.active = false;
cp.visible = false;
}
}
ParticleSystem{
id: imageSystem
}
ColoredParticle{
id: cp
system: imageSystem
color: "gray"
alpha: 1
image: "images/squareParticle.png"
colorVariation: 0
}
Picture{
id: pixAffect
system: imageSystem
anchors.fill: parent
image: container.photoUrl;
onceOff: true
}
Turbulence{
id: turbulence
system: imageSystem
anchors.fill: parent
frequency: 100
strength: 250
active: false
}
TrailEmitter{
id: pixelEmitter0
system: imageSystem
height: parent.height
particleSize: 4
particleDuration: 1000
particlesPerSecond: 4096
speed: PointVector{x: 360; xVariation: 8; yVariation: 4}
emitting: false
}
TrailEmitter{
id: pixelEmitter
system: imageSystem
anchors.fill: parent
particleSize: 4
particleDuration: 1000
particlesPerSecond: 2048
emitting: false
}
}
}
}
......@@ -148,7 +236,7 @@ Flipable {
anchors.centerIn: parent; color: "white"; font.bold: true
}
Common.Slider {
Slider {
id: slider; visible: { bigImage.status == Image.Ready && maximum > minimum }
anchors {
bottom: parent.bottom; bottomMargin: 65
......@@ -174,12 +262,13 @@ Flipable {
PropertyChanges { target: itemRotation; angle: 180 }
PropertyChanges { target: toolBar; button2Visible: false }
PropertyChanges { target: toolBar; button1Label: "Back" }
PropertyChanges { target: bigImage; inBackState: true }
}
transitions: Transition {
SequentialAnimation {
PropertyAction { target: bigImage; property: "smooth"; value: false }
NumberAnimation { easing.type: Easing.InOutQuad; properties: "angle"; duration: 500 }
NumberAnimation { easing.type: Easing.InOutQuad; properties: "angle"; duration: 1000 }
PropertyAction { target: bigImage; property: "smooth"; value: !flickable.movingVertically }
}
}
......
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Component {
Item {
......
......@@ -39,9 +39,11 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
import Qt.labs.particles 2.0
Item {
Item{
id: container
property variant progress: 0
Rectangle {
......@@ -53,21 +55,34 @@ Item {
}
}
Rectangle {
ParticleSystem{
running: container.visible
id: barSys
}
ColoredParticle{
color: "lightsteelblue"
alpha: 0.1
colorVariation: 0.05
image: "images/particle.png"
system: barSys
}
TrailEmitter{
y: 2; height: parent.height-4;
x: 2; width: Math.max(parent.width * progress - 4, 0);
opacity: width < 1 ? 0 : 1; smooth: true
gradient: Gradient {
GradientStop { position: 0; color: "lightsteelblue" }
GradientStop { position: 1.0; color: "steelblue" }
}
radius: height/2 - 2
speed: AngleVector{ angleVariation: 180; magnitudeVariation: 12 }
system: barSys
particlesPerSecond: width;
particleDuration: 1000
particleSize: 20
particleSizeVariation: 4
particleEndSize: 12
maxParticles: parent.width;
}
Text {
text: Math.round(progress * 100) + "%"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "white"; font.bold: true; font.pixelSize: 15
color: Qt.rgba(1.0, 1.0 - progress, 1.0 - progress,0.9); font.bold: true; font.pixelSize: 15
}
}
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
XmlListModel {
property string tags : ""
......
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
id: container
......
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
id: slider; width: 400; height: 16
......
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
import Qt.labs.particles 2.0
Item{
id: container
property alias model: mp.model
property alias delegate: mp.delegate
property bool jumpStarted: false
ParticleSystem{
id: sys
anchors.fill:parent
overwrite: false
}
ModelParticle{
id: mp
fade: false
system: sys
anchors.fill: parent
onModelCountChanged: {
if(!jumpStarted && modelCount > 0){
console.log("Jumping");
jumpStarted = true;
sys.fastForward(8000);
}
}
}
property real emitterSpacing: parent.width/3
TrailEmitter{
system: sys
width: emitterSpacing - 64
x: emitterSpacing*0 + 32
y: -128
height: 32
speed: PointVector{ y: (container.height + 128)/12 }
particlesPerSecond: 0.4
particleDuration: 1000000//eventually -1 should mean a million seconds for neatness
maxParticles: 15
}
TrailEmitter{
system: sys
width: emitterSpacing - 64
x: emitterSpacing*1 + 32
y: -128
height: 32
speed: PointVector{ y: (container.height + 128)/12 }
particlesPerSecond: 0.4
particleDuration: 1000000//eventually -1 should mean a million seconds for neatness
maxParticles: 15
}
TrailEmitter{
system: sys
width: emitterSpacing - 64
x: emitterSpacing*2 + 32
y: -128
height: 32
speed: PointVector{ y: (container.height + 128)/12 }
particlesPerSecond: 0.4
particleDuration: 1000000//eventually -1 should mean a million seconds for neatness
maxParticles: 15
}
Kill{
system: sys
y: container.height + 64
width: container.width
height: 6400
}
}
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
id: titleBar
......
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
id: toolbar
......
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
import Qt.labs.particles 2.0
Package {
function photoClicked() {
imageDetails.photoTitle = title;
imageDetails.photoTags = tags;
imageDetails.photoWidth = photoWidth;
imageDetails.photoHeight = photoHeight;
imageDetails.photoType = photoType;
imageDetails.photoAuthor = photoAuthor;
imageDetails.photoDate = photoDate;
imageDetails.photoUrl = url;
imageDetails.rating = 0;
scaleMe.state = "Details";
}
Item {
id: gridwrapper;
width: GridView.view.cellWidth; height: GridView.view.cellHeight
Package.name: "grid"
}
Item {
id: streamwrapper;
width: 80; height: 80
Package.name: "stream"
function pleaseFreeze(){
ModelParticle.particle.freeze(streamwrapper);
}
function pleaseUnfreeze(){
ModelParticle.particle.unfreeze(streamwrapper);
}
}
Item {
//anchors.centerIn: parent//Doesn't animate :(
width: 80; height: 80
scale: 0.0
Behavior on scale { NumberAnimation { easing.type: Easing.InOutQuad} }
id: scaleMe
Item {
id: whiteRectContainer
width: 77; height: 77; anchors.centerIn: parent
Rectangle {
id: whiteRect; width: 77; height: 77; color: "#dddddd"; smooth: true
x:0; y:0
Image { id: thumb; source: imagePath; x: 1; y: 1; smooth: true }
Image { source: "images/gloss.png" }
MouseArea { anchors.fill: parent; onClicked: photoClicked() }
}
}
Connections {
target: toolBar
onButton2Clicked: if (scaleMe.state == 'Details' ) scaleMe.state = 'Show'
}
state: 'inStream'
states: [
State {
name: "Show"; when: thumb.status == Image.Ready
PropertyChanges { target: scaleMe; scale: 1; }
},
State {
name: "Details"
PropertyChanges { target: scaleMe; scale: 1 }
ParentChange { target: whiteRect; x: 10; y: 20; parent: imageDetails.frontContainer }
PropertyChanges { target: background; state: "DetailedView" }
}
]
transitions: [
Transition {
from: "Show"; to: "Details"
ScriptAction{ script: streamwrapper.pleaseFreeze(); }
ParentAnimation {
via: foreground
NumberAnimation { properties: "x,y"; duration: 500; easing.type: Easing.InOutQuad }
}
},
Transition {
from: "Details"; to: "Show"
SequentialAnimation{
ParentAnimation {
via: foreground
NumberAnimation { properties: "x,y"; duration: 500; easing.type: Easing.InOutQuad }
}
ScriptAction{ script: streamwrapper.pleaseUnfreeze(); }
}
}
]
Item{
id: stateContainer
states: [
State {
name: 'inStream'
when: screen.inGridView == false
ParentChange {
target: scaleMe; parent: streamwrapper
x: 0; y: 0;
}
},
State {
name: 'inGrid'
when: screen.inGridView == true
ParentChange {
target: scaleMe; parent: gridwrapper
x: 0; y: 0;
}
}
]
transitions: [
Transition {
ParentAnimation {
NumberAnimation { target: scaleMe; properties: 'x,y,width,height'; duration: 300 }
}
}
]
}
}
}
......@@ -39,7 +39,7 @@
**
****************************************************************************/
import QtQuick 1.0
import QtQuick 2.0
Item {
width: 480; height: 320
......
......@@ -39,21 +39,62 @@
**
****************************************************************************/
import QtQuick 1.0
import "common" as Common
import "mobile" as Mobile
import QtQuick 2.0
import Qt.labs.particles 2.0
import "content"
Item {
id: screen; width: 320; height: 480
property bool inListView : false
property bool inGridView : false
Rectangle {
id: background
anchors.fill: parent; color: "#343434";
Image { source: "mobile/images/stripes.png"; fillMode: Image.Tile; anchors.fill: parent; opacity: 0.3 }
Image { source: "content/images/stripes.png"; fillMode: Image.Tile; anchors.fill: parent; opacity: 0.3 }
ParticleSystem {
id: bgParticles
startTime: 16000
}
ColoredParticle {
particles: ["trail"]
image: "content/images/particle.png"
color: "#1A1A6F"
alpha: 0.1
colorVariation: 0.01
blueVariation: 0.8
system: bgParticles
}
TrailEmitter {
particle: "drops"
width: parent.width
particlesPerSecond: 0.5
particleDuration: 20000
speed: PointVector{
y: {screen.height/18}
}
system: bgParticles
}
FollowEmitter {
follow: "drops"
particle: "trail"
particlesPerParticlePerSecond: 18
particleSize: 32
particleEndSize: 0
particleSizeVariation: 4
particleDuration: 1200
system: bgParticles
anchors.fill: parent
emissionWidth: 16
emissionHeight: 16
emissionShape: Ellipse{}
}
Common.RssModel { id: rssModel }
VisualDataModel{
id: vdm
delegate: UnifiedDelegate{}
model: RssModel { id: rssModel }
}
Item {
id: views
......@@ -61,39 +102,38 @@ Item {
anchors.top: titleBar.bottom; anchors.bottom: toolBar.top
GridView {
id: photoGridView; model: rssModel; delegate: Mobile.GridDelegate {}
id: photoGridView; model: vdm.parts.grid
cacheBuffer: 1000
cellWidth: (parent.width-2)/4; cellHeight: cellWidth; width: parent.width; height: parent.height
}
ListView {
id: photoListView; model: rssModel; delegate: Mobile.ListDelegate { }
width: parent.width; height: parent.height; x: -(parent.width * 1.5); cacheBuffer: 100;
StreamView{
id: photoStreamView
model: vdm.parts.stream
width: parent.width; height: parent.height
}
states: State {
name: "ListView"; when: screen.inListView == true
PropertyChanges { target: photoListView; x: 0 }
PropertyChanges { target: photoGridView; x: -(parent.width * 1.5) }
name: "GridView"; when: screen.inGridView == true
}
transitions: Transition {
NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
}
Mobile.ImageDetails { id: imageDetails; width: parent.width; anchors.left: views.right; height: parent.height }
ImageDetails { id: imageDetails; width: parent.width; anchors.left: views.right; height: parent.height }
Item { id: foreground; anchors.fill: parent }
}
Mobile.TitleBar { id: titleBar; width: parent.width; height: 40; opacity: 0.9 }
TitleBar { id: titleBar; width: parent.width; height: 40; opacity: 0.9 }
Mobile.ToolBar {
ToolBar {
id: toolBar
height: 40; anchors.bottom: parent.bottom; width: parent.width; opacity: 0.9
button1Label: "Update"; button2Label: "View mode"
onButton1Clicked: rssModel.reload()
onButton2Clicked: if (screen.inListView == true) screen.inListView = false; else screen.inListView = true
onButton2Clicked: if (screen.inGridView == true) screen.inGridView = false; else screen.inGridView = true