aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit885735d011472bcfbb96e688d9e64553d7fe9d4b (patch)
tree734963625eba643bf11bc4870a4c407809a6400a /src/imports
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.pro26
-rw-r--r--src/imports/folderlistmodel/plugin.cpp70
-rw-r--r--src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp485
-rw-r--r--src/imports/folderlistmodel/qdeclarativefolderlistmodel.h159
-rw-r--r--src/imports/folderlistmodel/qmldir1
-rw-r--r--src/imports/gestures/gestures.pro26
-rw-r--r--src/imports/gestures/plugin.cpp73
-rw-r--r--src/imports/gestures/qdeclarativegesturearea.cpp282
-rw-r--r--src/imports/gestures/qdeclarativegesturearea_p.h104
-rw-r--r--src/imports/gestures/qmldir1
-rw-r--r--src/imports/imports.pro4
-rw-r--r--src/imports/particles/particles.cpp69
-rw-r--r--src/imports/particles/particles.pro30
-rw-r--r--src/imports/particles/qdeclarativeparticles.cpp1296
-rw-r--r--src/imports/particles/qdeclarativeparticles_p.h258
-rw-r--r--src/imports/particles/qmldir1
-rw-r--r--src/imports/qimportbase.pri36
17 files changed, 2921 insertions, 0 deletions
diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro
new file mode 100644
index 0000000000..44764a91a2
--- /dev/null
+++ b/src/imports/folderlistmodel/folderlistmodel.pro
@@ -0,0 +1,26 @@
+TARGET = qmlfolderlistmodelplugin
+TARGETPATH = Qt/labs/folderlistmodel
+include(../qimportbase.pri)
+
+QT += declarative script
+
+SOURCES += qdeclarativefolderlistmodel.cpp plugin.cpp
+HEADERS += qdeclarativefolderlistmodel.h
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$PWD/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+symbian:{
+ TARGET.UID3 = 0x20021320
+
+ isEmpty(DESTDIR):importFiles.files = qmlfolderlistmodelplugin$${QT_LIBINFIX}.dll qmldir
+ else:importFiles.files = $$DESTDIR/qmlfolderlistmodelplugin$${QT_LIBINFIX}.dll qmldir
+ importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+
+ DEPLOYMENT = importFiles
+}
+
+INSTALLS += target qmldir
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
new file mode 100644
index 0000000000..724dfc5529
--- /dev/null
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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 plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
+
+#include "qdeclarativefolderlistmodel.h"
+
+QT_BEGIN_NAMESPACE
+
+//![class decl]
+class QmlFolderListModelPlugin : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel"));
+#ifndef QT_NO_DIRMODEL
+ qmlRegisterType<QDeclarativeFolderListModel>(uri,1,0,"FolderListModel");
+#endif
+ }
+};
+//![class decl]
+
+QT_END_NAMESPACE
+
+#include "plugin.moc"
+
+//![plugin export decl]
+Q_EXPORT_PLUGIN2(qmlfolderlistmodelplugin, QT_PREPEND_NAMESPACE(QmlFolderListModelPlugin));
+//![plugin export decl]
+
diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp
new file mode 100644
index 0000000000..9fe01bf22c
--- /dev/null
+++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp
@@ -0,0 +1,485 @@
+/****************************************************************************
+**
+** 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 examples 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$
+**
+****************************************************************************/
+
+//![code]
+#include "qdeclarativefolderlistmodel.h"
+#include <QDirModel>
+#include <QDebug>
+#include <qdeclarativecontext.h>
+
+#ifndef QT_NO_DIRMODEL
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeFolderListModelPrivate
+{
+public:
+ QDeclarativeFolderListModelPrivate()
+ : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0) {
+ nameFilters << QLatin1String("*");
+ }
+
+ void updateSorting() {
+ QDir::SortFlags flags = 0;
+ switch(sortField) {
+ case QDeclarativeFolderListModel::Unsorted:
+ flags |= QDir::Unsorted;
+ break;
+ case QDeclarativeFolderListModel::Name:
+ flags |= QDir::Name;
+ break;
+ case QDeclarativeFolderListModel::Time:
+ flags |= QDir::Time;
+ break;
+ case QDeclarativeFolderListModel::Size:
+ flags |= QDir::Size;
+ break;
+ case QDeclarativeFolderListModel::Type:
+ flags |= QDir::Type;
+ break;
+ }
+
+ if (sortReversed)
+ flags |= QDir::Reversed;
+
+ model.setSorting(flags);
+ }
+
+ QDirModel model;
+ QUrl folder;
+ QStringList nameFilters;
+ QModelIndex folderIndex;
+ QDeclarativeFolderListModel::SortField sortField;
+ bool sortReversed;
+ int count;
+};
+
+/*!
+ \qmlclass FolderListModel QDeclarativeFolderListModel
+ \ingroup qml-working-with-data
+ \brief The FolderListModel provides a model of the contents of a file system folder.
+
+ FolderListModel provides access to information about the contents of a folder
+ in the local file system, exposing a list of files to views and other data components.
+
+ \note This type is made available by importing the \c Qt.labs.folderlistmodel module.
+ \e{Elements in the Qt.labs module are not guaranteed to remain compatible
+ in future versions.}
+
+ \bold{import Qt.labs.folderlistmodel 1.0}
+
+ The \l folder property specifies the folder to access. Information about the
+ files and directories in the folder is supplied via the model's interface.
+ Components access names and paths via the following roles:
+
+ \list
+ \o fileName
+ \o filePath
+ \endlist
+
+ Additionally a file entry can be differentiated from a folder entry via the
+ isFolder() method.
+
+ \section1 Filtering
+
+ Various properties can be set to filter the number of files and directories
+ exposed by the model.
+
+ The \l nameFilters property can be set to contain a list of wildcard filters
+ that are applied to names of files and directories, causing only those that
+ match the filters to be exposed.
+
+ Directories can be included or excluded using the \l showDirs property, and
+ navigation directories can also be excluded by setting the \l showDotAndDotDot
+ property to false.
+
+ It is sometimes useful to limit the files and directories exposed to those
+ that the user can access. The \l showOnlyReadable property can be set to
+ enable this feature.
+
+ \section1 Example Usage
+
+ The following example shows a FolderListModel being used to provide a list
+ of QML files in a \l ListView:
+
+ \snippet doc/src/snippets/declarative/folderlistmodel.qml 0
+
+ \section1 Path Separators
+
+ Qt uses "/" as a universal directory separator in the same way that "/" is
+ used as a path separator in URLs. If you always use "/" as a directory
+ separator, Qt will translate your paths to conform to the underlying
+ operating system.
+
+ \sa {QML Data Models}
+*/
+
+QDeclarativeFolderListModel::QDeclarativeFolderListModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+ QHash<int, QByteArray> roles;
+ roles[FileNameRole] = "fileName";
+ roles[FilePathRole] = "filePath";
+ setRoleNames(roles);
+
+ d = new QDeclarativeFolderListModelPrivate;
+ d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot);
+ connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int))
+ , this, SLOT(inserted(const QModelIndex&,int,int)));
+ connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int))
+ , this, SLOT(removed(const QModelIndex&,int,int)));
+ connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&))
+ , this, SLOT(handleDataChanged(const QModelIndex&,const QModelIndex&)));
+ connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh()));
+ connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh()));
+}
+
+QDeclarativeFolderListModel::~QDeclarativeFolderListModel()
+{
+ delete d;
+}
+
+QVariant QDeclarativeFolderListModel::data(const QModelIndex &index, int role) const
+{
+ QVariant rv;
+ QModelIndex modelIndex = d->model.index(index.row(), 0, d->folderIndex);
+ if (modelIndex.isValid()) {
+ if (role == FileNameRole)
+ rv = d->model.data(modelIndex, QDirModel::FileNameRole).toString();
+ else if (role == FilePathRole)
+ rv = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString());
+ }
+ return rv;
+}
+
+/*!
+ \qmlproperty int FolderListModel::count
+
+ Returns the number of items in the current folder that match the
+ filter criteria.
+*/
+int QDeclarativeFolderListModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return d->count;
+}
+
+/*!
+ \qmlproperty string FolderListModel::folder
+
+ The \a folder property holds a URL for the folder that the model is
+ currently providing.
+
+ The value is a URL expressed as a string, and must be a \c file: or \c qrc:
+ URL, or a relative URL.
+
+ By default, the value is an invalid URL.
+*/
+QUrl QDeclarativeFolderListModel::folder() const
+{
+ return d->folder;
+}
+
+void QDeclarativeFolderListModel::setFolder(const QUrl &folder)
+{
+ if (folder == d->folder)
+ return;
+ QModelIndex index = d->model.index(folder.toLocalFile());
+ if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) {
+
+ d->folder = folder;
+ QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
+ emit folderChanged();
+ }
+}
+
+/*!
+ \qmlproperty url FolderListModel::parentFolder
+
+ Returns the URL of the parent of of the current \l folder.
+*/
+QUrl QDeclarativeFolderListModel::parentFolder() const
+{
+ QString localFile = d->folder.toLocalFile();
+ if (!localFile.isEmpty()) {
+ QDir dir(localFile);
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN)
+ if (dir.isRoot())
+ dir.setPath("");
+ else
+#endif
+ dir.cdUp();
+ localFile = dir.path();
+ } else {
+ int pos = d->folder.path().lastIndexOf(QLatin1Char('/'));
+ if (pos == -1)
+ return QUrl();
+ localFile = d->folder.path().left(pos);
+ }
+ return QUrl::fromLocalFile(localFile);
+}
+
+/*!
+ \qmlproperty list<string> FolderListModel::nameFilters
+
+ The \a nameFilters property contains a list of file name filters.
+ The filters may include the ? and * wildcards.
+
+ The example below filters on PNG and JPEG files:
+
+ \qml
+ FolderListModel {
+ nameFilters: [ "*.png", "*.jpg" ]
+ }
+ \endqml
+
+ \note Directories are not excluded by filters.
+*/
+QStringList QDeclarativeFolderListModel::nameFilters() const
+{
+ return d->nameFilters;
+}
+
+void QDeclarativeFolderListModel::setNameFilters(const QStringList &filters)
+{
+ d->nameFilters = filters;
+ d->model.setNameFilters(d->nameFilters);
+}
+
+void QDeclarativeFolderListModel::classBegin()
+{
+}
+
+void QDeclarativeFolderListModel::componentComplete()
+{
+ if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile()))
+ setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
+
+ if (!d->folderIndex.isValid())
+ QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
+}
+
+/*!
+ \qmlproperty enumeration FolderListModel::sortField
+
+ The \a sortField property contains field to use for sorting. sortField
+ may be one of:
+ \list
+ \o Unsorted - no sorting is applied. The order is system default.
+ \o Name - sort by filename
+ \o Time - sort by time modified
+ \o Size - sort by file size
+ \o Type - sort by file type (extension)
+ \endlist
+
+ \sa sortReversed
+*/
+QDeclarativeFolderListModel::SortField QDeclarativeFolderListModel::sortField() const
+{
+ return d->sortField;
+}
+
+void QDeclarativeFolderListModel::setSortField(SortField field)
+{
+ if (field != d->sortField) {
+ d->sortField = field;
+ d->updateSorting();
+ }
+}
+
+/*!
+ \qmlproperty bool FolderListModel::sortReversed
+
+ If set to true, reverses the sort order. The default is false.
+
+ \sa sortField
+*/
+bool QDeclarativeFolderListModel::sortReversed() const
+{
+ return d->sortReversed;
+}
+
+void QDeclarativeFolderListModel::setSortReversed(bool rev)
+{
+ if (rev != d->sortReversed) {
+ d->sortReversed = rev;
+ d->updateSorting();
+ }
+}
+
+/*!
+ \qmlmethod bool FolderListModel::isFolder(int index)
+
+ Returns true if the entry \a index is a folder; otherwise
+ returns false.
+*/
+bool QDeclarativeFolderListModel::isFolder(int index) const
+{
+ if (index != -1) {
+ QModelIndex idx = d->model.index(index, 0, d->folderIndex);
+ if (idx.isValid())
+ return d->model.isDir(idx);
+ }
+ return false;
+}
+
+void QDeclarativeFolderListModel::refresh()
+{
+ d->folderIndex = QModelIndex();
+ if (d->count) {
+ emit beginRemoveRows(QModelIndex(), 0, d->count-1);
+ d->count = 0;
+ emit endRemoveRows();
+ }
+ d->folderIndex = d->model.index(d->folder.toLocalFile());
+ int newcount = d->model.rowCount(d->folderIndex);
+ if (newcount) {
+ emit beginInsertRows(QModelIndex(), 0, newcount-1);
+ d->count = newcount;
+ emit endInsertRows();
+ }
+}
+
+void QDeclarativeFolderListModel::inserted(const QModelIndex &index, int start, int end)
+{
+ if (index == d->folderIndex) {
+ emit beginInsertRows(QModelIndex(), start, end);
+ d->count = d->model.rowCount(d->folderIndex);
+ emit endInsertRows();
+ }
+}
+
+void QDeclarativeFolderListModel::removed(const QModelIndex &index, int start, int end)
+{
+ if (index == d->folderIndex) {
+ emit beginRemoveRows(QModelIndex(), start, end);
+ d->count = d->model.rowCount(d->folderIndex);
+ emit endRemoveRows();
+ }
+}
+
+void QDeclarativeFolderListModel::handleDataChanged(const QModelIndex &start, const QModelIndex &end)
+{
+ if (start.parent() == d->folderIndex)
+ emit dataChanged(index(start.row(),0), index(end.row(),0));
+}
+
+/*!
+ \qmlproperty bool FolderListModel::showDirs
+
+ If true, directories are included in the model; otherwise only files
+ are included.
+
+ By default, this property is true.
+
+ Note that the nameFilters are not applied to directories.
+
+ \sa showDotAndDotDot
+*/
+bool QDeclarativeFolderListModel::showDirs() const
+{
+ return d->model.filter() & QDir::AllDirs;
+}
+
+void QDeclarativeFolderListModel::setShowDirs(bool on)
+{
+ if (!(d->model.filter() & QDir::AllDirs) == !on)
+ return;
+ if (on)
+ d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives);
+ else
+ d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives));
+}
+
+/*!
+ \qmlproperty bool FolderListModel::showDotAndDotDot
+
+ If true, the "." and ".." directories are included in the model; otherwise
+ they are excluded.
+
+ By default, this property is false.
+
+ \sa showDirs
+*/
+bool QDeclarativeFolderListModel::showDotAndDotDot() const
+{
+ return !(d->model.filter() & QDir::NoDotAndDotDot);
+}
+
+void QDeclarativeFolderListModel::setShowDotAndDotDot(bool on)
+{
+ if (!(d->model.filter() & QDir::NoDotAndDotDot) == on)
+ return;
+ if (on)
+ d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot);
+ else
+ d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot);
+}
+
+/*!
+ \qmlproperty bool FolderListModel::showOnlyReadable
+
+ If true, only readable files and directories are shown; otherwise all files
+ and directories are shown.
+
+ By default, this property is false.
+
+ \sa showDirs
+*/
+bool QDeclarativeFolderListModel::showOnlyReadable() const
+{
+ return d->model.filter() & QDir::Readable;
+}
+
+void QDeclarativeFolderListModel::setShowOnlyReadable(bool on)
+{
+ if (!(d->model.filter() & QDir::Readable) == !on)
+ return;
+ if (on)
+ d->model.setFilter(d->model.filter() | QDir::Readable);
+ else
+ d->model.setFilter(d->model.filter() & ~QDir::Readable);
+}
+
+//![code]
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRMODEL
diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h
new file mode 100644
index 0000000000..17dc84c026
--- /dev/null
+++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** 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 examples 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEFOLDERLISTMODEL_H
+#define QDECLARATIVEFOLDERLISTMODEL_H
+
+#include <qdeclarative.h>
+#include <QStringList>
+#include <QUrl>
+#include <QAbstractListModel>
+
+#ifndef QT_NO_DIRMODEL
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeContext;
+class QModelIndex;
+
+class QDeclarativeFolderListModelPrivate;
+
+//![class begin]
+class QDeclarativeFolderListModel : public QAbstractListModel, public QDeclarativeParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QDeclarativeParserStatus)
+//![class begin]
+
+//![class props]
+ Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
+ Q_PROPERTY(QUrl parentFolder READ parentFolder NOTIFY folderChanged)
+ Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
+ Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
+ Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed)
+ Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs)
+ Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
+ Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
+ Q_PROPERTY(int count READ count)
+//![class props]
+
+//![abslistmodel]
+public:
+ QDeclarativeFolderListModel(QObject *parent = 0);
+ ~QDeclarativeFolderListModel();
+
+ enum Roles { FileNameRole = Qt::UserRole+1, FilePathRole = Qt::UserRole+2 };
+
+ int rowCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+//![abslistmodel]
+
+//![count]
+ int count() const { return rowCount(QModelIndex()); }
+//![count]
+
+//![prop funcs]
+ QUrl folder() const;
+ void setFolder(const QUrl &folder);
+
+ QUrl parentFolder() const;
+
+ QStringList nameFilters() const;
+ void setNameFilters(const QStringList &filters);
+
+ enum SortField { Unsorted, Name, Time, Size, Type };
+ SortField sortField() const;
+ void setSortField(SortField field);
+ Q_ENUMS(SortField)
+
+ bool sortReversed() const;
+ void setSortReversed(bool rev);
+
+ bool showDirs() const;
+ void setShowDirs(bool);
+ bool showDotAndDotDot() const;
+ void setShowDotAndDotDot(bool);
+ bool showOnlyReadable() const;
+ void setShowOnlyReadable(bool);
+//![prop funcs]
+
+//![isfolder]
+ Q_INVOKABLE bool isFolder(int index) const;
+//![isfolder]
+
+//![parserstatus]
+ virtual void classBegin();
+ virtual void componentComplete();
+//![parserstatus]
+
+//![notifier]
+Q_SIGNALS:
+ void folderChanged();
+//![notifier]
+
+//![class end]
+private Q_SLOTS:
+ void refresh();
+ void inserted(const QModelIndex &index, int start, int end);
+ void removed(const QModelIndex &index, int start, int end);
+ void handleDataChanged(const QModelIndex &start, const QModelIndex &end);
+
+private:
+ Q_DISABLE_COPY(QDeclarativeFolderListModel)
+ QDeclarativeFolderListModelPrivate *d;
+};
+//![class end]
+
+QT_END_NAMESPACE
+
+//![qml decl]
+QML_DECLARE_TYPE(QDeclarativeFolderListModel)
+//![qml decl]
+
+QT_END_HEADER
+
+#endif // QT_NO_DIRMODEL
+
+#endif // QDECLARATIVEFOLDERLISTMODEL_H
diff --git a/src/imports/folderlistmodel/qmldir b/src/imports/folderlistmodel/qmldir
new file mode 100644
index 0000000000..6e115bbc7e
--- /dev/null
+++ b/src/imports/folderlistmodel/qmldir
@@ -0,0 +1 @@
+plugin qmlfolderlistmodelplugin
diff --git a/src/imports/gestures/gestures.pro b/src/imports/gestures/gestures.pro
new file mode 100644
index 0000000000..ad872bae3f
--- /dev/null
+++ b/src/imports/gestures/gestures.pro
@@ -0,0 +1,26 @@
+TARGET = qmlgesturesplugin
+TARGETPATH = Qt/labs/gestures
+include(../qimportbase.pri)
+
+QT += declarative
+
+SOURCES += qdeclarativegesturearea.cpp plugin.cpp
+HEADERS += qdeclarativegesturearea_p.h
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$PWD/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+symbian:{
+ TARGET.UID3 = 0x2002131F
+
+ isEmpty(DESTDIR):importFiles.files = qmlgesturesplugin$${QT_LIBINFIX}.dll qmldir
+ else:importFiles.files = $$DESTDIR/qmlgesturesplugin$${QT_LIBINFIX}.dll qmldir
+ importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+
+ DEPLOYMENT = importFiles
+}
+
+INSTALLS += target qmldir
diff --git a/src/imports/gestures/plugin.cpp b/src/imports/gestures/plugin.cpp
new file mode 100644
index 0000000000..9ebfb9bd70
--- /dev/null
+++ b/src/imports/gestures/plugin.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 plugins 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$
+**
+****************************************************************************/
+
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
+
+#include "qdeclarativegesturearea_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class GestureAreaQmlPlugin : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.gestures"));
+#ifndef QT_NO_GESTURES
+ qmlRegisterCustomType<QDeclarativeGestureArea>(uri,1,0, "GestureArea", new QDeclarativeGestureAreaParser);
+
+ qmlRegisterUncreatableType<QGesture>(uri, 1, 0, "Gesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QPanGesture>(uri, 1, 0, "PanGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QTapGesture>(uri, 1, 0, "TapGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QTapAndHoldGesture>(uri, 1, 0, "TapAndHoldGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QPinchGesture>(uri, 1, 0, "PinchGesture", QLatin1String("Do not create objects of this type."));
+ qmlRegisterUncreatableType<QSwipeGesture>(uri, 1, 0, "SwipeGesture", QLatin1String("Do not create objects of this type."));
+#endif
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "plugin.moc"
+
+Q_EXPORT_PLUGIN2(qmlgesturesplugin, QT_PREPEND_NAMESPACE(GestureAreaQmlPlugin));
diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp
new file mode 100644
index 0000000000..aae6a010f1
--- /dev/null
+++ b/src/imports/gestures/qdeclarativegesturearea.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qdeclarativegesturearea_p.h"
+
+#include <qdeclarativeexpression.h>
+#include <qdeclarativecontext.h>
+#include <qdeclarativeinfo.h>
+
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativeitem_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstringlist.h>
+
+#include <QtGui/qevent.h>
+
+#include <private/qobject_p.h>
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeGestureAreaPrivate : public QDeclarativeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeGestureArea)
+public:
+ QDeclarativeGestureAreaPrivate() : componentcomplete(false), gesture(0) {}
+
+ typedef QMap<Qt::GestureType,QDeclarativeExpression*> Bindings;
+ Bindings bindings;
+
+ bool componentcomplete;
+
+ QByteArray data;
+
+ QGesture *gesture;
+
+ bool gestureEvent(QGestureEvent *event);
+};
+
+/*!
+ \qmlclass GestureArea QDeclarativeGestureArea
+ \ingroup qml-basic-interaction-elements
+
+ \brief The GestureArea item enables simple gesture handling.
+ \inherits Item
+
+ A GestureArea is like a MouseArea, but it has signals for gesture events.
+
+ \warning Elements in the Qt.labs module are not guaranteed to remain compatible
+ in future versions.
+
+ \warning GestureArea is an experimental element whose development has
+ been discontinued. PinchArea is available in QtQuick 1.1 and handles
+ two finger gesture input.
+
+ \note This element is only functional on devices with touch input.
+
+ \qml
+ import Qt.labs.gestures 1.0
+
+ GestureArea {
+ anchors.fill: parent
+ // onPan: ... gesture.acceleration ...
+ // onPinch: ... gesture.rotationAngle ...
+ // onSwipe: ...
+ // onTapAndHold: ...
+ // onTap: ...
+ // onGesture: ...
+ }
+ \endqml
+
+ Each signal has a \e gesture parameter that has the
+ properties of the gesture.
+
+ \table
+ \header \o Signal \o Type \o Property \o Description
+ \row \o onTap \o point \o position \o the position of the tap
+ \row \o onTapAndHold \o point \o position \o the position of the tap
+ \row \o onPan \o real \o acceleration \o the acceleration of the pan
+ \row \o onPan \o point \o delta \o the offset from the previous input position to the current input
+ \row \o onPan \o point \o offset \o the total offset from the first input position to the current input position
+ \row \o onPan \o point \o lastOffset \o the previous value of offset
+ \row \o onPinch \o point \o centerPoint \o the midpoint between the two input points
+ \row \o onPinch \o point \o lastCenterPoint \o the previous value of centerPoint
+ \row \o onPinch \o point \o startCenterPoint \o the first value of centerPoint
+ \row \o onPinch \o real \o rotationAngle \o the angle covered by the gesture motion
+ \row \o onPinch \o real \o lastRotationAngle \o the previous value of rotationAngle
+ \row \o onPinch \o real \o totalRotationAngle \o the complete angle covered by the gesture
+ \row \o onPinch \o real \o scaleFactor \o the change in distance between the two input points
+ \row \o onPinch \o real \o lastScaleFactor \o the previous value of scaleFactor
+ \row \o onPinch \o real \o totalScaleFactor \o the complete scale factor of the gesture
+ \row \o onSwipe \o real \o swipeAngle \o the angle of the swipe
+ \endtable
+
+ Custom gestures, handled by onGesture, will have custom properties.
+
+ GestureArea is an invisible item: it is never painted.
+
+ \sa MouseArea
+*/
+
+/*!
+ \internal
+ \class QDeclarativeGestureArea
+ \brief The QDeclarativeGestureArea class provides simple gesture handling.
+
+*/
+QDeclarativeGestureArea::QDeclarativeGestureArea(QDeclarativeItem *parent) :
+ QDeclarativeItem(*(new QDeclarativeGestureAreaPrivate), parent)
+{
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptTouchEvents(true);
+}
+
+QDeclarativeGestureArea::~QDeclarativeGestureArea()
+{
+}
+
+QByteArray
+QDeclarativeGestureAreaParser::compile(const QList<QDeclarativeCustomParserProperty> &props)
+{
+ QByteArray rv;
+ QDataStream ds(&rv, QIODevice::WriteOnly);
+
+ for(int ii = 0; ii < props.count(); ++ii)
+ {
+ QString propName = QString::fromUtf8(props.at(ii).name());
+ Qt::GestureType type;
+
+ if (propName == QLatin1String("onTap")) {
+ type = Qt::TapGesture;
+ } else if (propName == QLatin1String("onTapAndHold")) {
+ type = Qt::TapAndHoldGesture;
+ } else if (propName == QLatin1String("onPan")) {
+ type = Qt::PanGesture;
+ } else if (propName == QLatin1String("onPinch")) {
+ type = Qt::PinchGesture;
+ } else if (propName == QLatin1String("onSwipe")) {
+ type = Qt::SwipeGesture;
+ } else if (propName == QLatin1String("onGesture")) {
+ type = Qt::CustomGesture;
+ } else {
+ error(props.at(ii), QDeclarativeGestureArea::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
+ return QByteArray();
+ }
+
+ QList<QVariant> values = props.at(ii).assignedValues();
+
+ for (int i = 0; i < values.count(); ++i) {
+ const QVariant &value = values.at(i);
+
+ if (value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) {
+ error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: nested objects not allowed"));
+ return QByteArray();
+ } else if (value.userType() == qMetaTypeId<QDeclarativeCustomParserProperty>()) {
+ error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: syntax error"));
+ return QByteArray();
+ } else {
+ QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(value);
+ if (v.isScript()) {
+ ds << propName;
+ ds << int(type);
+ ds << v.asScript();
+ } else {
+ error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: script expected"));
+ return QByteArray();
+ }
+ }
+ }
+ }
+
+ return rv;
+}
+
+void QDeclarativeGestureAreaParser::setCustomData(QObject *object,
+ const QByteArray &data)
+{
+ QDeclarativeGestureArea *ga = static_cast<QDeclarativeGestureArea*>(object);
+ ga->d_func()->data = data;
+}
+
+
+void QDeclarativeGestureArea::connectSignals()
+{
+ Q_D(QDeclarativeGestureArea);
+ if (!d->componentcomplete)
+ return;
+
+ QDataStream ds(d->data);
+ while (!ds.atEnd()) {
+ QString propName;
+ ds >> propName;
+ int gesturetype;
+ ds >> gesturetype;
+ QString script;
+ ds >> script;
+ QDeclarativeExpression *exp = new QDeclarativeExpression(qmlContext(this), this, script);
+ d->bindings.insert(Qt::GestureType(gesturetype),exp);
+ grabGesture(Qt::GestureType(gesturetype));
+ }
+}
+
+void QDeclarativeGestureArea::componentComplete()
+{
+ QDeclarativeItem::componentComplete();
+ Q_D(QDeclarativeGestureArea);
+ d->componentcomplete=true;
+ connectSignals();
+}
+
+QGesture *QDeclarativeGestureArea::gesture() const
+{
+ Q_D(const QDeclarativeGestureArea);
+ return d->gesture;
+}
+
+bool QDeclarativeGestureArea::sceneEvent(QEvent *event)
+{
+ Q_D(QDeclarativeGestureArea);
+ if (event->type() == QEvent::Gesture)
+ return d->gestureEvent(static_cast<QGestureEvent*>(event));
+ return QDeclarativeItem::sceneEvent(event);
+}
+
+bool QDeclarativeGestureAreaPrivate::gestureEvent(QGestureEvent *event)
+{
+ bool accept = true;
+ for (Bindings::Iterator it = bindings.begin(); it != bindings.end(); ++it) {
+ if ((gesture = event->gesture(it.key()))) {
+ QDeclarativeExpression *expr = it.value();
+ expr->evaluate();
+ if (expr->hasError())
+ qmlInfo(q_func()) << expr->error();
+ event->setAccepted(true); // XXX only if value returns true?
+ }
+ }
+ return accept;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/src/imports/gestures/qdeclarativegesturearea_p.h b/src/imports/gestures/qdeclarativegesturearea_p.h
new file mode 100644
index 0000000000..01306045bb
--- /dev/null
+++ b/src/imports/gestures/qdeclarativegesturearea_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEGESTUREAREA_H
+#define QDECLARATIVEGESTUREAREA_H
+
+#include <qdeclarativeitem.h>
+#include <qdeclarativescriptstring.h>
+#include <private/qdeclarativecustomparser_p.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qgesture.h>
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeBoundSignal;
+class QDeclarativeContext;
+class QDeclarativeGestureAreaPrivate;
+class QDeclarativeGestureArea : public QDeclarativeItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QGesture *gesture READ gesture)
+
+public:
+ QDeclarativeGestureArea(QDeclarativeItem *parent=0);
+ ~QDeclarativeGestureArea();
+
+ QGesture *gesture() const;
+
+protected:
+ bool sceneEvent(QEvent *event);
+
+private:
+ void connectSignals();
+ void componentComplete();
+ friend class QDeclarativeGestureAreaParser;
+
+ Q_DISABLE_COPY(QDeclarativeGestureArea)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeGestureArea)
+};
+
+class QDeclarativeGestureAreaParser : public QDeclarativeCustomParser
+{
+public:
+ virtual QByteArray compile(const QList<QDeclarativeCustomParserProperty> &);
+ virtual void setCustomData(QObject *, const QByteArray &);
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeGestureArea)
+
+QT_END_HEADER
+
+#endif // QT_NO_GESTURES
+
+#endif
diff --git a/src/imports/gestures/qmldir b/src/imports/gestures/qmldir
new file mode 100644
index 0000000000..2a31920a40
--- /dev/null
+++ b/src/imports/gestures/qmldir
@@ -0,0 +1 @@
+plugin qmlgesturesplugin
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
new file mode 100644
index 0000000000..5e50b08da8
--- /dev/null
+++ b/src/imports/imports.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += folderlistmodel particles gestures
+
diff --git a/src/imports/particles/particles.cpp b/src/imports/particles/particles.cpp
new file mode 100644
index 0000000000..ca2b0609cb
--- /dev/null
+++ b/src/imports/particles/particles.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
+
+#include "qdeclarativeparticles_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QParticlesQmlModule : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.particles"));
+ qmlRegisterType<QDeclarativeParticleMotion>(uri,1,0,"ParticleMotion");
+ qmlRegisterType<QDeclarativeParticleMotionGravity>(uri,1,0,"ParticleMotionGravity");
+ qmlRegisterType<QDeclarativeParticleMotionLinear>(uri,1,0,"ParticleMotionLinear");
+ qmlRegisterType<QDeclarativeParticleMotionWander>(uri,1,0,"ParticleMotionWander");
+ qmlRegisterType<QDeclarativeParticles>(uri,1,0,"Particles");
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "particles.moc"
+
+Q_EXPORT_PLUGIN2(qmlparticlesplugin, QT_PREPEND_NAMESPACE(QParticlesQmlModule));
+
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
new file mode 100644
index 0000000000..90b50e4659
--- /dev/null
+++ b/src/imports/particles/particles.pro
@@ -0,0 +1,30 @@
+TARGET = qmlparticlesplugin
+TARGETPATH = Qt/labs/particles
+include(../qimportbase.pri)
+
+QT += declarative
+
+SOURCES += \
+ qdeclarativeparticles.cpp \
+ particles.cpp
+
+HEADERS += \
+ qdeclarativeparticles_p.h
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$PWD/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+symbian:{
+ TARGET.UID3 = 0x2002131E
+
+ isEmpty(DESTDIR):importFiles.files = qmlparticlesplugin$${QT_LIBINFIX}.dll qmldir
+ else:importFiles.files = $$DESTDIR/qmlparticlesplugin$${QT_LIBINFIX}.dll qmldir
+ importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+
+ DEPLOYMENT = importFiles
+}
+
+INSTALLS += target qmldir
diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp
new file mode 100644
index 0000000000..f54152c054
--- /dev/null
+++ b/src/imports/particles/qdeclarativeparticles.cpp
@@ -0,0 +1,1296 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qdeclarativeparticles_p.h"
+
+#include <qdeclarativeinfo.h>
+#include <private/qdeclarativeitem_p.h>
+
+#include <private/qdeclarativepixmapcache_p.h>
+#include <QtCore/QAbstractAnimation>
+
+#include <QPainter>
+#include <QtGui/qdrawutil.h>
+#include <QVarLengthArray>
+
+#include <stdlib.h>
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#define M_PI_2 (M_PI / 2.)
+#endif
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+QT_BEGIN_NAMESPACE
+#define PI_SQR 9.8696044
+// parabolic approximation
+inline qreal fastSin(qreal theta)
+{
+ const qreal b = 4 / M_PI;
+ const qreal c = -4 / PI_SQR;
+
+ qreal y = b * theta + c * theta * qAbs(theta);
+ return y;
+}
+
+inline qreal fastCos(qreal theta)
+{
+ theta += M_PI_2;
+ if (theta > M_PI)
+ theta -= 2 * M_PI;
+
+ return fastSin(theta);
+}
+
+class QDeclarativeParticle
+{
+public:
+ QDeclarativeParticle(int time) : lifeSpan(1000), fadeOutAge(800)
+ , opacity(0), birthTime(time), x_velocity(0), y_velocity(0)
+ , state(FadeIn), data(0)
+ {
+ }
+
+ int lifeSpan;
+ int fadeOutAge;
+ qreal x;
+ qreal y;
+ qreal opacity;
+ int birthTime;
+ qreal x_velocity;
+ qreal y_velocity;
+ enum State { FadeIn, Solid, FadeOut };
+ State state;
+ void *data;
+};
+
+//---------------------------------------------------------------------------
+
+/*!
+ \class QDeclarativeParticleMotion
+ \ingroup group_effects
+ \brief The QDeclarativeParticleMotion class is the base class for particle motion.
+ \internal
+
+ This class causes the particles to remain static.
+*/
+
+/*!
+ Constructs a QDeclarativeParticleMotion with parent object \a parent.
+*/
+QDeclarativeParticleMotion::QDeclarativeParticleMotion(QObject *parent) :
+ QObject(parent)
+{
+}
+
+/*!
+ Move the \a particle to its new position. \a interval is the number of
+ milliseconds elapsed since it was last moved.
+*/
+void QDeclarativeParticleMotion::advance(QDeclarativeParticle &particle, int interval)
+{
+ Q_UNUSED(particle);
+ Q_UNUSED(interval);
+}
+
+/*!
+ The \a particle has just been created. Some motion strategies require
+ additional state information. This can be allocated by this function.
+*/
+void QDeclarativeParticleMotion::created(QDeclarativeParticle &particle)
+{
+ Q_UNUSED(particle);
+}
+
+/*!
+ The \a particle is about to be destroyed. Any additional memory
+ that has been allocated for the particle should be freed.
+*/
+void QDeclarativeParticleMotion::destroy(QDeclarativeParticle &particle)
+{
+ Q_UNUSED(particle);
+}
+
+/*!
+ \qmlclass ParticleMotionLinear QDeclarativeParticleMotionLinear
+ \ingroup qml-particle-elements
+ \since 4.7
+ \brief The ParticleMotionLinear object moves particles linearly.
+
+ \sa Particles
+
+ This is the default motion, and moves the particles according to the
+ properties specified in the Particles element.
+
+ It has no further properties.
+*/
+void QDeclarativeParticleMotionLinear::advance(QDeclarativeParticle &p, int interval)
+{
+ p.x += interval * p.x_velocity;
+ p.y += interval * p.y_velocity;
+}
+
+/*!
+ \qmlclass ParticleMotionGravity QDeclarativeParticleMotionGravity
+ \ingroup qml-particle-elements
+ \since 4.7
+ \brief The ParticleMotionGravity object moves particles towards a point.
+
+ This motion attracts the particles to the specified point with the specified acceleration.
+ To mimic earth gravity, set yattractor to -6360000 and acceleration to 9.8.
+
+ The defaults are all 0, not earth gravity, and so no motion will occur without setting
+ at least the acceleration property.
+
+
+ \sa Particles
+*/
+
+/*!
+ \qmlproperty real ParticleMotionGravity::xattractor
+ \qmlproperty real ParticleMotionGravity::yattractor
+ These properties hold the x and y coordinates of the point attracting the particles.
+*/
+
+/*!
+ \qmlproperty real ParticleMotionGravity::acceleration
+ This property holds the acceleration to apply to the particles.
+*/
+
+/*!
+ \property QDeclarativeParticleMotionGravity::xattractor
+ \brief the x coordinate of the point attracting the particles.
+*/
+
+/*!
+ \property QDeclarativeParticleMotionGravity::yattractor
+ \brief the y coordinate of the point attracting the particles.
+*/
+
+/*!
+ \property QDeclarativeParticleMotionGravity::acceleration
+ \brief the acceleration to apply to the particles.
+*/
+
+void QDeclarativeParticleMotionGravity::setXAttractor(qreal x)
+{
+ if (qFuzzyCompare(x, _xAttr))
+ return;
+ _xAttr = x;
+ emit xattractorChanged();
+}
+
+void QDeclarativeParticleMotionGravity::setYAttractor(qreal y)
+{
+ if (qFuzzyCompare(y, _yAttr))
+ return;
+ _yAttr = y;
+ emit yattractorChanged();
+}
+
+void QDeclarativeParticleMotionGravity::setAcceleration(qreal accel)
+{
+ qreal scaledAccel = accel/1000000.0;
+ if (qFuzzyCompare(scaledAccel, _accel))
+ return;
+ _accel = scaledAccel;
+ emit accelerationChanged();
+}
+
+void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval)
+{
+ qreal xdiff = _xAttr - p.x;
+ qreal ydiff = _yAttr - p.y;
+ qreal absXdiff = qAbs(xdiff);
+ qreal absYdiff = qAbs(ydiff);
+
+ qreal xcomp = xdiff / (absXdiff + absYdiff);
+ qreal ycomp = ydiff / (absXdiff + absYdiff);
+
+ p.x_velocity += xcomp * _accel * interval;
+ p.y_velocity += ycomp * _accel * interval;
+
+ p.x += interval * p.x_velocity;
+ p.y += interval * p.y_velocity;
+}
+
+/*!
+ \qmlclass ParticleMotionWander QDeclarativeParticleMotionWander
+ \ingroup qml-particle-elements
+ \since 4.7
+ \brief The ParticleMotionWander object moves particles in a somewhat random fashion.
+
+ The particles will continue roughly in the original direction, however will randomly
+ drift to each side.
+
+ The code below produces an effect similar to falling snow.
+
+ \qml
+Rectangle {
+ width: 240
+ height: 320
+ color: "black"
+
+ Particles {
+ y: 0
+ width: parent.width
+ height: 30
+ source: "star.png"
+ lifeSpan: 5000
+ count: 50
+ angle: 70
+ angleDeviation: 36
+ velocity: 30
+ velocityDeviation: 10
+ ParticleMotionWander {
+ xvariance: 30
+ pace: 100
+ }
+ }
+}
+ \endqml
+
+ \sa Particles
+*/
+
+/*!
+ \qmlproperty real ParticleMotionWander::xvariance
+ \qmlproperty real ParticleMotionWander::yvariance
+
+ These properties set the amount to wander in the x and y directions.
+*/
+
+/*!
+ \qmlproperty real ParticleMotionWander::pace
+ This property holds how quickly the paricles will move from side to side.
+*/
+
+void QDeclarativeParticleMotionWander::advance(QDeclarativeParticle &p, int interval)
+{
+ if (!particles)
+ particles = qobject_cast<QDeclarativeParticles*>(parent());
+ if (particles) {
+ Data *d = (Data*)p.data;
+ if (_xvariance != 0.) {
+ qreal xdiff = p.x_velocity - d->x_targetV;
+ if ((xdiff > d->x_peak && d->x_var > 0.0) || (xdiff < -d->x_peak && d->x_var < 0.0)) {
+ d->x_var = -d->x_var;
+ d->x_peak = _xvariance + _xvariance * qreal(qrand()) / RAND_MAX;
+ }
+ p.x_velocity += d->x_var * interval;
+ }
+ p.x += interval * p.x_velocity;
+
+ if (_yvariance != 0.) {
+ qreal ydiff = p.y_velocity - d->y_targetV;
+ if ((ydiff > d->y_peak && d->y_var > 0.0) || (ydiff < -d->y_peak && d->y_var < 0.0)) {
+ d->y_var = -d->y_var;
+ d->y_peak = _yvariance + _yvariance * qreal(qrand()) / RAND_MAX;
+ }
+ p.y_velocity += d->y_var * interval;
+ }
+ p.y += interval * p.y_velocity;
+ }
+}
+
+void QDeclarativeParticleMotionWander::created(QDeclarativeParticle &p)
+{
+ if (!p.data) {
+ Data *d = new Data;
+ p.data = (void*)d;
+ d->x_targetV = p.x_velocity;
+ d->y_targetV = p.y_velocity;
+ d->x_peak = _xvariance;
+ d->y_peak = _yvariance;
+ d->x_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0;
+ d->y_var = _pace * qreal(qrand()) / RAND_MAX / 1000.0;
+ }
+}
+
+void QDeclarativeParticleMotionWander::destroy(QDeclarativeParticle &p)
+{
+ if (p.data)
+ delete (Data*)p.data;
+}
+
+void QDeclarativeParticleMotionWander::setXVariance(qreal var)
+{
+ qreal scaledVar = var / 1000.0;
+ if (qFuzzyCompare(scaledVar, _xvariance))
+ return;
+ _xvariance = scaledVar;
+ emit xvarianceChanged();
+}
+
+void QDeclarativeParticleMotionWander::setYVariance(qreal var)
+{
+ qreal scaledVar = var / 1000.0;
+ if (qFuzzyCompare(scaledVar, _yvariance))
+ return;
+ _yvariance = scaledVar;
+ emit yvarianceChanged();
+}
+
+void QDeclarativeParticleMotionWander::setPace(qreal pace)
+{
+ qreal scaledPace = pace / 1000.0;
+ if (qFuzzyCompare(scaledPace, _pace))
+ return;
+ _pace = scaledPace;
+ emit paceChanged();
+}
+
+//---------------------------------------------------------------------------
+class QDeclarativeParticlesPainter : public QDeclarativeItem
+{
+public:
+ QDeclarativeParticlesPainter(QDeclarativeParticlesPrivate *p, QDeclarativeItem* parent)
+ : QDeclarativeItem(parent), d(p)
+ {
+ setFlag(QGraphicsItem::ItemHasNoContents, false);
+ maxX = minX = maxY = minY = 0;
+ }
+
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+ void updateSize();
+
+ qreal maxX;
+ qreal minX;
+ qreal maxY;
+ qreal minY;
+ QDeclarativeParticlesPrivate* d;
+};
+
+//an animation that just gives a tick
+template<class T, void (T::*method)(int)>
+class TickAnimationProxy : public QAbstractAnimation
+{
+public:
+ TickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {}
+ virtual int duration() const { return -1; }
+protected:
+ virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); }
+
+private:
+ T *m_p;
+};
+
+//---------------------------------------------------------------------------
+class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeParticles)
+public:
+ QDeclarativeParticlesPrivate()
+ : count(1), emissionRate(-1), emissionVariance(0.5), lifeSpan(1000)
+ , lifeSpanDev(1000), fadeInDur(200), fadeOutDur(300)
+ , angle(0), angleDev(0), velocity(0), velocityDev(0), emissionCarry(0.)
+ , addParticleTime(0), addParticleCount(0), lastAdvTime(0)
+ , motion(0), clock(this)
+ {
+ }
+
+ ~QDeclarativeParticlesPrivate()
+ {
+ }
+
+ void init()
+ {
+ Q_Q(QDeclarativeParticles);
+ paintItem = new QDeclarativeParticlesPainter(this, q);
+ }
+
+ void tick(int time);
+ void createParticle(int time);
+ void updateOpacity(QDeclarativeParticle &p, int age);
+
+ QUrl url;
+ QDeclarativePixmap image;
+ int count;
+ int emissionRate;
+ qreal emissionVariance;
+ int lifeSpan;
+ int lifeSpanDev;
+ int fadeInDur;
+ int fadeOutDur;
+ qreal angle;
+ qreal angleDev;
+ qreal velocity;
+ qreal velocityDev;
+ qreal emissionCarry;
+ int addParticleTime;
+ int addParticleCount;
+ int lastAdvTime;
+ QDeclarativeParticleMotion *motion;
+ QDeclarativeParticlesPainter *paintItem;
+
+
+ QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs
+ QList<QDeclarativeParticle> particles;
+ TickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock;
+
+};
+
+void QDeclarativeParticlesPrivate::tick(int time)
+{
+ Q_Q(QDeclarativeParticles);
+ if (!motion)
+ motion = new QDeclarativeParticleMotionLinear(q);
+
+ int oldCount = particles.count();
+ int removed = 0;
+ int interval = time - lastAdvTime;
+ for (int i = 0; i < particles.count(); ) {
+ QDeclarativeParticle &particle = particles[i];
+ int age = time - particle.birthTime;
+ if (age >= particle.lifeSpan) {
+ QDeclarativeParticle part = particles.takeAt(i);
+ motion->destroy(part);
+ ++removed;
+ } else {
+ updateOpacity(particle, age);
+ motion->advance(particle, interval);
+ ++i;
+ }
+ }
+
+ if(emissionRate == -1)//Otherwise leave emission to the emission rate
+ while(removed-- && ((count == -1) || particles.count() < count))
+ createParticle(time);
+
+ if (!addParticleTime)
+ addParticleTime = time;
+
+ //Possibly emit new particles
+ if (((count == -1) || particles.count() < count) && emissionRate
+ && !(count==-1 && emissionRate==-1)) {
+ int emissionCount = -1;
+ if (emissionRate != -1){
+ qreal variance = 1.;
+ if (emissionVariance > 0.){
+ variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.);
+ }
+ qreal emission = emissionRate * (qreal(interval)/1000.);
+ emission = emission * variance + emissionCarry;
+ double tmpDbl;
+ emissionCarry = modf(emission, &tmpDbl);
+ emissionCount = (int)tmpDbl;
+ emissionCount = qMax(0,emissionCount);
+ }
+ while(((count == -1) || particles.count() < count) &&
+ (emissionRate==-1 || emissionCount--))
+ createParticle(time);
+ }
+
+ //Deal with emissions from requested bursts
+ for(int i=0; i<bursts.size(); i++){
+ int emission = 0;
+ if(bursts[i].second == -1){
+ emission = bursts[i].first;
+ }else{
+ qreal variance = 1.;
+ if (emissionVariance > 0.){
+ variance += (qreal(qrand())/RAND_MAX) * emissionVariance * (qrand()%2?-1.:1.);
+ }
+ qreal workingEmission = bursts[i].second * (qreal(interval)/1000.);
+ workingEmission *= variance;
+ emission = (int)workingEmission;
+ emission = qMax(emission, 0);
+ }
+ emission = qMin(emission, bursts[i].first);
+ bursts[i].first -= emission;
+ while(emission--)
+ createParticle(time);
+ }
+ for(int i=bursts.size()-1; i>=0; i--)
+ if(bursts[i].first <= 0)
+ bursts.removeAt(i);
+
+ lastAdvTime = time;
+ paintItem->updateSize();
+ paintItem->update();
+ if (!(oldCount || particles.count()) && (!count || !emissionRate) && bursts.isEmpty()) {
+ lastAdvTime = 0;
+ clock.stop();
+ }
+}
+
+void QDeclarativeParticlesPrivate::createParticle(int time)
+{
+ Q_Q(QDeclarativeParticles);
+ QDeclarativeParticle p(time);
+ p.x = q->x() + q->width() * qreal(qrand()) / RAND_MAX - image.width()/2.0;
+ p.y = q->y() + q->height() * qreal(qrand()) / RAND_MAX - image.height()/2.0;
+ p.lifeSpan = lifeSpan;
+ if (lifeSpanDev)
+ p.lifeSpan += int(lifeSpanDev/2 - lifeSpanDev * qreal(qrand()) / RAND_MAX);
+ p.fadeOutAge = p.lifeSpan - fadeOutDur;
+ if (fadeInDur == 0.) {
+ p.state= QDeclarativeParticle::Solid;
+ p.opacity = 1.0;
+ }
+ qreal a = angle;
+ if (angleDev)
+ a += angleDev/2 - angleDev * qreal(qrand()) / RAND_MAX;
+ if (a > M_PI)
+ a = a - 2 * M_PI;
+ qreal v = velocity;
+ if (velocityDev)
+ v += velocityDev/2 - velocityDev * qreal(qrand()) / RAND_MAX;
+ p.x_velocity = v * fastCos(a);
+ p.y_velocity = v * fastSin(a);
+ particles.append(p);
+ motion->created(particles.last());
+}
+
+void QDeclarativeParticlesPrivate::updateOpacity(QDeclarativeParticle &p, int age)
+{
+ switch (p.state) {
+ case QDeclarativeParticle::FadeIn:
+ if (age <= fadeInDur) {
+ p.opacity = qreal(age) / fadeInDur;
+ break;
+ } else {
+ p.opacity = 1.0;
+ p.state = QDeclarativeParticle::Solid;
+ // Fall through
+ }
+ case QDeclarativeParticle::Solid:
+ if (age <= p.fadeOutAge) {
+ break;
+ } else {
+ p.state = QDeclarativeParticle::FadeOut;
+ // Fall through
+ }
+ case QDeclarativeParticle::FadeOut:
+ p.opacity = qreal(p.lifeSpan - age) / fadeOutDur;
+ break;
+ }
+}
+
+/*!
+ \qmlclass Particles QDeclarativeParticles
+ \ingroup qml-particle-elements
+ \since 4.7
+ \brief The Particles object generates and moves particles.
+ \inherits Item
+
+ Particles are available in the \bold{Qt.labs.particles 1.0} module.
+ \e {Elements in the Qt.labs module are not guaranteed to remain compatible
+ in future versions.}
+
+ This element provides preliminary support for particles in QML,
+ and may be heavily changed or removed in later versions.
+
+ The particles created by this object cannot be dealt with
+ directly, they can only be controlled through the parameters of
+ the Particles object. The particles are all the same pixmap,
+ specified by the user.
+
+ The particles are painted relative to the parent of the Particles
+ object. Moving the Particles object will not move the particles
+ already emitted.
+
+ The below example creates two differently behaving particle
+ sources. The top one has particles falling from the top like
+ snow, the lower one has particles expelled up like a fountain.
+
+ \qml
+import QtQuick 1.0
+import Qt.labs.particles 1.0
+
+Rectangle {
+ width: 240
+ height: 320
+ color: "black"
+ Particles {
+ y: 0
+ width: parent.width
+ height: 30
+ source: "star.png"
+ lifeSpan: 5000
+ count: 50
+ angle: 70
+ angleDeviation: 36
+ velocity: 30
+ velocityDeviation: 10
+ ParticleMotionWander {
+ xvariance: 30
+ pace: 100
+ }
+ }
+ Particles {
+ y: 300
+ x: 120
+ width: 1
+ height: 1
+ source: "star.png"
+ lifeSpan: 5000
+ count: 200
+ angle: 270
+ angleDeviation: 45
+ velocity: 50
+ velocityDeviation: 30
+ ParticleMotionGravity {
+ yattractor: 1000
+ xattractor: 0
+ acceleration: 25
+ }
+ }
+}
+ \endqml
+ \image particles.gif
+*/
+
+QDeclarativeParticles::QDeclarativeParticles(QDeclarativeItem *parent)
+ : QDeclarativeItem(*(new QDeclarativeParticlesPrivate), parent)
+{
+ Q_D(QDeclarativeParticles);
+ d->init();
+}
+
+QDeclarativeParticles::~QDeclarativeParticles()
+{
+}
+
+/*!
+ \qmlproperty string Particles::source
+ This property holds the URL of the particle image.
+*/
+
+/*!
+ \property QDeclarativeParticles::source
+ \brief the URL of the particle image.
+*/
+QUrl QDeclarativeParticles::source() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->url;
+}
+
+void QDeclarativeParticles::imageLoaded()
+{
+ Q_D(QDeclarativeParticles);
+ if (d->image.isError())
+ qmlInfo(this) << d->image.error();
+ d->paintItem->updateSize();
+ d->paintItem->update();
+}
+
+void QDeclarativeParticles::setSource(const QUrl &name)
+{
+ Q_D(QDeclarativeParticles);
+
+ if ((d->url.isEmpty() == name.isEmpty()) && name == d->url)
+ return;
+
+ if (name.isEmpty()) {
+ d->url = name;
+ d->image.clear(this);
+ d->paintItem->updateSize();
+ d->paintItem->update();
+ } else {
+ d->url = name;
+ Q_ASSERT(!name.isRelative());
+ d->image.load(qmlEngine(this), d->url);
+ if (d->image.isLoading()) {
+ d->image.connectFinished(this, SLOT(imageLoaded()));
+ } else {
+ if (d->image.isError())
+ qmlInfo(this) << d->image.error();
+ //### unify with imageLoaded
+ d->paintItem->updateSize();
+ d->paintItem->update();
+ }
+ }
+ emit sourceChanged();
+}
+
+/*!
+ \qmlproperty int Particles::count
+ This property holds the maximum number of particles
+
+ The particles element emits particles until it has count active
+ particles. When this number is reached, new particles are not emitted until
+ some of the current particles reach the end of their lifespan.
+
+ If count is -1 then there is no maximum number of active particles, and
+ particles will be constantly emitted at the rate specified by emissionRate.
+
+ The default value for count is 1.
+
+ If both count and emissionRate are set to -1, nothing will be emitted.
+
+*/
+
+/*!
+ \property QDeclarativeParticles::count
+ \brief the maximum number of particles
+*/
+int QDeclarativeParticles::count() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->count;
+}
+
+void QDeclarativeParticles::setCount(int cnt)
+{
+ Q_D(QDeclarativeParticles);
+ if (cnt == d->count)
+ return;
+
+ int oldCount = d->count;
+ d->count = cnt;
+ d->addParticleTime = 0;
+ d->addParticleCount = d->particles.count();
+ if (!oldCount && d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) {
+ d->clock.start();
+ }
+ d->paintItem->updateSize();
+ d->paintItem->update();
+ emit countChanged();
+}
+
+
+/*!
+ \qmlproperty int Particles::emissionRate
+ This property holds the target number of particles to emit every second.
+
+ The particles element will emit up to emissionRate particles every
+ second. Fewer particles may be emitted per second if the maximum number of
+ particles has been reached.
+
+ If emissionRate is set to -1 there is no limit to the number of
+ particles emitted per second, and particles will be instantly emitted to
+ reach the maximum number of particles specified by count.
+
+ The default value for emissionRate is -1.
+
+ If both count and emissionRate are set to -1, nothing will be emitted.
+*/
+
+/*!
+ \property QDeclarativeParticles::emissionRate
+ \brief the emission rate of particles
+*/
+int QDeclarativeParticles::emissionRate() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->emissionRate;
+}
+void QDeclarativeParticles::setEmissionRate(int er)
+{
+ Q_D(QDeclarativeParticles);
+ if(er == d->emissionRate)
+ return;
+ d->emissionRate = er;
+ if (d->clock.state() != QAbstractAnimation::Running && d->count && d->emissionRate) {
+ d->clock.start();
+ }
+ emit emissionRateChanged();
+}
+
+/*!
+ \qmlproperty real Particles::emissionVariance
+ This property holds how inconsistent the rate of particle emissions are.
+ It is a number between 0 (no variance) and 1 (some variance).
+
+ The expected number of particles emitted per second is emissionRate. If
+ emissionVariance is 0 then particles will be emitted consistently throughout
+ each second to reach that number. If emissionVariance is greater than 0 the
+ rate of particle emission will vary randomly throughout the second, with the
+ consequence that the actual number of particles emitted in one second will
+ vary randomly as well.
+
+ emissionVariance is the maximum deviation from emitting
+ emissionRate particles per second. An emissionVariance of 0 means you should
+ get exactly emissionRate particles emitted per second,
+ and an emissionVariance of 1 means you will get between zero and two times
+ emissionRate particles per second, but you should get emissionRate particles
+ per second on average.
+
+ Note that even with an emissionVariance of 0 there may be some variance due
+ to performance and hardware constraints.
+
+ The default value of emissionVariance is 0.5
+*/
+
+/*!
+ \property QDeclarativeParticles::emissionVariance
+ \brief how much the particle emission amounts vary per tick
+*/
+
+qreal QDeclarativeParticles::emissionVariance() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->emissionVariance;
+}
+
+void QDeclarativeParticles::setEmissionVariance(qreal ev)
+{
+ Q_D(QDeclarativeParticles);
+ if(d->emissionVariance == ev)
+ return;
+ d->emissionVariance = ev;
+ emit emissionVarianceChanged();
+}
+
+/*!
+ \qmlproperty int Particles::lifeSpan
+ \qmlproperty int Particles::lifeSpanDeviation
+
+ These properties describe the life span of each particle.
+
+ The default lifespan for a particle is 1000ms.
+
+ lifeSpanDeviation randomly varies the lifeSpan up to the specified variation. For
+ example, the following creates particles whose lifeSpan will vary
+ from 150ms to 250ms:
+
+ \qml
+Particles {
+ source: "star.png"
+ lifeSpan: 200
+ lifeSpanDeviation: 100
+}
+ \endqml
+*/
+
+/*!
+ \property QDeclarativeParticles::lifeSpan
+ \brief the life span of each particle.
+
+ Default value is 1000ms.
+
+ \sa QDeclarativeParticles::lifeSpanDeviation
+*/
+int QDeclarativeParticles::lifeSpan() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->lifeSpan;
+}
+
+void QDeclarativeParticles::setLifeSpan(int ls)
+{
+ Q_D(QDeclarativeParticles);
+ if(d->lifeSpan == ls)
+ return;
+ d->lifeSpan = ls;
+ emit lifeSpanChanged();
+}
+
+/*!
+ \property QDeclarativeParticles::lifeSpanDeviation
+ \brief the maximum possible deviation from the set lifeSpan.
+
+ Randomly varies the lifeSpan up to the specified variation. For
+ example, the following creates particles whose lifeSpan will vary
+ from 150ms to 250ms:
+
+\qml
+Particles {
+ source: "star.png"
+ lifeSpan: 200
+ lifeSpanDeviation: 100
+}
+\endqml
+
+ \sa QDeclarativeParticles::lifeSpan
+*/
+int QDeclarativeParticles::lifeSpanDeviation() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->lifeSpanDev;
+}
+
+void QDeclarativeParticles::setLifeSpanDeviation(int dev)
+{
+ Q_D(QDeclarativeParticles);
+ if(d->lifeSpanDev == dev)
+ return;
+ d->lifeSpanDev = dev;
+ emit lifeSpanDeviationChanged();
+}
+
+/*!
+ \qmlproperty int Particles::fadeInDuration
+ \qmlproperty int Particles::fadeOutDuration
+ These properties hold the time taken to fade the particles in and out.
+
+ By default fade in is 200ms and fade out is 300ms.
+*/
+
+/*!
+ \property QDeclarativeParticles::fadeInDuration
+ \brief the time taken to fade in the particles.
+
+ Default value is 200ms.
+*/
+int QDeclarativeParticles::fadeInDuration() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->fadeInDur;
+}
+
+void QDeclarativeParticles::setFadeInDuration(int dur)
+{
+ Q_D(QDeclarativeParticles);
+ if (dur < 0.0 || dur == d->fadeInDur)
+ return;
+ d->fadeInDur = dur;
+ emit fadeInDurationChanged();
+}
+
+/*!
+ \property QDeclarativeParticles::fadeOutDuration
+ \brief the time taken to fade out the particles.
+
+ Default value is 300ms.
+*/
+int QDeclarativeParticles::fadeOutDuration() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->fadeOutDur;
+}
+
+void QDeclarativeParticles::setFadeOutDuration(int dur)
+{
+ Q_D(QDeclarativeParticles);
+ if (dur < 0.0 || d->fadeOutDur == dur)
+ return;
+ d->fadeOutDur = dur;
+ emit fadeOutDurationChanged();
+}
+
+/*!
+ \qmlproperty real Particles::angle
+ \qmlproperty real Particles::angleDeviation
+
+ These properties control particle direction.
+
+ angleDeviation randomly varies the direction up to the specified variation. For
+ example, the following creates particles whose initial direction will
+ vary from 15 degrees to 105 degrees:
+
+ \qml
+Particles {
+ source: "star.png"
+ angle: 60
+ angleDeviation: 90
+}
+ \endqml
+*/
+
+/*!
+ \property QDeclarativeParticles::angle
+ \brief the initial angle of direction.
+
+ \sa QDeclarativeParticles::angleDeviation
+*/
+qreal QDeclarativeParticles::angle() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->angle * 180.0 / M_PI;
+}
+
+void QDeclarativeParticles::setAngle(qreal angle)
+{
+ Q_D(QDeclarativeParticles);
+ qreal radAngle = angle * M_PI / 180.0;
+ if(radAngle == d->angle)
+ return;
+ d->angle = radAngle;
+ emit angleChanged();
+}
+
+/*!
+ \property QDeclarativeParticles::angleDeviation
+ \brief the maximum possible deviation from the set angle.
+
+ Randomly varies the direction up to the specified variation. For
+ example, the following creates particles whose initial direction will
+ vary from 15 degrees to 105 degrees:
+
+\qml
+Particles {
+ source: "star.png"
+ angle: 60
+ angleDeviation: 90
+}
+\endqml
+
+ \sa QDeclarativeParticles::angle
+*/
+qreal QDeclarativeParticles::angleDeviation() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->angleDev * 180.0 / M_PI;
+}
+
+void QDeclarativeParticles::setAngleDeviation(qreal dev)
+{
+ Q_D(QDeclarativeParticles);
+ qreal radDev = dev * M_PI / 180.0;
+ if(radDev == d->angleDev)
+ return;
+ d->angleDev = radDev;
+ emit angleDeviationChanged();
+}
+
+/*!
+ \qmlproperty real Particles::velocity
+ \qmlproperty real Particles::velocityDeviation
+
+ These properties control the velocity of the particles.
+
+ velocityDeviation randomly varies the velocity up to the specified variation. For
+ example, the following creates particles whose initial velocity will
+ vary from 40 to 60.
+
+ \qml
+Particles {
+ source: "star.png"
+ velocity: 50
+ velocityDeviation: 20
+}
+ \endqml
+*/
+
+/*!
+ \property QDeclarativeParticles::velocity
+ \brief the initial velocity of the particles.
+
+ \sa QDeclarativeParticles::velocityDeviation
+*/
+qreal QDeclarativeParticles::velocity() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->velocity * 1000.0;
+}
+
+void QDeclarativeParticles::setVelocity(qreal velocity)
+{
+ Q_D(QDeclarativeParticles);
+ qreal realVel = velocity / 1000.0;
+ if(realVel == d->velocity)
+ return;
+ d->velocity = realVel;
+ emit velocityChanged();
+}
+
+/*!
+ \property QDeclarativeParticles::velocityDeviation
+ \brief the maximum possible deviation from the set velocity.
+
+ Randomly varies the velocity up to the specified variation. For
+ example, the following creates particles whose initial velocity will
+ vary from 40 to 60.
+
+\qml
+Particles {
+ source: "star.png"
+ velocity: 50
+ velocityDeviation: 20
+}
+\endqml
+
+ \sa QDeclarativeParticles::velocity
+*/
+qreal QDeclarativeParticles::velocityDeviation() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->velocityDev * 1000.0;
+}
+
+void QDeclarativeParticles::setVelocityDeviation(qreal velocity)
+{
+ Q_D(QDeclarativeParticles);
+ qreal realDev = velocity / 1000.0;
+ if(realDev == d->velocityDev)
+ return;
+ d->velocityDev = realDev;
+ emit velocityDeviationChanged();
+}
+
+/*!
+ \qmlproperty ParticleMotion Particles::motion
+ This property sets the type of motion to apply to the particles.
+
+ When a particle is created it will have an initial direction and velocity.
+ The motion of the particle during its lifeSpan is then influenced by the
+ motion property.
+
+ Default motion is ParticleMotionLinear.
+*/
+
+/*!
+ \property QDeclarativeParticles::motion
+ \brief sets the type of motion to apply to the particles.
+
+ When a particle is created it will have an initial direction and velocity.
+ The motion of the particle during its lifeSpan is then influenced by the
+ motion property.
+
+ Default motion is QDeclarativeParticleMotionLinear.
+*/
+QDeclarativeParticleMotion *QDeclarativeParticles::motion() const
+{
+ Q_D(const QDeclarativeParticles);
+ return d->motion;
+}
+
+void QDeclarativeParticles::setMotion(QDeclarativeParticleMotion *motion)
+{
+ Q_D(QDeclarativeParticles);
+ if (motion == d->motion)
+ return;
+ d->motion = motion;
+ emit motionChanged();
+}
+
+/*!
+ \qmlmethod Particles::burst(int count, int emissionRate)
+
+ Initiates a burst of particles.
+
+ This method takes two arguments. The first argument is the number
+ of particles to emit and the second argument is the emissionRate for the
+ burst. If the second argument is omitted, it is treated as -1. The burst
+ of particles has a separate emissionRate and count to the normal emission of
+ particles. The burst uses the same values as normal emission for all other
+ properties, including emissionVariance.
+
+ The normal emission of particles will continue during the burst, however
+ the particles created by the burst count towards the maximum number used by
+ normal emission. To avoid this behavior, use two Particles elements.
+
+*/
+void QDeclarativeParticles::burst(int count, int emissionRate)
+{
+ Q_D(QDeclarativeParticles);
+ d->bursts << qMakePair(count, emissionRate);
+ if (d->clock.state() != QAbstractAnimation::Running)
+ d->clock.start();
+}
+
+void QDeclarativeParticlesPainter::updateSize()
+{
+ if (!d->componentComplete)
+ return;
+
+ const int parentX = parentItem()->x();
+ const int parentY = parentItem()->y();
+ for (int i = 0; i < d->particles.count(); ++i) {
+ const QDeclarativeParticle &particle = d->particles.at(i);
+ if(particle.x > maxX)
+ maxX = particle.x;
+ if(particle.x < minX)
+ minX = particle.x;
+ if(particle.y > maxY)
+ maxY = particle.y;
+ if(particle.y < minY)
+ minY = particle.y;
+ }
+
+ int myWidth = (int)(maxX-minX+0.5)+d->image.width();
+ int myX = (int)(minX - parentX);
+ int myHeight = (int)(maxY-minY+0.5)+d->image.height();
+ int myY = (int)(minY - parentY);
+ setWidth(myWidth);
+ setHeight(myHeight);
+ setX(myX);
+ setY(myY);
+}
+
+void QDeclarativeParticles::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ Q_UNUSED(p);
+ //painting is done by the ParticlesPainter, so it can have the right size
+}
+
+void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ if (d->image.isNull() || d->particles.isEmpty())
+ return;
+
+ const int myX = x() + parentItem()->x();
+ const int myY = y() + parentItem()->y();
+
+ QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData;
+ pixmapData.resize(d->particles.count());
+
+ const QRectF sourceRect = d->image.rect();
+ qreal halfPWidth = sourceRect.width()/2.;
+ qreal halfPHeight = sourceRect.height()/2.;
+ for (int i = 0; i < d->particles.count(); ++i) {
+ const QDeclarativeParticle &particle = d->particles.at(i);
+ pixmapData[i].x = particle.x - myX + halfPWidth;
+ pixmapData[i].y = particle.y - myY + halfPHeight;
+ pixmapData[i].opacity = particle.opacity;
+
+ //these never change
+ pixmapData[i].rotation = 0;
+ pixmapData[i].scaleX = 1;
+ pixmapData[i].scaleY = 1;
+ pixmapData[i].sourceLeft = sourceRect.left();
+ pixmapData[i].sourceTop = sourceRect.top();
+ pixmapData[i].width = sourceRect.width();
+ pixmapData[i].height = sourceRect.height();
+ }
+ p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image);
+}
+
+void QDeclarativeParticles::componentComplete()
+{
+ Q_D(QDeclarativeParticles);
+ QDeclarativeItem::componentComplete();
+ if (d->count && d->emissionRate) {
+ d->paintItem->updateSize();
+ d->clock.start();
+ }
+ if (d->lifeSpanDev > d->lifeSpan)
+ d->lifeSpanDev = d->lifeSpan;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/particles/qdeclarativeparticles_p.h b/src/imports/particles/qdeclarativeparticles_p.h
new file mode 100644
index 0000000000..4ffdbbab9e
--- /dev/null
+++ b/src/imports/particles/qdeclarativeparticles_p.h
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEPARTICLES_H
+#define QDECLARATIVEPARTICLES_H
+
+#include <QtDeclarative/qdeclarativeitem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeParticle;
+class QDeclarativeParticles;
+class QDeclarativeParticleMotion : public QObject
+{
+ Q_OBJECT
+public:
+ QDeclarativeParticleMotion(QObject *parent=0);
+
+ virtual void advance(QDeclarativeParticle &, int interval);
+ virtual void created(QDeclarativeParticle &);
+ virtual void destroy(QDeclarativeParticle &);
+};
+
+class QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion
+{
+ Q_OBJECT
+public:
+ QDeclarativeParticleMotionLinear(QObject *parent=0)
+ : QDeclarativeParticleMotion(parent) {}
+
+ virtual void advance(QDeclarativeParticle &, int interval);
+};
+
+class QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion
+{
+ Q_OBJECT
+
+ Q_PROPERTY(qreal xattractor READ xAttractor WRITE setXAttractor NOTIFY xattractorChanged)
+ Q_PROPERTY(qreal yattractor READ yAttractor WRITE setYAttractor NOTIFY yattractorChanged)
+ Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
+public:
+ QDeclarativeParticleMotionGravity(QObject *parent=0)
+ : QDeclarativeParticleMotion(parent), _xAttr(0.0), _yAttr(0.0), _accel(0.00005) {}
+
+ qreal xAttractor() const { return _xAttr; }
+ void setXAttractor(qreal x);
+
+ qreal yAttractor() const { return _yAttr; }
+ void setYAttractor(qreal y);
+
+ qreal acceleration() const { return _accel * 1000000; }
+ void setAcceleration(qreal accel);
+
+ virtual void advance(QDeclarativeParticle &, int interval);
+
+Q_SIGNALS:
+ void xattractorChanged();
+ void yattractorChanged();
+ void accelerationChanged();
+
+private:
+ qreal _xAttr;
+ qreal _yAttr;
+ qreal _accel;
+};
+
+class QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion
+{
+ Q_OBJECT
+public:
+ QDeclarativeParticleMotionWander()
+ : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0), _pace(100) {}
+
+ virtual void advance(QDeclarativeParticle &, int interval);
+ virtual void created(QDeclarativeParticle &);
+ virtual void destroy(QDeclarativeParticle &);
+
+ struct Data {
+ qreal x_targetV;
+ qreal y_targetV;
+ qreal x_peak;
+ qreal y_peak;
+ qreal x_var;
+ qreal y_var;
+ };
+
+ Q_PROPERTY(qreal xvariance READ xVariance WRITE setXVariance NOTIFY xvarianceChanged)
+ qreal xVariance() const { return _xvariance * 1000.0; }
+ void setXVariance(qreal var);
+
+ Q_PROPERTY(qreal yvariance READ yVariance WRITE setYVariance NOTIFY yvarianceChanged)
+ qreal yVariance() const { return _yvariance * 1000.0; }
+ void setYVariance(qreal var);
+
+ Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged)
+ qreal pace() const { return _pace * 1000.0; }
+ void setPace(qreal pace);
+
+Q_SIGNALS:
+ void xvarianceChanged();
+ void yvarianceChanged();
+ void paceChanged();
+
+private:
+ QDeclarativeParticles *particles;
+ qreal _xvariance;
+ qreal _yvariance;
+ qreal _pace;
+};
+
+class QDeclarativeParticlesPrivate;
+class QDeclarativeParticles : public QDeclarativeItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
+ Q_PROPERTY(int emissionRate READ emissionRate WRITE setEmissionRate NOTIFY emissionRateChanged)
+ Q_PROPERTY(qreal emissionVariance READ emissionVariance WRITE setEmissionVariance NOTIFY emissionVarianceChanged)
+ Q_PROPERTY(int lifeSpan READ lifeSpan WRITE setLifeSpan NOTIFY lifeSpanChanged)
+ Q_PROPERTY(int lifeSpanDeviation READ lifeSpanDeviation WRITE setLifeSpanDeviation NOTIFY lifeSpanDeviationChanged)
+ Q_PROPERTY(int fadeInDuration READ fadeInDuration WRITE setFadeInDuration NOTIFY fadeInDurationChanged)
+ Q_PROPERTY(int fadeOutDuration READ fadeOutDuration WRITE setFadeOutDuration NOTIFY fadeOutDurationChanged)
+ Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
+ Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged)
+ Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
+ Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged)
+ Q_PROPERTY(QDeclarativeParticleMotion *motion READ motion WRITE setMotion NOTIFY motionChanged)
+ Q_CLASSINFO("DefaultProperty", "motion")
+
+public:
+ QDeclarativeParticles(QDeclarativeItem *parent=0);
+ ~QDeclarativeParticles();
+
+ QUrl source() const;
+ void setSource(const QUrl &);
+
+ int count() const;
+ void setCount(int cnt);
+
+ int emissionRate() const;
+ void setEmissionRate(int);
+
+ qreal emissionVariance() const;
+ void setEmissionVariance(qreal);
+
+ int lifeSpan() const;
+ void setLifeSpan(int);
+
+ int lifeSpanDeviation() const;
+ void setLifeSpanDeviation(int);
+
+ int fadeInDuration() const;
+ void setFadeInDuration(int);
+
+ int fadeOutDuration() const;
+ void setFadeOutDuration(int);
+
+ qreal angle() const;
+ void setAngle(qreal);
+
+ qreal angleDeviation() const;
+ void setAngleDeviation(qreal);
+
+ qreal velocity() const;
+ void setVelocity(qreal);
+
+ qreal velocityDeviation() const;
+ void setVelocityDeviation(qreal);
+
+ QDeclarativeParticleMotion *motion() const;
+ void setMotion(QDeclarativeParticleMotion *);
+
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+public Q_SLOTS:
+ void burst(int count, int emissionRate=-1);
+
+protected:
+ virtual void componentComplete();
+
+Q_SIGNALS:
+ void sourceChanged();
+ void countChanged();
+ void emissionRateChanged();
+ void emissionVarianceChanged();
+ void lifeSpanChanged();
+ void lifeSpanDeviationChanged();
+ void fadeInDurationChanged();
+ void fadeOutDurationChanged();
+ void angleChanged();
+ void angleDeviationChanged();
+ void velocityChanged();
+ void velocityDeviationChanged();
+ void emittingChanged();
+ void motionChanged();
+
+private Q_SLOTS:
+ void imageLoaded();
+
+private:
+ Q_DISABLE_COPY(QDeclarativeParticles)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeParticles)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeParticleMotion)
+QML_DECLARE_TYPE(QDeclarativeParticleMotionLinear)
+QML_DECLARE_TYPE(QDeclarativeParticleMotionGravity)
+QML_DECLARE_TYPE(QDeclarativeParticleMotionWander)
+QML_DECLARE_TYPE(QDeclarativeParticles)
+
+QT_END_HEADER
+
+#endif
diff --git a/src/imports/particles/qmldir b/src/imports/particles/qmldir
new file mode 100644
index 0000000000..aeebd2c99b
--- /dev/null
+++ b/src/imports/particles/qmldir
@@ -0,0 +1 @@
+plugin qmlparticlesplugin
diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri
new file mode 100644
index 0000000000..0f70030dac
--- /dev/null
+++ b/src/imports/qimportbase.pri
@@ -0,0 +1,36 @@
+symbian:include(../plugins/qpluginbase.pri)
+TEMPLATE = lib
+CONFIG += qt plugin
+
+win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release
+
+isEmpty(TARGETPATH) {
+ error("qimportbase.pri: You must provide a TARGETPATH!")
+}
+isEmpty(TARGET) {
+ error("qimportbase.pri: You must provide a TARGET!")
+}
+
+QMLDIRFILE = $${_PRO_FILE_PWD_}/qmldir
+copy2build.input = QMLDIRFILE
+copy2build.output = $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir
+!contains(TEMPLATE_PREFIX, vc):copy2build.variable_out = PRE_TARGETDEPS
+copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+copy2build.name = COPY ${QMAKE_FILE_IN}
+copy2build.CONFIG += no_link
+# `clean' should leave the build in a runnable state, which means it shouldn't delete qmldir
+copy2build.CONFIG += no_clean
+QMAKE_EXTRA_COMPILERS += copy2build
+
+TARGET = $$qtLibraryTarget($$TARGET)
+contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
+
+include(../qt_targets.pri)
+
+wince*:LIBS += $$QMAKE_LIBS_GUI
+
+symbian: {
+ TARGET.EPOCALLOWDLLDATA=1
+ TARGET.CAPABILITY = All -Tcb
+ load(armcc_warnings)
+}